Fix UAF in md<tab> by owning the graph by core in the heap, not in stack

This commit is contained in:
pancake 2022-08-21 23:57:02 +02:00 committed by pancake
parent 82646917c7
commit 521e296fd7
4 changed files with 41 additions and 39 deletions

View File

@ -482,20 +482,17 @@ static int cmd_mount(void *data, const char *_input) {
r_cons_set_raw (false);
{
char *cwd = strdup (r_config_get (core->config, "fs.cwd"));
RFSShell shell = {
.cwd = &cwd,
.set_prompt = r_line_set_prompt,
.readline = r_line_readline,
.hist_add = r_line_hist_add
};
core->rfs = &shell;
free (core->rfs->cwd);
core->rfs->cwd = (char **)cwd;
core->rfs->set_prompt = r_line_set_prompt;
core->rfs->readline = r_line_readline;
core->rfs->hist_add = r_line_hist_add;
core->autocomplete_type = AUTOCOMPLETE_MS;
r_core_autocomplete_reload (core);
r_fs_shell_prompt (&shell, core->fs, input);
r_fs_shell_prompt (core->rfs, core->fs, input);
core->autocomplete_type = AUTOCOMPLETE_DEFAULT;
r_core_autocomplete_reload (core);
r_config_set (core->config, "fs.cwd", cwd);
R_FREE (cwd);
r_config_set (core->config, "fs.cwd", (const char *)core->rfs->cwd);
}
break;
case 'w': // "mw"

View File

@ -1150,13 +1150,12 @@ static void autocomplete_mount_point(RLineCompletion *completion, RCore *core, c
static void autocomplete_ms_path(RLineCompletion *completion, RCore *core, const char *str, const char *path) {
r_return_if_fail (completion && core && str && path);
char *lpath = NULL, *dirname = NULL , *basename = NULL;
char *p = NULL;
char *pwd = (core->rfs && core->rfs->cwd && *(core->rfs->cwd)) ? *(core->rfs->cwd): ".";
char *dirname = NULL , *basename = NULL;
char *pwd = strdup (core->rfs->cwd? (const char *)core->rfs->cwd: ".");
int n = 0;
RFSFile *file;
lpath = r_str_new (path);
p = (char *)r_str_last (lpath, R_SYS_DIR);
char *lpath = r_str_new (path);
char *p = (char *)r_str_last (lpath, R_SYS_DIR);
if (p) {
*p = 0;
if (p == lpath) { // /xxx
@ -1181,13 +1180,14 @@ static void autocomplete_ms_path(RLineCompletion *completion, RCore *core, const
}
basename = r_str_new (lpath);
}
R_FREE (pwd);
if (!dirname || !basename) {
goto out;
}
RList *list = r_fs_dir (core->fs, dirname);
n = strlen (basename);
bool chgdir = !strncmp (str, "cd ", 3);
bool chgdir = r_str_startswith (str, "cd ");
if (list) {
RListIter *iter;
r_list_foreach (list, iter, file) {
@ -1729,29 +1729,23 @@ static void autocomplete_macro(RCore *core, RLineCompletion *completion, const c
static void autocomplete_file(RLineCompletion *completion, const char *str) {
r_return_if_fail (completion && str);
char *pipe = strchr (str, '>');
if (pipe) {
str = r_str_trim_head_ro (pipe + 1);
}
if (str && !*str) {
autocomplete_process_path (completion, str, "./");
} else {
autocomplete_process_path (completion, str, str);
}
const char *arg = (str && !*str)? "./": str;
autocomplete_process_path (completion, str, arg);
}
static void autocomplete_ms_file(RCore* core, RLineCompletion *completion, const char *str) {
r_return_if_fail (str);
char *pipe = strchr (str, '>');
char *path = (core->rfs && core->rfs->cwd && *(core->rfs->cwd)) ? *(core->rfs->cwd): "/";
char *path = strdup ((core->rfs->cwd && *core->rfs->cwd) ? (const char *)core->rfs->cwd: "/");
if (pipe) {
str = r_str_trim_head_ro (pipe + 1);
}
if (str && !*str) {
autocomplete_ms_path (completion, core, str, path);
} else {
autocomplete_ms_path (completion, core, str, str);
}
const char *arg = (str && !*str)? path: str;
autocomplete_ms_path (completion, core, str, arg);
free (path);
}
static void autocomplete_charsets(RCore *core, RLineCompletion *completion, const char *str) {
@ -2992,6 +2986,7 @@ R_API bool r_core_init(RCore *core) {
}
core->chan = NULL;
r_core_setenv (core);
core->rfs = r_fs_shell_new ();
core->ev = r_event_new (core);
r_event_hook (core->ev, R_EVENT_ALL, cb_event_handler, NULL);
core->max_cmd_depth = R_CONS_CMD_DEPTH + 1;
@ -3315,6 +3310,7 @@ R_API void r_core_fini(RCore *c) {
sdb_free (c->sdb);
r_core_log_free (c->log);
r_parse_free (c->parser);
r_fs_shell_free (c->rfs);
free (c->times);
}

View File

@ -31,7 +31,7 @@ static bool handlePipes(RFS *fs, char *msg, const ut8 *data, const char *cwd) {
}
static char *fs_abspath(RFSShell *shell, const char *input) {
char *path = strdup (*shell->cwd);
char *path = strdup ((const char *)shell->cwd);
if (!strcmp (input, "..")) {
char* p = (char*) r_str_lchr (path, '/');
if (p) {
@ -64,12 +64,12 @@ static bool r_fs_shell_command(RFSShell *shell, RFS *fs, const char *buf) {
r_sandbox_system (buf + 1, 1);
} else if (r_str_startswith (buf, "echo")) {
char *msg = r_str_trim_dup (buf + 4);
if (!handlePipes (fs, msg, NULL, *shell->cwd)) {
if (!handlePipes (fs, msg, NULL, (const char *)shell->cwd)) {
cb_printf ("%s\n", msg);
}
free (msg);
} else if (r_str_startswith (buf, "getall")) {
RList *list = r_fs_dir (fs, *shell->cwd);
RList *list = r_fs_dir (fs, (const char *)shell->cwd);
r_list_foreach (list, iter, file) {
if (file->type == 'f') {
R_LOG_INFO ("Downloading: %s", file->name);
@ -108,19 +108,19 @@ static bool r_fs_shell_command(RFSShell *shell, RFS *fs, const char *buf) {
ls++;
*ls = 0;
}
if (r_str_startswith (base, *shell->cwd)) {
if (r_str_startswith (base, (const char *)shell->cwd)) {
cb_printf ("m %s\n", (r->path && r->path[0]) ? r->path + 1: "");
}
free (base);
}
free (cwd);
} else if (r_str_startswith (buf, "pwd")) {
cb_printf ("%s\n", *shell->cwd);
cb_printf ("%s\n", shell->cwd);
} else if (r_str_startswith (buf, "cd ")) {
const char *input = r_str_trim_head_ro (buf + 3);
char *abspath = fs_abspath (shell, input);
free (*shell->cwd);
*shell->cwd = abspath;
free (shell->cwd);
shell->cwd = (char **)abspath;
#if 0
RList *list = r_fs_dir (fs, path);
if (r_list_empty (list)) {
@ -256,13 +256,13 @@ static bool r_fs_shell_command(RFSShell *shell, RFS *fs, const char *buf) {
R_API int r_fs_shell_prompt(RFSShell* shell, RFS* fs, const char* root) {
r_return_val_if_fail (shell && fs, false);
if (R_STR_ISNOTEMPTY (root)) {
free (*shell->cwd);
*shell->cwd = strdup (root);
free (shell->cwd);
shell->cwd = (char **)strdup (root);
}
char buf[PROMPT_PATH_BUFSIZE];
char prompt[PROMPT_PATH_BUFSIZE];
for (;;) {
snprintf (prompt, sizeof (prompt), "[%.*s]> ", (int)sizeof (prompt) - 5, *shell->cwd);
snprintf (prompt, sizeof (prompt), "[%.*s]> ", (int)sizeof (prompt) - 5, (const char *)shell->cwd);
if (shell) {
if (shell->set_prompt) {
shell->set_prompt (prompt);

View File

@ -82,12 +82,21 @@ typedef struct r_fs_partition_t {
} RFSPartition;
typedef struct r_fs_shell_t {
char **cwd;
char **cwd; // R2_580 char *
void (*set_prompt)(const char *prompt);
const char* (*readline)(void);
int (*hist_add)(const char *line);
} RFSShell;
static inline RFSShell *r_fs_shell_new(void) {
return R_NEW0 (RFSShell);
}
static inline void r_fs_shell_free(RFSShell *s) {
free (s->cwd);
free (s);
}
#define R_FS_FILE_TYPE_MOUNTPOINT 'm'
#define R_FS_FILE_TYPE_DIRECTORY 'd'
#define R_FS_FILE_TYPE_REGULAR 'r'