From 8e42c7ec44d6417821698a07ae002b3ffacfa0d4 Mon Sep 17 00:00:00 2001 From: pancake Date: Wed, 26 Jun 2024 16:37:54 +0200 Subject: [PATCH] Fix a recently introduced uaf in pdc ##crash --- libr/anal/block.c | 26 ++++++++-------- libr/anal/function.c | 51 ++++++++++++++++--------------- libr/core/pseudo.c | 15 +++++++-- libr/util/list.c | 72 ++++++++++++++++++++++---------------------- 4 files changed, 88 insertions(+), 76 deletions(-) diff --git a/libr/anal/block.c b/libr/anal/block.c index 98a2f0a653ca4..d057fc72917a6 100644 --- a/libr/anal/block.c +++ b/libr/anal/block.c @@ -87,23 +87,23 @@ static RAnalBlock *block_new(RAnal *a, ut64 addr, ut64 size) { return block; } -static void block_free(RAnalBlock *block) { - if (!block) { +static void block_free(RAnalBlock *bb) { + if (!bb) { return; } - free (block->esil); - r_anal_cond_free (block->cond); - free (block->fingerprint); - r_anal_diff_free (block->diff); - free (block->op_bytes); - r_anal_switch_op_free (block->switch_op); - r_list_free (block->fcns); - free (block->op_pos); - free (block->parent_reg_arena); - free (block); + free (bb->esil); + r_anal_cond_free (bb->cond); + free (bb->fingerprint); + r_anal_diff_free (bb->diff); + free (bb->op_bytes); + r_anal_switch_op_free (bb->switch_op); + r_list_free (bb->fcns); + free (bb->op_pos); + free (bb->parent_reg_arena); + free (bb); } -void __block_free_rb(RBNode *node, void *user) { +R_IPI void __block_free_rb(RBNode *node, void *user) { RAnalBlock *block = unwrap (node); r_anal_block_unref (block); // block_free (block); diff --git a/libr/anal/function.c b/libr/anal/function.c index 51c60fa3bc403..090e51ddfec06 100644 --- a/libr/anal/function.c +++ b/libr/anal/function.c @@ -1,4 +1,4 @@ -/* radare - LGPL - Copyright 2019-2023 - pancake, thestr4ng3r */ +/* radare - LGPL - Copyright 2019-2024 - pancake, thestr4ng3r */ #include @@ -16,7 +16,7 @@ static bool get_functions_block_cb(RAnalBlock *block, void *user) { } R_API RList *r_anal_get_functions_in(RAnal *anal, ut64 addr) { - r_return_val_if_fail (anal, NULL); + R_RETURN_VAL_IF_FAIL (anal, NULL); RList *list = r_list_new (); if (list) { r_anal_blocks_foreach_in (anal, addr, get_functions_block_cb, list); @@ -104,7 +104,7 @@ R_API void r_anal_function_free(RAnalFunction *fcn) { r_list_foreach_safe (fcn->bbs, iter, iter2, block) { r_anal_function_remove_block (fcn, block); // r_list_delete_data (block->fcns, fcn); - //r_anal_block_unref (block); + // r_anal_block_unref (block); } // fcn->bbs->free = r_anal_block_unref; r_list_free (fcn->bbs); @@ -133,7 +133,7 @@ R_API void r_anal_function_free(RAnalFunction *fcn) { } R_API bool r_anal_add_function(RAnal *anal, RAnalFunction *fcn) { - r_return_val_if_fail (anal && fcn, false); + R_RETURN_VAL_IF_FAIL (anal && fcn, false); if (__fcn_exists (anal, fcn->name, fcn->addr)) { return false; } @@ -151,7 +151,7 @@ R_API bool r_anal_add_function(RAnal *anal, RAnalFunction *fcn) { } R_API RAnalFunction *r_anal_create_function(RAnal *anal, const char *name, ut64 addr, int type, RAnalDiff *diff) { - r_return_val_if_fail (anal && addr != UT64_MAX, NULL); + R_RETURN_VAL_IF_FAIL (anal && addr != UT64_MAX, NULL); RAnalFunction *fcn = r_anal_function_new (anal); if (!fcn) { return NULL; @@ -186,12 +186,12 @@ R_API RAnalFunction *r_anal_create_function(RAnal *anal, const char *name, ut64 } R_API bool r_anal_function_delete(RAnalFunction *fcn) { - r_return_val_if_fail (fcn, false); + R_RETURN_VAL_IF_FAIL (fcn, false); return r_list_delete_data (fcn->anal->fcns, fcn); } R_API RAnalFunction *r_anal_get_function_at(RAnal *anal, ut64 addr) { - r_return_val_if_fail (anal, NULL); + R_RETURN_VAL_IF_FAIL (anal, NULL); bool found = false; RAnalFunction *f = ht_up_find (anal->ht_addr_fun, addr, &found); if (f && found) { @@ -201,7 +201,7 @@ R_API RAnalFunction *r_anal_get_function_at(RAnal *anal, ut64 addr) { } R_API bool r_anal_function_relocate(RAnalFunction *fcn, ut64 addr) { - r_return_val_if_fail (fcn, false); + R_RETURN_VAL_IF_FAIL (fcn, false); if (fcn->addr == addr) { return true; } @@ -215,7 +215,7 @@ R_API bool r_anal_function_relocate(RAnalFunction *fcn, ut64 addr) { } R_API bool r_anal_function_rename(RAnalFunction *fcn, const char *name) { - r_return_val_if_fail (fcn && name, false); + R_RETURN_VAL_IF_FAIL (fcn && name, false); RAnal *anal = fcn->anal; RAnalFunction *existing = ht_pp_find (anal->ht_name_fun, name, NULL); if (existing) { @@ -226,21 +226,22 @@ R_API bool r_anal_function_rename(RAnalFunction *fcn, const char *name) { return false; } char *newname = strdup (name); - if (!newname) { - return false; - } - bool in_tree = ht_pp_delete (anal->ht_name_fun, fcn->name); - free (fcn->name); - fcn->name = newname; - if (in_tree) { - // only re-insert if it really was in the tree before - ht_pp_insert (anal->ht_name_fun, fcn->name, fcn); + if (R_LIKELY (newname)) { + bool in_tree = ht_pp_delete (anal->ht_name_fun, fcn->name); + free (fcn->name); + fcn->name = newname; + if (in_tree) { + // only re-insert if it really was in the tree before + ht_pp_insert (anal->ht_name_fun, fcn->name, fcn); + } + return true; } - return true; + return false; } R_API void r_anal_function_add_block(RAnalFunction *fcn, RAnalBlock *bb) { - r_return_if_fail (fcn && bb); + R_RETURN_IF_FAIL (fcn && bb); + // XXX this is slow use skiplist or vector instead if (r_list_contains (bb->fcns, fcn)) { return; } @@ -263,7 +264,7 @@ R_API void r_anal_function_add_block(RAnalFunction *fcn, RAnalBlock *bb) { } R_API void r_anal_function_remove_block(RAnalFunction *fcn, RAnalBlock *bb) { - r_return_if_fail (fcn && bb); + R_RETURN_IF_FAIL (fcn && bb); r_list_delete_data (bb->fcns, fcn); if (fcn->meta._min != UT64_MAX @@ -317,7 +318,7 @@ R_API ut64 r_anal_function_size_from_entry(RAnalFunction *fcn) { } R_API ut64 r_anal_function_realsize(const RAnalFunction *fcn) { - r_return_val_if_fail (fcn, UT64_MAX); + R_RETURN_VAL_IF_FAIL (fcn, UT64_MAX); RListIter *iter; RAnalBlock *bb; ut64 sz = 0; @@ -339,7 +340,7 @@ static bool fcn_in_cb(RAnalBlock *block, void *user) { } R_API bool r_anal_function_contains(RAnalFunction *fcn, ut64 addr) { - r_return_val_if_fail (fcn, false); + R_RETURN_VAL_IF_FAIL (fcn, false); if (addr == UT64_MAX) { return false; } @@ -348,7 +349,7 @@ R_API bool r_anal_function_contains(RAnalFunction *fcn, ut64 addr) { } R_API bool r_anal_function_was_modified(RAnalFunction *fcn) { - r_return_val_if_fail (fcn, false); + R_RETURN_VAL_IF_FAIL (fcn, false); RListIter *it; RAnalBlock *bb; r_list_foreach (fcn->bbs, it, bb) { @@ -373,7 +374,7 @@ R_API int r_anal_function_coverage(RAnalFunction *fcn) { } R_API RGraph *r_anal_function_get_graph(RAnalFunction *fcn, RGraphNode **node_ptr, ut64 addr) { - r_return_val_if_fail (fcn && fcn->bbs && r_list_length (fcn->bbs), NULL); + R_RETURN_VAL_IF_FAIL (fcn && fcn->bbs && r_list_length (fcn->bbs), NULL); HtUP *nodes = ht_up_new0 (); RGraph *g = r_graph_new (); if (node_ptr) { diff --git a/libr/core/pseudo.c b/libr/core/pseudo.c index 1a2cf703f2af0..e2d78e32b7c08 100644 --- a/libr/core/pseudo.c +++ b/libr/core/pseudo.c @@ -638,6 +638,12 @@ R_API int r_core_pseudo_code(RCore *core, const char *input) { if (r_list_contains (visited, bb)) { continue; } + ut64 nextbbaddr = UT64_MAX; + if (iter->n) { + RListIter *nit = (RListIter*)(iter->n); + RAnalBlock *nbb = (RAnalBlock*)(nit->data); + nextbbaddr = nbb->addr; + } if (use_html) { r_config_set_b (core->config, "scr.html", false); } @@ -699,11 +705,16 @@ R_API int r_core_pseudo_code(RCore *core, const char *input) { } else { PRINTF ("loc_0x%08"PFMT64x": // orphan\n%s", bb->addr, s); } - ut64 nbbaddr = UT64_MAX; + ut64 nbbaddr = nextbbaddr; // UT64_MAX; +#if 0 + eprintf ("iter %p %p\n", iter, iter->n); + if (nextbbaddr) { + } if (iter->n) { - RAnalBlock *nbb = (RAnalBlock*)iter->n; + RAnalBlock *nbb = (RAnalBlock*)(iter->n); nbbaddr = nbb->addr; } +#endif if (bb->jump == UT64_MAX) { NEWLINE (bb->addr, indent); if (r0) { diff --git a/libr/util/list.c b/libr/util/list.c index 278a9dc94abbb..214098f2e1955 100644 --- a/libr/util/list.c +++ b/libr/util/list.c @@ -1,4 +1,4 @@ -/* radare - LGPL - Copyright 2007-2022 - pancake, alvarofe */ +/* radare - LGPL - Copyright 2007-2024 - pancake, alvarofe */ #define _R_LIST_C_ #include "r_util.h" @@ -24,22 +24,22 @@ R_API void r_list_iter_free(RListIter *list) { } R_API RListIter *r_list_iter_get_next(RListIter *list) { - r_return_val_if_fail (list, NULL); + R_RETURN_VAL_IF_FAIL (list, NULL); return list->n; } R_API RListIter *r_list_iter_get_prev(RListIter *list) { - r_return_val_if_fail (list, NULL); + R_RETURN_VAL_IF_FAIL (list, NULL); return list->p; } R_API void *r_list_iter_get_data(RListIter *list) { - r_return_val_if_fail (list, NULL); + R_RETURN_VAL_IF_FAIL (list, NULL); return list->data; } R_API RListIter *r_list_iterator(const RList *list) { - r_return_val_if_fail (list, NULL); + R_RETURN_VAL_IF_FAIL (list, NULL); return list->head; } @@ -48,18 +48,18 @@ R_API RListIter *r_list_push(RList *list, void *item) { } R_API RListIter *r_list_get_next(RListIter *list) { - r_return_val_if_fail (list, NULL); + R_RETURN_VAL_IF_FAIL (list, NULL); return list->n; } // rename to head/last R_API void *r_list_first(const RList *list) { - r_return_val_if_fail (list, NULL); + R_RETURN_VAL_IF_FAIL (list, NULL); return list->head ? list->head->data : NULL; } R_API void *r_list_last(const RList *list) { - r_return_val_if_fail (list, NULL); + R_RETURN_VAL_IF_FAIL (list, NULL); return list->tail ? list->tail->data : NULL; } @@ -72,7 +72,7 @@ R_API void r_list_init(RList *list) { } R_API int r_list_length(const RList *list) { - r_return_val_if_fail (list, 0); + R_RETURN_VAL_IF_FAIL (list, 0); return list->length; } @@ -103,7 +103,7 @@ R_API bool r_list_delete_data(RList *list, void *ptr) { void *p; RListIter *iter; - r_return_val_if_fail (list, false); + R_RETURN_VAL_IF_FAIL (list, false); r_list_foreach (list, iter, p) { if (ptr == p) { @@ -115,7 +115,7 @@ R_API bool r_list_delete_data(RList *list, void *ptr) { } R_API void r_list_delete(RList *list, RListIter *iter) { - r_return_if_fail (list && iter); + R_RETURN_IF_FAIL (list && iter); r_list_split_iter (list, iter); if (list->free && iter->data) { list->free (iter->data); @@ -125,7 +125,7 @@ R_API void r_list_delete(RList *list, RListIter *iter) { } R_API void r_list_split(RList *list, void *ptr) { - r_return_if_fail (list); + R_RETURN_IF_FAIL (list); RListIter *iter = r_list_iterator (list); while (iter) { @@ -140,7 +140,7 @@ R_API void r_list_split(RList *list, void *ptr) { } R_API void r_list_split_iter(RList *list, RListIter *iter) { - r_return_if_fail (list); + R_RETURN_IF_FAIL (list); if (list->head == iter) { list->head = iter->n; @@ -159,7 +159,7 @@ R_API void r_list_split_iter(RList *list, RListIter *iter) { //Warning: free functions must be compatible R_API int r_list_join(RList *list1, RList *list2) { - r_return_val_if_fail (list1 && list2, 0); + R_RETURN_VAL_IF_FAIL (list1 && list2, 0); if (!(list2->length)) { return 0; @@ -206,7 +206,7 @@ R_API RListIter *r_list_item_new(void *data) { } R_API RListIter *r_list_append(RList *list, void *data) { - r_return_val_if_fail (list, NULL); + R_RETURN_VAL_IF_FAIL (list, NULL); RListIter *item = r_list_item_new (data); if (!item) { @@ -226,7 +226,7 @@ R_API RListIter *r_list_append(RList *list, void *data) { } R_API RListIter *r_list_prepend(RList *list, void *data) { - r_return_val_if_fail (list, NULL); + R_RETURN_VAL_IF_FAIL (list, NULL); RListIter *item = r_list_item_new (data); if (!item) { @@ -246,7 +246,7 @@ R_API RListIter *r_list_prepend(RList *list, void *data) { } R_API RListIter *r_list_insert(RList *list, ut32 n, void *data) { - r_return_val_if_fail (list, NULL); + R_RETURN_VAL_IF_FAIL (list, NULL); if (!list->head || !n) { return r_list_prepend (list, data); @@ -278,7 +278,7 @@ R_API void *r_list_pop(RList *list) { void *data = NULL; RListIter *iter; - r_return_val_if_fail (list, NULL); + R_RETURN_VAL_IF_FAIL (list, NULL); if (list->tail) { iter = list->tail; @@ -298,7 +298,7 @@ R_API void *r_list_pop(RList *list) { R_API void *r_list_pop_head(RList *list) { void *data = NULL; - r_return_val_if_fail (list, NULL); + R_RETURN_VAL_IF_FAIL (list, NULL); if (list->head) { RListIter *iter = list->head; @@ -319,7 +319,7 @@ R_API int r_list_del_n(RList *list, int n) { RListIter *it; int i; - r_return_val_if_fail (list, false); + R_RETURN_VAL_IF_FAIL (list, false); for (it = list->head, i = 0; it && it->data; it = it->n, i++) { if (i == n) { @@ -344,13 +344,13 @@ R_API int r_list_del_n(RList *list, int n) { } R_DEPRECATE R_API void *r_list_get_top(const RList *list) { - r_return_val_if_fail (list, NULL); + R_RETURN_VAL_IF_FAIL (list, NULL); return list->tail ? list->tail->data : NULL; } R_DEPRECATE R_API void *r_list_get_bottom(const RList *list) { - r_return_val_if_fail (list, NULL); + R_RETURN_VAL_IF_FAIL (list, NULL); return list->head ? list->head->data : NULL; } @@ -358,7 +358,7 @@ R_DEPRECATE R_API void *r_list_get_bottom(const RList *list) { // Moves an iter to the top(tail) of the list // There is an underlying assumption here, that iter is an RListIter of this RList R_API void r_list_iter_to_top(RList *list, RListIter *iter) { - r_return_if_fail (list && iter); + R_RETURN_IF_FAIL (list && iter); if (list->tail == iter) { return; } @@ -378,7 +378,7 @@ R_API void r_list_iter_to_top(RList *list, RListIter *iter) { R_API void r_list_reverse(RList *list) { RListIter *it, *tmp; - r_return_if_fail (list); + R_RETURN_IF_FAIL (list); for (it = list->head; it && it->data; it = it->p) { tmp = it->p; @@ -394,7 +394,7 @@ R_API RList *r_list_clone(const RList *list, RListClone clone) { RListIter *iter; void *data; - r_return_val_if_fail (list, NULL); + R_RETURN_VAL_IF_FAIL (list, NULL); RList *l = r_list_new (); if (!l) { @@ -418,7 +418,7 @@ R_API RList *r_list_clone(const RList *list, RListClone clone) { R_API RListIter *r_list_add_sorted(RList *list, void *data, RListComparator cmp) { RListIter *it, *item = NULL; - r_return_val_if_fail (list && data && cmp, NULL); + R_RETURN_VAL_IF_FAIL (list && data && cmp, NULL); for (it = list->head; it && it->data && cmp (data, it->data) > 0; it = it->n) { ; @@ -449,7 +449,7 @@ R_API int r_list_set_n(RList *list, int n, void *p) { RListIter *it; int i; - r_return_val_if_fail (list, false); + R_RETURN_VAL_IF_FAIL (list, false); for (it = list->head, i = 0; it ; it = it->n, i++) { if (i == n) { if (list->free) { @@ -467,7 +467,7 @@ R_API void *r_list_get_n(const RList *list, int n) { RListIter *it; int i; - r_return_val_if_fail (list, NULL); + R_RETURN_VAL_IF_FAIL (list, NULL); for (it = list->head, i = 0; it && it->data; it = it->n, i++) { if (i == n) { @@ -481,7 +481,7 @@ R_API RListIter *r_list_contains(const RList *list, const void *p) { void *q; RListIter *iter; - r_return_val_if_fail (list, NULL); + R_RETURN_VAL_IF_FAIL (list, NULL); r_list_foreach (list, iter, q) { if (p == q) { @@ -495,7 +495,7 @@ R_API RListIter *r_list_find(const RList *list, const void *p, RListComparator c void *q; RListIter *iter; - r_return_val_if_fail (list, NULL); + R_RETURN_VAL_IF_FAIL (list, NULL); r_list_foreach (list, iter, q) { if (!cmp (p, q)) { @@ -588,7 +588,7 @@ static RListIter *_merge_sort(RListIter *head, RListComparator cmp) { } R_API void r_list_merge_sort(RList *list, RListComparator cmp) { - r_return_if_fail (list); + R_RETURN_IF_FAIL (list); if (!list->sorted && list->head && cmp) { RListIter *iter; @@ -604,7 +604,7 @@ R_API void r_list_merge_sort(RList *list, RListComparator cmp) { } R_API void r_list_insertion_sort(RList *list, RListComparator cmp) { - r_return_if_fail (list); + R_RETURN_IF_FAIL (list); if (!list->sorted) { RListIter *it; @@ -624,9 +624,9 @@ R_API void r_list_insertion_sort(RList *list, RListComparator cmp) { } } -//chose wisely based on length +// chose wisely based on length R_API void r_list_sort(RList *list, RListComparator cmp) { - r_return_if_fail (list); + R_RETURN_IF_FAIL (list); if (list->length > MERGE_LIMIT) { r_list_merge_sort (list, cmp); } else { @@ -638,7 +638,7 @@ R_API RList *r_list_uniq(const RList *list, RListComparatorItem cmp) { RListIter *iter, *iter2; void *item; - r_return_val_if_fail (list && cmp, 0); + R_RETURN_VAL_IF_FAIL (list && cmp, 0); RList *rlist = r_list_newf (list->free); SetU *s = set_u_new (); r_list_foreach_safe (list, iter, iter2, item) { @@ -657,7 +657,7 @@ R_API int r_list_uniq_inplace(RList *list, RListComparatorItem cmp) { void *item; int deleted = 0; - r_return_val_if_fail (list && cmp, 0); + R_RETURN_VAL_IF_FAIL (list && cmp, 0); SetU *s = set_u_new (); r_list_foreach_safe (list, iter, iter2, item) { ut64 v = cmp (item);