Fix crash in r_anal_block_chop_noreturn (#17012)

This commit is contained in:
GustavoLCR 2020-06-12 05:19:50 -03:00 committed by GitHub
parent 6a37a4ecef
commit ae2ed249f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 1 deletions

View File

@ -634,13 +634,16 @@ R_API RAnalBlock *r_anal_block_chop_noreturn(RAnalBlock *block, ut64 addr) {
// Now, for each fcn, check which of our successors are still reachable in the function remove and the ones that are not.
RListIter *it;
RAnalFunction *fcn;
r_list_foreach (block->fcns, it, fcn) {
// We need to clone the list because block->fcns will get modified in the loop
RList *fcns_cpy = r_list_clone (block->fcns);
r_list_foreach (fcns_cpy, it, fcn) {
RAnalBlock *entry = r_anal_get_block_at (block->anal, fcn->addr);
if (entry && r_list_contains (entry->fcns, fcn)) {
r_anal_block_recurse (entry, noreturn_successors_reachable_cb, succs);
}
ht_up_foreach (succs, noreturn_remove_unreachable_cb, fcn);
}
r_list_free (fcns_cpy);
// This last step isn't really critical, but nice to have.
// Prepare to merge blocks with their predecessors if possible

View File

@ -1,4 +1,5 @@
#include <r_anal.h>
#include <r_core.h>
#include "minunit.h"
#include "test_anal_block_invars.inl"
@ -644,7 +645,33 @@ bool test_r_anal_block_automerge() {
mu_end;
}
bool test_r_anal_block_chop_noreturn(void) {
RAnal *anal = r_anal_new ();
assert_invariants (anal);
RAnalBlock *a = r_anal_create_block (anal, 0x100, 0x10);
RAnalBlock *b = r_anal_create_block (anal, 0x110, 0x10);
RAnalBlock *c = r_anal_create_block (anal, 0x120, 0x10);
a->jump = c->addr;
b->jump = c->addr;
RAnalFunction *fa = r_anal_create_function (anal, "fcn", 0x100, R_ANAL_FCN_TYPE_FCN, NULL);
r_anal_function_add_block (fa, a);
r_anal_function_add_block (fa, b);
r_anal_function_add_block (fa, c);
RAnalFunction *fb = r_anal_create_function (anal, "fcn2", 0x130, R_ANAL_FCN_TYPE_FCN, NULL);
fb->is_noreturn = true;
r_anal_block_chop_noreturn (b, 0x111);
assert_invariants (anal);
mu_end;
}
int all_tests() {
mu_run_test (test_r_anal_block_chop_noreturn);
mu_run_test (test_r_anal_block_create);
mu_run_test (test_r_anal_block_contains);
mu_run_test (test_r_anal_block_split);