Fix double free and reject invalid values for search.in (#6327)

This commit is contained in:
Rot127
2026-05-11 13:01:53 +08:00
committed by GitHub
parent f1251293a4
commit 045fff363b
6 changed files with 99 additions and 63 deletions
+70 -56
View File
@@ -646,6 +646,75 @@ RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_debug_program(RZ_NO
return list;
}
/**
* \brief Returns a list of boundaries (as RzIOMap), based on the selected mode; see [search/analysis/zoom/[in/from/to]] for available modes.
*
* \param core The RzCore to use
* \param interval The address range of the boundaries.
* \param region The region of the boundaries. Check valid ones with `e search.in=?`.
*
* \return On success a valid pointer (can be an empty list), otherwise NULL
*/
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries(RZ_NONNULL RzCore *core, RzInterval interval, const char *region) {
rz_return_val_if_fail(core, NULL);
if (!strcmp(region, "raw") || !strcmp(region, "file")) {
return rz_core_get_boundaries_raw(core, interval);
} else if (!strcmp(region, "block")) {
return rz_core_get_boundaries_block(core, interval);
} else if (!strcmp(region, "dbg.map")) {
return rz_core_get_boundaries_current_debug_map(core, interval);
} else if (!strcmp(region, "io.map")) {
return rz_core_get_boundaries_current_io_map(core, interval);
} else if (!strcmp(region, "range") || !strcmp(region, "io.maps")) {
return rz_core_get_boundaries_all_io_maps(core, interval);
} else if (!strcmp(region, "io.sky")) {
return rz_core_get_boundaries_all_io_skyline(core, interval);
} else if (!strcmp(region, "code")) {
return rz_core_get_boundaries_code_only(core, interval);
} else if (!strcmp(region, "bin.segment")) {
return rz_core_get_boundaries_current_bin_segment(core, interval);
} else if (!strcmp(region, "bin.section")) {
return rz_core_get_boundaries_current_bin_section(core, interval);
} else if (!strcmp(region, "bin.segments")) {
return rz_core_get_boundaries_all_bin_segments(core, interval);
} else if (!strcmp(region, "bin.sections")) {
return rz_core_get_boundaries_all_bin_sections(core, interval);
} else if (!strcmp(region, "analysis.fcn")) {
return rz_core_get_boundaries_current_function(core, interval);
} else if (!strcmp(region, "analysis.bb")) {
return rz_core_get_boundaries_current_function_bb(core, interval);
} else if (!strcmp(region, "dbg.maps")) {
return rz_core_get_boundaries_all_debug_maps(core, interval);
} else if (!strcmp(region, "dbg.heap")) {
return rz_core_get_boundaries_debug_heap(core, interval);
} else if (!strcmp(region, "dbg.stack")) {
return rz_core_get_boundaries_debug_stack(core, interval);
} else if (!strcmp(region, "dbg.program")) {
return rz_core_get_boundaries_debug_program(core, interval);
} else if (rz_str_startswith(region, "dbg.maps.")) {
#define PARSE_PERMS(input, mode_name) rz_str_rwx(input + strlen(mode_name))
int perms = PARSE_PERMS(region, "dbg.maps.");
return rz_core_get_boundaries_debug_maps(core, interval, perms, perms, false);
} else if (rz_str_startswith(region, "io.sky.")) {
int perms = PARSE_PERMS(region, "io.sky.");
return rz_core_get_boundaries_io_skyline(core, interval, perms, perms);
} else if (rz_str_startswith(region, "io.maps.")) {
int perms = PARSE_PERMS(region, "io.maps.");
return rz_core_get_boundaries_io_maps(core, interval, perms, perms);
} else if (rz_str_startswith(region, "bin.segments.")) {
int perms = PARSE_PERMS(region, "bin.segments.");
return rz_core_get_boundaries_bin_segments(core, interval, perms, perms);
} else if (rz_str_startswith(region, "bin.sections.")) {
int perms = PARSE_PERMS(region, "bin.sections.");
return rz_core_get_boundaries_bin_sections(core, interval, perms, perms);
#undef PARSE_PERMS
}
RZ_LOG_ERROR("core: Invalid mode '%s' for [0x%" PFMT64x ", 0x%" PFMT64x "]\n",
region, interval.addr, interval.size);
return NULL;
}
/**
* \brief Returns a list of boundaries (as RzIOMap), based on the selected mode; see [search/analysis/zoom/[in/from/to]] for available modes.
*
@@ -666,60 +735,5 @@ RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_select(RZ_NONNULL R
interval.addr = from;
interval.size = to - from;
if (!strcmp(use_mode, "raw") || !strcmp(use_mode, "file")) {
return rz_core_get_boundaries_raw(core, interval);
} else if (!strcmp(use_mode, "block")) {
return rz_core_get_boundaries_block(core, interval);
} else if (!strcmp(use_mode, "dbg.map")) {
return rz_core_get_boundaries_current_debug_map(core, interval);
} else if (!strcmp(use_mode, "io.map")) {
return rz_core_get_boundaries_current_io_map(core, interval);
} else if (!strcmp(use_mode, "range") || !strcmp(use_mode, "io.maps")) {
return rz_core_get_boundaries_all_io_maps(core, interval);
} else if (!strcmp(use_mode, "io.sky")) {
return rz_core_get_boundaries_all_io_skyline(core, interval);
} else if (!strcmp(use_mode, "code")) {
return rz_core_get_boundaries_code_only(core, interval);
} else if (!strcmp(use_mode, "bin.segment")) {
return rz_core_get_boundaries_current_bin_segment(core, interval);
} else if (!strcmp(use_mode, "bin.section")) {
return rz_core_get_boundaries_current_bin_section(core, interval);
} else if (!strcmp(use_mode, "bin.segments")) {
return rz_core_get_boundaries_all_bin_segments(core, interval);
} else if (!strcmp(use_mode, "bin.sections")) {
return rz_core_get_boundaries_all_bin_sections(core, interval);
} else if (!strcmp(use_mode, "analysis.fcn")) {
return rz_core_get_boundaries_current_function(core, interval);
} else if (!strcmp(use_mode, "analysis.bb")) {
return rz_core_get_boundaries_current_function_bb(core, interval);
} else if (!strcmp(use_mode, "dbg.maps")) {
return rz_core_get_boundaries_all_debug_maps(core, interval);
} else if (!strcmp(use_mode, "dbg.heap")) {
return rz_core_get_boundaries_debug_heap(core, interval);
} else if (!strcmp(use_mode, "dbg.stack")) {
return rz_core_get_boundaries_debug_stack(core, interval);
} else if (!strcmp(use_mode, "dbg.program")) {
return rz_core_get_boundaries_debug_program(core, interval);
} else if (rz_str_startswith(use_mode, "dbg.maps.")) {
#define PARSE_PERMS(input, mode_name) rz_str_rwx(input + strlen(mode_name))
int perms = PARSE_PERMS(use_mode, "dbg.maps.");
return rz_core_get_boundaries_debug_maps(core, interval, perms, perms, false);
} else if (rz_str_startswith(use_mode, "io.sky.")) {
int perms = PARSE_PERMS(use_mode, "io.sky.");
return rz_core_get_boundaries_io_skyline(core, interval, perms, perms);
} else if (rz_str_startswith(use_mode, "io.maps.")) {
int perms = PARSE_PERMS(use_mode, "io.maps.");
return rz_core_get_boundaries_io_maps(core, interval, perms, perms);
} else if (rz_str_startswith(use_mode, "bin.segments.")) {
int perms = PARSE_PERMS(use_mode, "bin.segments.");
return rz_core_get_boundaries_bin_segments(core, interval, perms, perms);
} else if (rz_str_startswith(use_mode, "bin.sections.")) {
int perms = PARSE_PERMS(use_mode, "bin.sections.");
return rz_core_get_boundaries_bin_sections(core, interval, perms, perms);
#undef PARSE_PERMS
}
RZ_LOG_ERROR("core: unknown mode '%s' for %s\n", use_mode, in_key);
return NULL;
return rz_core_get_boundaries(core, interval, use_mode);
}
+10
View File
@@ -2566,7 +2566,17 @@ static ConfigOptDescr search_in_opts[] = {
static bool cb_search_in(void *user, void *data) {
RzConfigNode *node = (RzConfigNode *)data;
RzCore *core = (RzCore *)user;
RzInterval itv = {
.addr = rz_config_get_i(core->config, "search.from"),
.size = rz_config_get_i(core->config, "search.to")
};
if (node->value[0] != '?') {
RzList *bounds = rz_core_get_boundaries(core, itv, node->value);
if (!bounds) {
return false;
}
rz_list_free(bounds);
return true;
} else if (strlen(node->value) > 1 && node->value[1] == '?') {
rz_cons_printf("Valid values for search.in (depends on .from/.to and io.va):\n");
+5 -6
View File
@@ -1228,6 +1228,7 @@ static void __core_cmd_search_asm_infinite(RzCore *core, const char *arg) {
}
free(buf);
}
rz_list_free(boundaries);
}
static void __core_cmd_search_asm_byteswap(RzCore *core, int nth) {
@@ -1700,6 +1701,10 @@ static RzSearchOpt *setup_search_options(RzCore *core) {
}
static RzCmdStatus byte_pattern_search(RzCore *core, RZ_OWN RzSearchBytesPattern *pattern, RzCmdStateOutput *state) {
if (!pattern) {
RZ_LOG_ERROR("Failed to parse given pattern.\n");
return RZ_CMD_STATUS_ERROR;
}
RzSearchOpt *search_opts = setup_search_options(core);
RzList *hits = NULL;
if (!search_opts) {
@@ -1709,11 +1714,6 @@ static RzCmdStatus byte_pattern_search(RzCore *core, RZ_OWN RzSearchBytesPattern
CMD_SEARCH_BEGIN();
if (!pattern) {
RZ_LOG_ERROR("Failed to parse given pattern.\n");
goto error;
}
bool progress = rz_search_opt_get_show_progress(search_opts) != RZ_SEARCH_PROGRESS_DISABLED;
if (!rz_search_opt_set_cancel_cb(search_opts, cmd_search_progress_cancel, progress ? state : NULL)) {
RZ_LOG_ERROR("code: Failed to setup default search options.\n");
@@ -1731,7 +1731,6 @@ static RzCmdStatus byte_pattern_search(RzCore *core, RZ_OWN RzSearchBytesPattern
return cmd_core_handle_search_hits(core, state, hits);
error:
rz_search_bytes_pattern_free(pattern);
rz_list_free(hits);
rz_search_opt_free(search_opts);
CMD_SEARCH_END();
+1
View File
@@ -1204,6 +1204,7 @@ RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_debug_heap(RZ_NONNU
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_debug_stack(RZ_NONNULL RzCore *core, const RzInterval interval);
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_debug_program(RZ_NONNULL RzCore *core, const RzInterval interval);
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_select(RZ_NONNULL RzCore *core, RZ_NONNULL const char *from_key, RZ_NONNULL const char *to_key, RZ_NONNULL const char *in_key);
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries(RZ_NONNULL RzCore *core, RzInterval interval, const char *region);
RZ_API bool rz_core_hack(RzCore *core, const char *op);
RZ_API bool rz_core_dump(RzCore *core, const char *file, ut64 addr, ut64 size, int append);
+1 -1
View File
@@ -1003,8 +1003,8 @@ RZ_API int rz_main_rizin(int argc, const char **argv) {
if (asmbits) {
rz_config_set(r->config, "asm.bits", asmbits);
}
rz_config_set(r->config, "search.in", "dbg.map"); // implicit?
rz_config_set(r->config, "cfg.debug", "true");
rz_config_set(r->config, "search.in", "dbg.map");
perms = RZ_PERM_RWX;
if (opt.ind >= argc) {
RZ_LOG_ERROR("No program given to -d\n");
+12
View File
@@ -458,3 +458,15 @@ EXPECT=<<EOF
0x00000076
EOF
RUN
NAME=Heap use after free
FILE==
CMDS=<<EOF
e search.in=section
/x deadbeef
EOF
EXPECT=<<EOF
EOF
EXPECT_ERR=<<EOF
ERROR: core: Invalid mode 'section' for [0x0, 0xffffffffffffffff]
EOF