Fix #491 - Project untrusted input

- Fix various project related issues
- Do not save in directories. Projects are file + file.d/
- Do not show division by zero issue (e cfg.foo=/bin/ls)
This commit is contained in:
pancake 2013-12-28 02:34:15 +01:00
parent 5223c0f578
commit da33633680
11 changed files with 148 additions and 105 deletions

View File

@ -31,6 +31,7 @@ R_API void r_config_node_free (void *n) {
R_API void r_config_list(RConfig *cfg, const char *str, int rad) {
RConfigNode *node;
RListIter *iter;
const char *sfx = "";
const char *pfx = "";
int len = 0;
@ -40,12 +41,13 @@ R_API void r_config_list(RConfig *cfg, const char *str, int rad) {
}
switch (rad) {
case 1:
pfx = "e ";
pfx = "\"e ";
sfx = "\"";
case 0:
r_list_foreach (cfg->nodes, iter, node) {
if (!str || (str && (!strncmp (str, node->name, len))))
cfg->printf ("%s%s = %s\n", pfx,
node->name, node->value);
cfg->printf ("%s%s = %s%s\n", pfx,
node->name, node->value, sfx);
}
break;
case 2:

View File

@ -163,20 +163,20 @@ static void cmd_debug_pid(RCore *core, const char *input) {
(int) r_num_math (core->num, input+2));
break;
case '?':
r_cons_printf ("Usage: dp[=][pid]\n"
" dp list current pid and childrens\n"
" dp 748 list children of pid\n"
" dp* list all attachable pids\n"
" dpe show path to executable\n"
" dpa 377 attach and select this pid\n"
" dp=748 select this pid\n"
" dpf Attach to pid like file fd // HACK\n"
" dpn Create new process (fork)\n"
" dpnt Create new thread (clone)\n"
" dpt List threads of current pid\n"
" dpt 74 List threads of given process\n"
" dpt=64 Attach to thread\n"
" dpk P S send signal S to P process id\n");
r_cons_printf ("|Usage: dp[=][pid]\n"
"| dp list current pid and childrens\n"
"| dp 748 list children of pid\n"
"| dp* list all attachable pids\n"
"| dpe show path to executable\n"
"| dpa 377 attach and select this pid\n"
"| dp=748 select this pid\n"
"| dpf Attach to pid like file fd // HACK\n"
"| dpn Create new process (fork)\n"
"| dpnt Create new thread (clone)\n"
"| dpt List threads of current pid\n"
"| dpt 74 List threads of given process\n"
"| dpt=64 Attach to thread\n"
"| dpk P S send signal S to P process id\n");
break;
default:
eprintf ("selected: %d %d\n", core->dbg->pid, core->dbg->tid);
@ -233,19 +233,19 @@ static int cmd_debug_map(RCore *core, const char *input) {
switch (input[0]) {
case '?':
r_cons_printf (
"Usage: dm [size]\n"
" dm List memory maps of target process\n"
" dmj List memmaps in JSON format\n"
" dm* Same as above but in radare commands\n"
" dm addr size Allocate size bytes at addr (anywhere if addr is -1) in child process\n"
" dm-0x8048 Deallocate memory map of address 0x8048\n"
" dmp A S rwx Change page at A with size S protection permissions\n"
" dmd [file] Dump current debug map region to a file (from-to.dmp) (see Sd)\n"
" dml file Load contents of file into the current map region (see Sl)\n"
" dmi [addr|libname] [symname] List symbols of target lib\n"
" dmi* [addr|libname] [symname] Same as above but in radare commands\n"
//" dm rw- esp 9K set 9KB of the stack as read+write (no exec)\n"
"TODO: map files in process memory. (dmf file @ [addr])\n");
"|Usage: dm [size]\n"
"| dm List memory maps of target process\n"
"| dmj List memmaps in JSON format\n"
"| dm* Same as above but in radare commands\n"
"| dm addr size Allocate size bytes at addr (anywhere if addr is -1) in child process\n"
"| dm-0x8048 Deallocate memory map of address 0x8048\n"
"| dmp A S rwx Change page at A with size S protection permissions\n"
"| dmd [file] Dump current debug map region to a file (from-to.dmp) (see Sd)\n"
"| dml file Load contents of file into the current map region (see Sl)\n"
"| dmi [addr|libname] [symname] List symbols of target lib\n"
"| dmi* [addr|libname] [symname] Same as above but in radare commands\n"
//"| dm rw- esp 9K set 9KB of the stack as read+write (no exec)\n"
"|TODO: map files in process memory. (dmf file @ [addr])\n");
break;
case 'p':
if (input[1] == ' ') {
@ -805,10 +805,10 @@ static int cmd_debug(void *data, const char *input) {
case 't':
switch (input[1]) {
case '?':
r_cons_printf ("Usage: dt[*] [tag]\n");
r_cons_printf (" dtc - trace call/ret\n");
r_cons_printf (" dtg - graph call/ret trace\n");
r_cons_printf (" dtr - reset traces (instruction//cals)\n");
r_cons_printf ("|Usage: dt[*] [tag]\n"
"| dtc - trace call/ret\n"
"| dtg - graph call/ret trace\n"
"| dtr - reset traces (instruction//cals)\n");
break;
case 'c':
if (r_debug_is_dead (core->dbg))
@ -865,12 +865,12 @@ static int cmd_debug(void *data, const char *input) {
break;
case '?':
default:
r_cons_printf ("Usage: dd[*sdrw-?]\n"
" dd list filedescriptors\n"
" dd* list filedescriptors (in radare commands)\n"
" dd-1 close stdout fd\n"
" dd file open and map that file into the UI\n"
" dd? show this help\n");
r_cons_printf ("|Usage: dd[*sdrw-?]\n"
"| dd list filedescriptors\n"
"| dd* list filedescriptors (in radare commands)\n"
"| dd-1 close stdout fd\n"
"| dd file open and map that file into the UI\n"
"| dd? show this help\n");
break;
}
break;
@ -879,17 +879,17 @@ static int cmd_debug(void *data, const char *input) {
if (times<1) times = 1;
switch (input[1]) {
case '?':
r_cons_printf ("Usage: ds[ol] [count]\n"
" ds step one instruction\n"
" ds 4 step 4 instructions\n"
" dsf step until end of frame\n"
" dsi [cond] continue until condition matches\n"
" dsl step one source line\n"
" dsl 40 step 40 source lines\n"
" dso 3 step over 3 instructions\n"
" dsp step into program (skip libs)\n"
" dss 3 skip 3 step instructions\n"
" dsu addr step until address\n"
r_cons_printf ("|Usage: ds[ol] [count]\n"
"| ds step one instruction\n"
"| ds 4 step 4 instructions\n"
"| dsf step until end of frame\n"
"| dsi [cond] continue until condition matches\n"
"| dsl step one source line\n"
"| dsl 40 step 40 source lines\n"
"| dso 3 step over 3 instructions\n"
"| dsp step into program (skip libs)\n"
"| dss 3 skip 3 step instructions\n"
"| dsu addr step until address\n"
);
break;
case 'i':
@ -998,25 +998,25 @@ static int cmd_debug(void *data, const char *input) {
r_cons_break (static_debug_stop, core->dbg);
switch (input[1]) {
case '?':
eprintf("Usage: dc[?] -- continue execution\n"
" dc? show this help\n"
" dc continue execution of all children\n"
" dcf continue until fork (TODO)\n"
" dca [sym] [sym]. continue at every hit on any given symbol\n"
" dct [len] traptrace from curseek to len, no argument to list\n"
" dcu [addr] continue until address\n"
" dcu [addr] [end] continue until given address range\n"
" dco [num] step over N instructions\n"
" dcp continue until program code (mapped io section)\n"
" dcs [num] continue until syscall\n"
" dcc continue until call (use step into)\n"
" dcr continue until ret (uses step over)\n"
" dck [sig] [pid] continue sending kill 9 to process\n"
" dc [pid] continue execution of pid\n"
" dc[-pid] stop execution of pid\n"
"TODO: dcu/dcr needs dbg.untilover=true??\n"
"TODO: same for only user/libs side, to avoid steping into libs\n"
"TODO: support for threads?\n");
eprintf("|Usage: dc[?] -- continue execution\n"
"| dc? show this help\n"
"| dc continue execution of all children\n"
"| dcf continue until fork (TODO)\n"
"| dca [sym] [sym]. continue at every hit on any given symbol\n"
"| dct [len] traptrace from curseek to len, no argument to list\n"
"| dcu [addr] continue until address\n"
"| dcu [addr] [end] continue until given address range\n"
"| dco [num] step over N instructions\n"
"| dcp continue until program code (mapped io section)\n"
"| dcs [num] continue until syscall\n"
"| dcc continue until call (use step into)\n"
"| dcr continue until ret (uses step over)\n"
"| dck [sig] [pid] continue sending kill 9 to process\n"
"| dc [pid] continue execution of pid\n"
"| dc[-pid] stop execution of pid\n"
"|TODO: dcu/dcr needs dbg.untilover=true??\n"
"|TODO: same for only user/libs side, to avoid steping into libs\n"
"|TODO: support for threads?\n");
break;
case 'a':
eprintf ("TODO: dca\n");
@ -1192,11 +1192,11 @@ static int cmd_debug(void *data, const char *input) {
}
break;
default:
r_cons_printf ("Usage: di[asr] [arg| ...]\n"
" di 9090 ; inject two x86 nops\n"
" \"dia mov eax,6;mov ebx,0;int 0x80\" ; inject and restore state\n"
" dir 9090 ; inject and restore state\n"
" dis write 1, 0x8048, 12 ; syscall injection (see gs)\n");
r_cons_printf ("|Usage: di[asr] [arg| ...]\n"
"| di 9090 ; inject two x86 nops\n"
"| \"dia mov eax,6;mov ebx,0;int 0x80\" ; inject and restore state\n"
"| dir 9090 ; inject and restore state\n"
"| dis write 1, 0x8048, 12 ; syscall injection (see gs)\n");
break;
}
break;
@ -1218,22 +1218,22 @@ static int cmd_debug(void *data, const char *input) {
r_core_debug_kill (core, input+1);
break;
default:
r_cons_printf ("Usage: d[sbhcrbo] [arg]\n"
" dh [handler] list or set debugger handler\n"
" dH [handler] transplant process to a new handler\n"
" dd file descriptors (!fd in r1)\n"
" ds[ol] N step, over, source line\n"
" do open process (reload, alias for 'oo')\n"
" dk [sig][=act] list, send, get, set, signal handlers of child\n"
" di[s] [arg..] inject code on running process and execute it (See gs)\n"
" dp[=*?t][pid] list, attach to process or thread id\n"
" dc[?] continue execution. dc? for more\n"
" dr[?] cpu registers, dr? for extended help\n"
" db[?] breakpoints\n"
" dbt display backtrace\n"
" dt[?r] [tag] display instruction traces (dtr=reset)\n"
" dm[?*] show memory maps\n"
" dw [pid] block prompt until pid dies\n");
r_cons_printf ("|Usage: d[sbhcrbo] [arg]\n"
"| dh [handler] list or set debugger handler\n"
"| dH [handler] transplant process to a new handler\n"
"| dd file descriptors (!fd in r1)\n"
"| ds[ol] N step, over, source line\n"
"| do open process (reload, alias for 'oo')\n"
"| dk [sig][=act] list, send, get, set, signal handlers of child\n"
"| di[s] [arg..] inject code on running process and execute it (See gs)\n"
"| dp[=*?t][pid] list, attach to process or thread id\n"
"| dc[?] continue execution. dc? for more\n"
"| dr[?] cpu registers, dr? for extended help\n"
"| db[?] breakpoints\n"
"| dbt display backtrace\n"
"| dt[?r] [tag] display instruction traces (dtr=reset)\n"
"| dm[?*] show memory maps\n"
"| dw [pid] block prompt until pid dies\n");
break;
}
if (follow>0) {

View File

@ -158,7 +158,8 @@ static int cmd_meta(void *data, const char *input) {
free (comment);
}
break;
default: {
case ' ':
case '\0':
if (type!='z' && !input[1]) {
r_meta_list (core->anal->meta, input[0], 0);
break;
@ -195,7 +196,9 @@ static int cmd_meta(void *data, const char *input) {
if (!r_meta_add (core->anal->meta, type, addr, addr_end, name))
free (t);
//r_meta_cleanup (core->anal->meta, 0LL, UT64_MAX);
}
break;
default:
eprintf ("Missing space after CC\n");
break;
}
break;

View File

@ -1,19 +1,31 @@
/* radare - LGPL - Copyright 2009-2012 // pancake<nopcode.org> */
/* radare - LGPL - Copyright 2009-2013 - pancake */
static int cmd_project(void *data, const char *input) {
RCore *core = (RCore *)data;
const char *arg = input+1;
const char *file, *arg = input+1;
char *str = strdup (r_config_get (core->config, "file.project"));
if (*arg==' ') arg++;
file = input[1]?arg:str;
switch (input[0]) {
case 'o': r_core_project_open (core, input[1]?arg:str); break;
case 's': r_core_project_save (core, input[1]?arg:str); break;
case 'i': free (r_core_project_info (core, input[1]?arg:str)); break;
case 'o':
// if (r_file_is_regular (file))
r_core_project_open (core, file);
break;
case 's':
r_core_project_save (core, file);
r_config_set (core->config, "file.project", file);
break;
case 'i':
// if (r_file_is_regular (file))
free (r_core_project_info (core, file));
break;
default:
r_cons_printf (
"|Usage: P[?osi] [file]\n"
"| Po [file] open project\n"
"| Ps [file] save project\n"
"| Pi [file] info\n"
"| Pi [file] show project information\n"
"|NOTE: See 'e file.project'\n"
"|NOTE: project files are stored in ~/.config/radare2/rdb\n");
break;
}

View File

@ -655,7 +655,7 @@ R_API int r_core_config_init(RCore *core) {
SETPREF("dir.plugins", R2_LIBDIR"/radare2/"R2_VERSION"/", "Path to plugin files to be loaded at startup");
SETPREF("dir.source", "", "Path to find source files");
SETPREF("dir.types", "/usr/include", "Default path to look for cparse type files");
SETPREF("dir.projects", R2_HOMEDIR"/rdb", "Default path for projects");
SETPREF("dir.projects", "~/"R2_HOMEDIR"/rdb", "Default path for projects");
/* debug */
SETCB("dbg.backend", "native", &cb_dbgbackend, "Select the debugger backend");

View File

@ -40,6 +40,12 @@ R_API char *r_core_project_info(RCore *core, const char *prjfile) {
fgets (buf, sizeof (buf), fd);
if (feof (fd))
break;
if (!memcmp (buf, "\"e file.path = ", 15)) {
buf[strlen(buf)-2]=0;
file = r_str_new (buf+15);
break;
}
// TODO: deprecate before 1.0
if (!memcmp (buf, "e file.path = ", 14)) {
buf[strlen(buf)-1]=0;
file = r_str_new (buf+14);
@ -47,7 +53,7 @@ R_API char *r_core_project_info(RCore *core, const char *prjfile) {
}
}
if (fd) fclose (fd);
r_cons_printf ("Project : %s\n", prj);
r_cons_printf ("%s\n", prj);
if (file) r_cons_printf ("FilePath: %s\n", file);
free (prj);
return file;
@ -61,6 +67,10 @@ R_API int r_core_project_save(RCore *core, const char *file) {
return R_FALSE;
prj = r_core_project_file (core, file);
if (r_file_is_directory (prj)) {
eprintf ("Error: Target is a directory\n");
return R_FALSE;
}
r_core_project_init (core);
r_anal_project_save (core->anal, prj);
fd = r_sandbox_open (prj, O_BINARY|O_RDWR|O_CREAT, 0644);
@ -87,7 +97,7 @@ R_API int r_core_project_save(RCore *core, const char *file) {
r_cons_flush ();
{
char buf[1024];
snprintf (buf, sizeof(buf), "%s.d/xrefs", prj);
snprintf (buf, sizeof (buf), "%s.d/xrefs", prj);
sdb_file (core->anal->sdb_xrefs, buf);
sdb_sync (core->anal->sdb_xrefs);
}

View File

@ -72,8 +72,12 @@ R_API void r_flag_list(RFlag *f, int rad) {
continue;
if (rad) {
if (fs == -1 || flag->space != fs) {
const char *flagspace;
fs = flag->space;
r_cons_printf ("fs %s\n", r_flag_space_get_i (f, fs));
flagspace = r_flag_space_get_i (f, fs);
if (!flagspace || !*flagspace)
flagspace = "*";
r_cons_printf ("fs %s\n", flagspace);
}
r_cons_printf ("f %s %"PFMT64d" 0x%08"PFMT64x" %s\n",
flag->name, flag->size, flag->offset,

View File

@ -232,6 +232,7 @@ R_API RGraphNode* r_graph_pop(RGraph *t);
R_API int r_file_size(const char *str);
R_API char *r_file_root(const char *root, const char *path);
R_API boolt r_file_is_directory(const char *str);
R_API boolt r_file_is_regular(const char *str);
R_API RMmap *r_file_mmap (const char *file, boolt rw, ut64 base);
R_API int r_file_mmap_read (const char *file, ut64 addr, ut8 *buf, int len);
R_API int r_file_mmap_write(const char *file, ut64 addr, const ut8 *buf, int len);

View File

@ -62,7 +62,7 @@ static RNumCalcValue term(RNum *num, RNumCalc *nc, int get) {
if (nc->curr_tok == RNCDIV) {
RNumCalcValue d = prim (num, nc, 1);
if (!d.d) {
error (num, nc, "divide by 0");
//error (num, nc, "divide by 0");
return d;
}
left = Ndiv (left, d);

View File

@ -19,8 +19,19 @@ R_API const char *r_file_basename (const char *path) {
return path;
}
R_API boolt r_file_is_regular(const char *str) {
struct stat buf = {0};
if (!str||!*str)
return R_FALSE;
if (stat (str, &buf)==-1)
return R_FALSE;
return ((S_IFREG & buf.st_mode))? R_TRUE: R_FALSE;
}
R_API boolt r_file_is_directory(const char *str) {
struct stat buf = {0};
if (!str||!*str)
return R_FALSE;
if (stat (str, &buf)==-1)
return R_FALSE;
return ((S_IFDIR &buf.st_mode))? R_TRUE: R_FALSE;

View File

@ -80,7 +80,7 @@ R_API FILE *r_sandbox_fopen (const char *path, const char *mode) {
if (!r_sandbox_check_path (path))
return NULL;
}
if (path)
if (path && r_file_is_regular (path))
return fopen (path, mode);
return NULL;
}