Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bin_elf import & symbol leak #4490

Merged
merged 9 commits into from
May 18, 2024
12 changes: 2 additions & 10 deletions librz/bin/bin.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,16 +203,8 @@ RZ_API void rz_bin_reloc_free(RZ_NULLABLE RzBinReloc *reloc) {
if (!reloc) {
return;
}
/**
* TODO: leak in bin_elf, but it will cause double free in bin_pe if free here,
* Because in the bin_elf implementation RzBinObject->imports and RzBinObject->relocs->imports
* are two pieces of data, but they are linked to each other in bin_pe
* TODO: also, double free in bin_coff if free here,
* Because in the bin_coff implementation imports and symbols are shared
* between relocs
*/
// rz_bin_import_free(reloc->import);
// rz_bin_symbol_free(reloc->symbol);
rz_bin_import_free(reloc->import);
rz_bin_symbol_free(reloc->symbol);
free(reloc);
}

Expand Down
7 changes: 5 additions & 2 deletions librz/bin/bobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ RZ_API RzBinRelocStorage *rz_bin_reloc_storage_new(RZ_OWN RzPVector /*<RzBinRelo
rz_pvector_push(&target_sorter, reloc);
}
}
ret->relocs_free = relocs->v.free_user;
relocs->v.free = NULL; // ownership of relocs transferred
rz_pvector_free(relocs);
rz_pvector_sort(&sorter, reloc_cmp, NULL);
Expand All @@ -132,8 +133,10 @@ RZ_API void rz_bin_reloc_storage_free(RzBinRelocStorage *storage) {
if (!storage) {
return;
}
for (size_t i = 0; i < storage->relocs_count; i++) {
rz_bin_reloc_free(storage->relocs[i]);
if (storage->relocs_free) {
for (size_t i = 0; i < storage->relocs_count; i++) {
storage->relocs_free(storage->relocs[i]);
}
}
free(storage->relocs);
free(storage->target_relocs);
Expand Down
7 changes: 5 additions & 2 deletions librz/bin/format/le/le.c
Original file line number Diff line number Diff line change
Expand Up @@ -1307,6 +1307,7 @@ static bool le_append_fixup(rz_bin_le_obj_t *bin, LE_reloc *reloc, RzList /*<RzB
free(tmp);
return false;
}
rz_list_append(bin->le_fixups, tmp);
return true;
}

Expand Down Expand Up @@ -1491,7 +1492,7 @@ static bool le_load_fixup_record(rz_bin_le_obj_t *bin, RzList /*<RzBinReloc *>*/
}

