mirror of
https://github.com/radareorg/radare2.git
synced 2025-03-01 18:57:20 +00:00
Fix #9015 - use after free when quitting main thread having background server threads
This commit is contained in:
parent
ff8959f1b0
commit
a8897b107d
@ -1842,10 +1842,11 @@ R_API RCore *r_core_fini(RCore *c) {
|
|||||||
if (!c) {
|
if (!c) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
r_core_wait (c);
|
||||||
/* TODO: it leaks as shit */
|
/* TODO: it leaks as shit */
|
||||||
//update_sdb (c);
|
//update_sdb (c);
|
||||||
// avoid double free
|
// avoid double free
|
||||||
r_core_free_autocomplete(c);
|
r_core_free_autocomplete (c);
|
||||||
R_FREE (c->lastsearch);
|
R_FREE (c->lastsearch);
|
||||||
c->cons->pager = NULL;
|
c->cons->pager = NULL;
|
||||||
r_core_task_join (c, NULL);
|
r_core_task_join (c, NULL);
|
||||||
@ -1898,6 +1899,7 @@ R_API RCore *r_core_fini(RCore *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
R_API RCore *r_core_free(RCore *c) {
|
R_API RCore *r_core_free(RCore *c) {
|
||||||
|
// must wait all threads first
|
||||||
if (c) {
|
if (c) {
|
||||||
r_core_fini (c);
|
r_core_fini (c);
|
||||||
free (c);
|
free (c);
|
||||||
@ -2169,26 +2171,23 @@ static void rap_break (void *u) {
|
|||||||
|
|
||||||
// TODO: PLEASE move into core/io/rap? */
|
// TODO: PLEASE move into core/io/rap? */
|
||||||
// TODO: use static buffer instead of mallocs all the time. it's network!
|
// TODO: use static buffer instead of mallocs all the time. it's network!
|
||||||
R_API int r_core_serve(RCore *core, RIODesc *file) {
|
R_API bool r_core_serve(RCore *core, RIODesc *file) {
|
||||||
ut8 cmd, flg, *ptr = NULL, buf[1024];
|
ut8 cmd, flg, *ptr = NULL, buf[1024];
|
||||||
RSocket *c, *fd;
|
|
||||||
int i, pipefd = -1;
|
int i, pipefd = -1;
|
||||||
RIORap *rior;
|
|
||||||
ut64 x;
|
ut64 x;
|
||||||
|
|
||||||
rior = (RIORap *)file->data;
|
RIORap *rior = (RIORap *)file->data;
|
||||||
if (!rior|| !rior->fd) {
|
if (!rior|| !rior->fd) {
|
||||||
eprintf ("rap: cannot listen.\n");
|
eprintf ("rap: cannot listen.\n");
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
fd = rior->fd;
|
RSocket *fd = rior->fd;
|
||||||
eprintf ("RAP Server started (rap.loop=%s)\n",
|
eprintf ("RAP Server started (rap.loop=%s)\n",
|
||||||
r_config_get (core->config, "rap.loop"));
|
r_config_get (core->config, "rap.loop"));
|
||||||
|
|
||||||
r_cons_break_push (rap_break, rior);
|
r_cons_break_push (rap_break, rior);
|
||||||
reaccept:
|
reaccept:
|
||||||
while (!r_cons_is_breaked ()) {
|
while (!r_cons_is_breaked ()) {
|
||||||
c = r_socket_accept (fd);
|
RSocket *c = r_socket_accept (fd);
|
||||||
if (!c) {
|
if (!c) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2222,15 +2221,14 @@ reaccept:
|
|||||||
if (!ptr) {
|
if (!ptr) {
|
||||||
eprintf ("Cannot malloc in rmt-open len = %d\n", cmd);
|
eprintf ("Cannot malloc in rmt-open len = %d\n", cmd);
|
||||||
} else {
|
} else {
|
||||||
RCoreFile *file;
|
|
||||||
ut64 baddr = r_config_get_i (core->config, "bin.laddr");
|
ut64 baddr = r_config_get_i (core->config, "bin.laddr");
|
||||||
r_socket_read_block (c, ptr, cmd); //filename
|
r_socket_read_block (c, ptr, cmd);
|
||||||
ptr[cmd] = 0;
|
ptr[cmd] = 0;
|
||||||
ut32 perm = R_IO_READ;
|
ut32 perm = R_IO_READ;
|
||||||
if (flg & R_IO_WRITE) {
|
if (flg & R_IO_WRITE) {
|
||||||
perm |= R_IO_WRITE;
|
perm |= R_IO_WRITE;
|
||||||
}
|
}
|
||||||
file = r_core_file_open (core, (const char *)ptr, perm, 0);
|
RCoreFile *file = r_core_file_open (core, (const char *)ptr, perm, 0);
|
||||||
if (file) {
|
if (file) {
|
||||||
r_core_bin_load (core, NULL, baddr);
|
r_core_bin_load (core, NULL, baddr);
|
||||||
r_io_map_add (core->io, file->fd, perm, 0, 0, r_io_fd_size (core->io, file->fd), true);
|
r_io_map_add (core->io, file->fd, perm, 0, 0, r_io_fd_size (core->io, file->fd), true);
|
||||||
@ -2414,7 +2412,7 @@ reaccept:
|
|||||||
}
|
}
|
||||||
out_of_function:
|
out_of_function:
|
||||||
r_cons_break_pop ();
|
r_cons_break_pop ();
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
R_API int r_core_search_cb(RCore *core, ut64 from, ut64 to, RCoreSearchCallback cb) {
|
R_API int r_core_search_cb(RCore *core, ut64 from, ut64 to, RCoreSearchCallback cb) {
|
||||||
|
@ -39,9 +39,17 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
RCore *core;
|
RCore *core;
|
||||||
const char* input;
|
char* input;
|
||||||
} RapThread;
|
} RapThread;
|
||||||
|
|
||||||
|
R_API void r_core_wait(RCore *core) {
|
||||||
|
r_cons_singleton () -> breaked = true;
|
||||||
|
r_th_kill (httpthread, true);
|
||||||
|
r_th_kill (rapthread, true);
|
||||||
|
r_th_wait (httpthread);
|
||||||
|
r_th_wait (rapthread);
|
||||||
|
}
|
||||||
|
|
||||||
static void http_logf(RCore *core, const char *fmt, ...) {
|
static void http_logf(RCore *core, const char *fmt, ...) {
|
||||||
bool http_log_enabled = r_config_get_i (core->config, "http.log");
|
bool http_log_enabled = r_config_get_i (core->config, "http.log");
|
||||||
va_list ap;
|
va_list ap;
|
||||||
@ -1609,17 +1617,18 @@ R_API void r_core_rtr_session(RCore *core, const char *input) {
|
|||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
prompt[0] = 0;
|
prompt[0] = 0;
|
||||||
if (IS_DIGIT(input[0])) {
|
if (IS_DIGIT (input[0])) {
|
||||||
fd = r_num_math (core->num, input);
|
fd = r_num_math (core->num, input);
|
||||||
for (rtr_n = 0; rtr_host[rtr_n].fd \
|
for (rtr_n = 0; rtr_host[rtr_n].fd \
|
||||||
&& rtr_host[rtr_n].fd->fd != fd \
|
&& rtr_host[rtr_n].fd->fd != fd \
|
||||||
&& rtr_n < RTR_MAX_HOSTS - 1; rtr_n++);
|
&& rtr_n < RTR_MAX_HOSTS - 1; rtr_n++);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
while (!r_cons_is_breaked ()) {
|
||||||
if (rtr_host[rtr_n].fd)
|
if (rtr_host[rtr_n].fd) {
|
||||||
snprintf (prompt, sizeof (prompt),
|
snprintf (prompt, sizeof (prompt),
|
||||||
"fd:%d> ", rtr_host[rtr_n].fd->fd);
|
"fd:%d> ", rtr_host[rtr_n].fd->fd);
|
||||||
|
}
|
||||||
free (r_line_singleton ()->prompt);
|
free (r_line_singleton ()->prompt);
|
||||||
r_line_singleton ()->prompt = strdup (prompt);
|
r_line_singleton ()->prompt = strdup (prompt);
|
||||||
if (r_cons_fgets (buf, sizeof (buf), 0, NULL) < 1) {
|
if (r_cons_fgets (buf, sizeof (buf), 0, NULL) < 1) {
|
||||||
@ -1653,9 +1662,22 @@ static void r_rap_packet_fill(ut8 *buf, const ut8* src, int len) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void r_core_rtr_rap_run(RCore *core, const char *input) {
|
static bool r_core_rtr_rap_run(RCore *core, const char *input) {
|
||||||
/* ouch, this hurts a bit, isnt? */
|
char *file = r_str_newf ("rap://%s", input);
|
||||||
r_core_cmdf (core, "o rap://%s", input);
|
int flags = R_IO_READ | R_IO_WRITE;
|
||||||
|
RIODesc *fd = r_io_open_nomap (core->io, file, flags, 0644);
|
||||||
|
if (fd) {
|
||||||
|
if (r_io_is_listener (core->io)) {
|
||||||
|
if (!r_core_serve (core, fd)) {
|
||||||
|
r_cons_singleton() -> breaked = true;
|
||||||
|
}
|
||||||
|
r_io_desc_free (fd);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
r_cons_singleton()->breaked = true;
|
||||||
|
}
|
||||||
|
return !r_cons_singleton ()->breaked;
|
||||||
|
// r_core_cmdf (core, "o rap://%s", input);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int r_core_rtr_rap_thread (RThread *th) {
|
static int r_core_rtr_rap_thread (RThread *th) {
|
||||||
@ -1666,8 +1688,7 @@ static int r_core_rtr_rap_thread (RThread *th) {
|
|||||||
if (!rt || !rt->core) {
|
if (!rt || !rt->core) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
r_core_rtr_rap_run (rt->core, rt->input);
|
return r_core_rtr_rap_run (rt->core, rt->input);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
R_API void r_core_rtr_cmd(RCore *core, const char *input) {
|
R_API void r_core_rtr_cmd(RCore *core, const char *input) {
|
||||||
@ -1687,11 +1708,16 @@ R_API void r_core_rtr_cmd(RCore *core, const char *input) {
|
|||||||
eprintf ("RAP Thread is already running\n");
|
eprintf ("RAP Thread is already running\n");
|
||||||
eprintf ("This is experimental and probably buggy. Use at your own risk\n");
|
eprintf ("This is experimental and probably buggy. Use at your own risk\n");
|
||||||
} else {
|
} else {
|
||||||
RapThread rt = { core, input + 1 };
|
RapThread *RT = R_NEW0 (RapThread);
|
||||||
rapthread = r_th_new (r_core_rtr_rap_thread, &rt, false);
|
if (RT) {
|
||||||
|
RT->core = core;
|
||||||
|
RT->input = strdup (input + 1);
|
||||||
|
//RapThread rt = { core, strdup (input + 1) };
|
||||||
|
rapthread = r_th_new (r_core_rtr_rap_thread, RT, false);
|
||||||
r_th_start (rapthread, true);
|
r_th_start (rapthread, true);
|
||||||
eprintf ("Background rap server started.\n");
|
eprintf ("Background rap server started.\n");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,6 +213,7 @@ R_API bool r_core_init(RCore *core);
|
|||||||
R_API RCore *r_core_new(void);
|
R_API RCore *r_core_new(void);
|
||||||
R_API RCore *r_core_free(RCore *core);
|
R_API RCore *r_core_free(RCore *core);
|
||||||
R_API RCore *r_core_fini(RCore *c);
|
R_API RCore *r_core_fini(RCore *c);
|
||||||
|
R_API void r_core_wait(RCore *core);
|
||||||
R_API RCore *r_core_ncast(ut64 p);
|
R_API RCore *r_core_ncast(ut64 p);
|
||||||
R_API RCore *r_core_cast(void *p);
|
R_API RCore *r_core_cast(void *p);
|
||||||
R_API int r_core_config_init(RCore *core);
|
R_API int r_core_config_init(RCore *core);
|
||||||
@ -283,7 +284,7 @@ R_API void r_core_visual_mark_dump(RCore *core);
|
|||||||
R_API void r_core_visual_mark_reset(RCore *core);
|
R_API void r_core_visual_mark_reset(RCore *core);
|
||||||
|
|
||||||
R_API int r_core_search_cb(RCore *core, ut64 from, ut64 to, RCoreSearchCallback cb);
|
R_API int r_core_search_cb(RCore *core, ut64 from, ut64 to, RCoreSearchCallback cb);
|
||||||
R_API int r_core_serve(RCore *core, RIODesc *fd);
|
R_API bool r_core_serve(RCore *core, RIODesc *fd);
|
||||||
R_API int r_core_file_reopen(RCore *core, const char *args, int perm, int binload);
|
R_API int r_core_file_reopen(RCore *core, const char *args, int perm, int binload);
|
||||||
R_API void r_core_file_reopen_debug(RCore *core, const char *args);
|
R_API void r_core_file_reopen_debug(RCore *core, const char *args);
|
||||||
R_API RCoreFile * r_core_file_find_by_fd(RCore* core, ut64 fd);
|
R_API RCoreFile * r_core_file_find_by_fd(RCore* core, ut64 fd);
|
||||||
|
@ -177,6 +177,7 @@ static RIODesc *rap__open(RIO *io, const char *pathname, int rw, int mode) {
|
|||||||
if (is_ssl) {
|
if (is_ssl) {
|
||||||
if (file && *file) {
|
if (file && *file) {
|
||||||
if (!r_socket_listen (rior->fd, port, file)) {
|
if (!r_socket_listen (rior->fd, port, file)) {
|
||||||
|
r_socket_free (rior->fd);
|
||||||
free (rior);
|
free (rior);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -67,9 +67,12 @@ R_API void r_th_break(RThread *th) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
R_API int r_th_kill(RThread *th, int force) {
|
R_API int r_th_kill(RThread *th, int force) {
|
||||||
|
if (!th) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
th->breaked = true;
|
th->breaked = true;
|
||||||
r_th_break(th);
|
r_th_break (th);
|
||||||
r_th_wait(th);
|
r_th_wait (th);
|
||||||
#if HAVE_PTHREAD
|
#if HAVE_PTHREAD
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
pthread_kill (th->tid, 9);
|
pthread_kill (th->tid, 9);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user