Skip to content

Commit

Permalink
Fix oob read on _luac_build_info and luac memleaks
Browse files Browse the repository at this point in the history
  • Loading branch information
wargio committed Aug 17, 2022
1 parent eb7e0ef commit 05bbd14
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 31 deletions.
66 changes: 38 additions & 28 deletions librz/bin/format/luac/luac_bin.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,6 @@ void luac_add_string(RzList *string_list, char *string, ut64 offset, ut64 size)
rz_list_append(string_list, bin_string);
}

static void try_free_empty_list(RzList *list) {
if (list != NULL) {
rz_list_free(list);
}
}

static void free_rz_section(RzBinSection *section) {
if (!section) {
return;
Expand Down Expand Up @@ -111,6 +105,17 @@ static void free_rz_addr(RzBinAddr *addr) {
RZ_FREE(addr);
}

void luac_build_info_free(LuacBinInfo *bin_info) {
if (!bin_info) {
return;
}
rz_list_free(bin_info->entry_list);
rz_list_free(bin_info->symbol_list);
rz_list_free(bin_info->section_list);
rz_list_free(bin_info->string_list);
free(bin_info);
}

LuacBinInfo *luac_build_info(LuaProto *proto) {
if (!proto) {
RZ_LOG_ERROR("Invalid luac file\n");
Expand All @@ -128,10 +133,10 @@ LuacBinInfo *luac_build_info(LuaProto *proto) {
ret->string_list = rz_list_newf((RzListFree)free_rz_string);

if (!(ret->entry_list && ret->symbol_list && ret->section_list && ret->string_list)) {
try_free_empty_list(ret->entry_list);
try_free_empty_list(ret->symbol_list);
try_free_empty_list(ret->section_list);
try_free_empty_list(ret->string_list);
rz_list_free(ret->entry_list);
rz_list_free(ret->symbol_list);
rz_list_free(ret->section_list);
rz_list_free(ret->string_list);
}

_luac_build_info(proto, ret);
Expand Down Expand Up @@ -227,13 +232,13 @@ void _luac_build_info(LuaProto *proto, LuacBinInfo *info) {
char *section_name;
char *symbol_name;
char *proto_name;
char **upvalue_names = NULL;
RzListIter *iter;
int i = 0; // iter

ut64 current_offset;
ut64 current_size;

int i = 0; // iter

// 0. check if stripped (proto name is lost)
if (proto->name_size == 0 || proto->proto_name == NULL) {
// replace name with current offset
Expand Down Expand Up @@ -295,21 +300,25 @@ void _luac_build_info(LuaProto *proto, LuacBinInfo *info) {
}

// 2.2 parse debug_upvalues
char **upvalue_names;
int real_upvalue_cnt;
LuaDbgUpvalueEntry *debug_upv_entry;
real_upvalue_cnt = rz_list_length(proto->upvalue_entries);
upvalue_names = RZ_NEWS0(char *, real_upvalue_cnt);
if (!upvalue_names) {
return;
}
rz_list_foreach (proto->dbg_upvalue_entries, iter, debug_upv_entry) {
upvalue_names[i] = (char *)debug_upv_entry->upvalue_name;
luac_add_string(
info->string_list,
upvalue_names[i],
debug_upv_entry->offset,
debug_upv_entry->name_len);
size_t real_upvalue_cnt = rz_list_length(proto->upvalue_entries);
if (real_upvalue_cnt > 0) {
LuaDbgUpvalueEntry *debug_upv_entry;
upvalue_names = RZ_NEWS0(char *, real_upvalue_cnt);
if (!upvalue_names) {
free(proto_name);
return;
}

i = 0;
rz_list_foreach (proto->dbg_upvalue_entries, iter, debug_upv_entry) {
upvalue_names[i] = (char *)debug_upv_entry->upvalue_name;
luac_add_string(
info->string_list,
upvalue_names[i],
debug_upv_entry->offset,
debug_upv_entry->name_len);
i++;
}
}

// 3.1 construct constant symbols
Expand Down Expand Up @@ -352,5 +361,6 @@ void _luac_build_info(LuaProto *proto, LuacBinInfo *info) {
_luac_build_info(sub_proto, info);
}

RZ_FREE(proto_name);
free(upvalue_names);
free(proto_name);
}
1 change: 1 addition & 0 deletions librz/bin/format/luac/luac_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ void luac_add_entry(RzList *entry_list, ut64 offset, int entry_type);
void luac_add_string(RzList *string_list, char *string, ut64 offset, ut64 size);

LuacBinInfo *luac_build_info(LuaProto *proto);
void luac_build_info_free(LuacBinInfo *bin_info);
void _luac_build_info(LuaProto *proto, LuacBinInfo *info);

/* ========================================================
Expand Down
12 changes: 9 additions & 3 deletions librz/bin/p/bin_luac.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ static RzList *symbols(RzBinFile *bf) {
return NULL;
}

return bin_info_obj->symbol_list;
return rz_list_clone(bin_info_obj->symbol_list);
}

static RzList *entries(RzBinFile *bf) {
Expand All @@ -112,7 +112,7 @@ static RzList *entries(RzBinFile *bf) {
return NULL;
}

return bin_info_obj->entry_list;
return rz_list_clone(bin_info_obj->entry_list);
}

static RzList *strings(RzBinFile *bf) {
Expand All @@ -124,7 +124,12 @@ static RzList *strings(RzBinFile *bf) {
return NULL;
}

return bin_info_obj->string_list;
return rz_list_clone(bin_info_obj->string_list);
}

static void destroy(RzBinFile *bf) {
LuacBinInfo *bin_info_obj = GET_INTERNAL_BIN_INFO_OBJ(bf);
luac_build_info_free(bin_info_obj);
}

RzBinPlugin rz_bin_plugin_luac = {
Expand All @@ -133,6 +138,7 @@ RzBinPlugin rz_bin_plugin_luac = {
.license = "LGPL3",
.get_sdb = NULL,
.load_buffer = &load_buffer,
.destroy = &destroy,
.check_buffer = &check_buffer,
.baddr = NULL,
.entries = &entries,
Expand Down

0 comments on commit 05bbd14

Please sign in to comment.