static RZ_OWN RzList /*<LE_reloc *>*/ *le_load_relocs(rz_bin_le_obj_t *bin) {
RzList *relocs = rz_list_newf((RzListFree)rz_bin_reloc_free);
RzList *relocs = rz_list_newf(NULL);
if (!relocs) {
return NULL;
}
Expand Down Expand Up @@ -1525,6 +1526,7 @@ static void rz_bin_le_free(rz_bin_le_obj_t *bin) {
rz_pvector_free(bin->imports);
ht_pp_free(bin->le_import_ht);
rz_list_free(bin->le_relocs);
rz_list_free(bin->le_fixups);
free(bin);
}

Expand Down Expand Up @@ -1571,6 +1573,7 @@ bool rz_bin_le_load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *
CHECK(bin->imp_mod_names = le_load_import_mod_names(bin));
CHECK(bin->le_entries = le_load_entries(bin));
err_ctx = ", unable to load and apply relocations.";
CHECK(bin->le_fixups = rz_list_newf(free));
CHECK(bin->le_relocs = le_load_relocs(bin));
CHECK(le_patch_relocs(bin));

Expand Down Expand Up @@ -1762,7 +1765,7 @@ RZ_OWN RzPVector /*<RzBinVirtualFile *>*/ *rz_bin_le_get_virtual_files(RzBinFile
RZ_OWN RzPVector /*<RzBinReloc *>*/ *rz_bin_le_get_relocs(RzBinFile *bf) {
rz_bin_le_obj_t *bin = bf->o->bin_obj;
RzList /*<LE_reloc *>*/ *le_relocs = bin->le_relocs;
RzPVector /*<RzBinReloc *>*/ *relocs = rz_pvector_new((RzPVectorFree)rz_bin_reloc_free);
RzPVector /*<RzBinReloc *>*/ *relocs = rz_pvector_new(free);
RzBinReloc *reloc = NULL;
if (!relocs) {
fail_cleanup:
Expand Down
1 change: 1 addition & 0 deletions librz/bin/format/le/le.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ typedef struct rz_bin_le_obj_s {
RzPVector /*<RzBinImport *>*/ *imports;
HtPP /*<LE_import *, NULL>*/ *le_import_ht;
RzList /*<LE_reloc *>*/ *le_relocs;
RzList /*<LE_reloc *>*/ *le_fixups;
ut32 reloc_target_map_base;
ut32 reloc_targets_count;
} rz_bin_le_obj_t;
Expand Down
2 changes: 1 addition & 1 deletion librz/bin/format/ne/ne.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ RzPVector /*<RzBinReloc *>*/ *rz_bin_ne_get_relocs(rz_bin_ne_obj_t *bin) {
}
rz_buf_read_at(bin->buf, (ut64)bin->ne_header->ModRefTable + bin->header_offset, (ut8 *)modref, bin->ne_header->ModRefs * sizeof(ut16));

RzPVector *relocs = rz_pvector_new(free);
RzPVector *relocs = rz_pvector_new((RzPVectorFree)rz_bin_reloc_free);
if (!relocs) {
free(modref);
return NULL;
Expand Down
2 changes: 1 addition & 1 deletion librz/bin/p/bin_bflt.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ static void convert_relocs(RzBfltObj *bin, RzPVector /*<RzBinReloc *>*/ *out, Rz

static RzPVector /*<RzBinReloc *>*/ *relocs(RzBinFile *bf) {
RzBfltObj *obj = (RzBfltObj *)bf->o->bin_obj;
RzPVector *vec = rz_pvector_new((RzPVectorFree)free);
RzPVector *vec = rz_pvector_new((RzPVectorFree)rz_bin_reloc_free);
if (!vec || !obj) {
rz_pvector_free(vec);
return NULL;
Expand Down
2 changes: 1 addition & 1 deletion librz/bin/p/bin_elf.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1858,7 +1858,7 @@ static RzPVector /*<RzBinReloc *>*/ *relocs(RzBinFile *bf) {

patch_relocs(bf, bin);

if (!(ret = rz_pvector_new((RzPVectorFree)free))) {
if (!(ret = rz_pvector_new((RzPVectorFree)rz_bin_reloc_free))) {
return NULL;
}

Expand Down
2 changes: 1 addition & 1 deletion librz/bin/p/bin_mz.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ static RzPVector /*<RzBinReloc *>*/ *relocs(RzBinFile *bf) {
if (!bf || !bf->o || !bf->o->bin_obj) {
return NULL;
}
if (!(ret = rz_pvector_new(free))) {
if (!(ret = rz_pvector_new((RzPVectorFree)rz_bin_reloc_free))) {
return NULL;
}
if (!(relocs = rz_bin_mz_get_relocs(bf->o->bin_obj))) {
Expand Down
2 changes: 1 addition & 1 deletion librz/bin/p/bin_qnx.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ static RzPVector /*<RzBinReloc *>*/ *relocs(RzBinFile *bf) {
QnxObj *qo = bf->o->bin_obj;
RzBinReloc *reloc = NULL;
RzListIter *it = NULL;
RzPVector *relocs = rz_pvector_new(free);
RzPVector *relocs = rz_pvector_new((RzPVectorFree)rz_bin_reloc_free);
if (!relocs) {
return NULL;
}
Expand Down
1 change: 1 addition & 0 deletions librz/include/rz_bin.h
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,7 @@ RZ_API ut64 rz_bin_reloc_size(RzBinReloc *reloc);
struct rz_bin_reloc_storage_t {
RzBinReloc **relocs; ///< all relocs, ordered by their vaddr
size_t relocs_count;
RzPVectorFree relocs_free;
RzBinReloc **target_relocs; ///< all relocs that have a valid target_vaddr, ordered by their target_vaddr. size is target_relocs_count!
size_t target_relocs_count;
}; // RzBinRelocStorage
Expand Down
Loading