Fix #7213 - Retrieve UID on XNU and Linux for RDebugPid

This commit is contained in:
pancake 2017-04-09 23:41:32 +02:00
parent 35c87e9192
commit 94d85cad32
4 changed files with 70 additions and 31 deletions

View File

@ -457,18 +457,24 @@ static RList *r_debug_native_tids (RDebug *dbg, int pid) {
static RList *r_debug_native_pids (RDebug *dbg, int pid) {
RList *list = r_list_new ();
if (!list) return NULL;
if (!list) {
return NULL;
}
#if __WINDOWS__ && !__CYGWIN__
return w32_pids (pid, list);
#elif __APPLE__
if (pid) {
RDebugPid *p = xnu_get_pid (pid);
if (p) r_list_append (list, p);
if (p) {
r_list_append (list, p);
}
} else {
int i;
for (i = 1; i < MAXPID; i++) {
RDebugPid *p = xnu_get_pid (i);
if (p) r_list_append (list, p);
if (p) {
r_list_append (list, p);
}
}
}
#elif __linux__
@ -490,7 +496,10 @@ static RList *r_debug_native_pids (RDebug *dbg, int pid) {
r_list_free (list);
return NULL;
}
int uid, gid;
while ((de = readdir (dh))) {
uid = 0;
gid = 0;
/* for each existing pid file... */
i = atoi (de->d_name);
if (i <= 0) {
@ -504,17 +513,27 @@ static RList *r_debug_native_pids (RDebug *dbg, int pid) {
}
buf[sizeof (buf) - 1] = 0;
ptr = strstr (buf, "Uid:");
if (ptr) {
uid = atoi (ptr + 4);
}
ptr = strstr (buf, "Gid:");
if (ptr) {
gid = atoi (ptr + 4);
}
/* look for the parent process id */
ptr = strstr (buf, "PPid:");
if (ptr) {
int ppid = atoi (ptr + 6);
int ppid = atoi (ptr + 5);
/* if this is the requested process... */
if (i == pid) {
//eprintf ("PPid: %d\n", ppid);
/* append it to the list with parent */
// eprintf ("PPid: %d\n", ppid);
// append it to the list with parent
r_list_append (list, r_debug_pid_new (
"(ppid)", ppid, 's', 0));
"(ppid)", ppid, uid, 's', 0));
}
/* ignore it if it is not one of our children */
@ -523,11 +542,10 @@ static RList *r_debug_native_pids (RDebug *dbg, int pid) {
}
/* it's a child of the requested pid, read it's command line and add it */
if (procfs_pid_slurp (ppid, "cmdline", buf, sizeof(buf)) == -1) {
if (procfs_pid_slurp (ppid, "cmdline", buf, sizeof (buf)) == -1) {
continue;
}
r_list_append (list, r_debug_pid_new (buf, i, 's', 0));
r_list_append (list, r_debug_pid_new (buf, i, uid, 's', 0));
}
}
closedir (dh);

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2015-2016 - pancake, alvaro_fe */
/* radare - LGPL - Copyright 2015-2017 - pancake, alvaro_fe */
#include <r_userconf.h>
#if DEBUGGER
@ -437,7 +437,7 @@ RList *xnu_thread_list (RDebug *dbg, int pid, RList *list) {
thread->state_size = sizeof (thread->gpr);
memcpy (&state, &thread->gpr, sizeof (R_REG_T));
r_list_append (list, r_debug_pid_new (thread->name,
thread->port, 's', CPU_PC));
thread->port, getuid (), 's', CPU_PC));
}
return list;
}
@ -786,6 +786,26 @@ static void xnu_collect_thread_state (thread_t port, void *tirp) {
#define CORE_ALL_SECT 0
#include <sys/sysctl.h>
static uid_t uidFromPid(pid_t pid) {
uid_t uid = -1;
struct kinfo_proc process;
size_t procBufferSize = sizeof (process);
uid = 0;
// Compose search path for sysctl. Here you can specify PID directly.
const u_int pathLenth = 4;
int path[pathLenth] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
int sysctlResult = sysctl (path, pathLenth, &process, &procBufferSize, NULL, 0);
// If sysctl did not fail and process with PID available - take UID.
if ((sysctlResult == 0) && (procBufferSize != 0)) {
uid = process.kp_eproc.e_ucred.cr_uid;
}
return uid;
}
bool xnu_generate_corefile (RDebug *dbg, RBuffer *dest) {
int error = 0, i;
int tstate_size;
@ -866,7 +886,7 @@ cleanup:
}
RDebugPid *xnu_get_pid (int pid) {
int psnamelen, foo, nargs, mib[3];
int psnamelen, foo, nargs, mib[3], uid;
size_t size, argmax = 4096;
char *curr_arg, *start_args, *iter_args, *end_args;
char *procargs = NULL;
@ -881,6 +901,8 @@ RDebugPid *xnu_get_pid (int pid) {
return NULL;
}
#endif
uid = uidFromPid (pid);
/* Allocate space for the arguments. */
procargs = (char *)malloc (argmax);
if (!procargs) {
@ -911,7 +933,7 @@ RDebugPid *xnu_get_pid (int pid) {
// copy the number of argument to nargs
memcpy (&nargs, procargs, sizeof (nargs));
iter_args = procargs + sizeof (nargs);
iter_args = procargs + sizeof (nargs);
end_args = &procargs[size - 30]; // end of the argument space
if (iter_args >= end_args) {
eprintf ("getcmdargs(): argument length mismatch");
@ -930,12 +952,6 @@ RDebugPid *xnu_get_pid (int pid) {
free (procargs);
return NULL;
}
/* Iterate through the '\0'-terminated strings and add each string
* to the Python List arglist as a Python string.
* Stop when nargs strings have been extracted. That should be all
* the arguments. The rest of the strings will be environment
* strings for the command.
*/
curr_arg = iter_args;
start_args = iter_args; //reset start position to beginning of cmdline
foo = 1;
@ -949,7 +965,7 @@ RDebugPid *xnu_get_pid (int pid) {
foo = 0;
} else {
psname[psnamelen] = ' ';
memcpy (psname+psnamelen+1, curr_arg, alen+1);
memcpy (psname + psnamelen + 1, curr_arg, alen + 1);
}
psnamelen += alen;
//printf("arg[%i]: %s\n", iter_args, curr_arg);
@ -971,7 +987,7 @@ RDebugPid *xnu_get_pid (int pid) {
return NULL;
}
#endif
return r_debug_pid_new (psname, pid, 's', 0); // XXX 's' ??, 0?? must set correct values
return r_debug_pid_new (psname, pid, uid, 's', 0); // XXX 's' ??, 0?? must set correct values
}
kern_return_t mach_vm_region_recurse (

View File

@ -1,12 +1,15 @@
/* radare - LGPL - Copyright 2009-2011 pancake<nopcode.org> */
/* radare - LGPL - Copyright 2009-2017 - pancake */
#include <r_debug.h>
R_API RDebugPid *r_debug_pid_new(const char *path, int pid, char status, ut64 pc) {
R_API RDebugPid *r_debug_pid_new(const char *path, int pid, int uid, char status, ut64 pc) {
RDebugPid *p = R_NEW0 (RDebugPid);
if (!p) return NULL;
if (!p) {
return NULL;
}
p->path = strdup (path);
p->pid = pid;
p->uid = uid;
p->status = status;
p->runnable = true;
p->pc = pc;
@ -43,20 +46,22 @@ R_API int r_debug_pid_list(RDebug *dbg, int pid, char fmt) {
switch (fmt) {
case 'j':
dbg->cb_printf ("{\"pid\":%d,"
"\"uid\":%d,"
"\"status\":\"%c\","
"\"path\":\"%s\"}%s",
p->pid, p->status, p->path,
p->pid, p->uid, p->status, p->path,
iter->n?",":"");
break;
default:
dbg->cb_printf (" %c %d %c %s\n",
dbg->pid==p->pid?'*':'-',
p->pid, p->status, p->path);
dbg->cb_printf (" %c %d uid:%d %c %s\n",
dbg->pid == p->pid? '*': '-',
p->pid, p->uid, p->status, p->path);
break;
}
}
if (fmt == 'j')
if (fmt == 'j') {
dbg->cb_printf ("]\n");
}
r_list_free (list);
}
return false;

View File

@ -393,7 +393,7 @@ R_API int r_debug_select(RDebug *dbg, int pid, int tid);
//R_API int r_debug_pid_del(RDebug *dbg);
//R_API int r_debug_pid_del_thread(RDebug *dbg);
R_API int r_debug_pid_list(RDebug *dbg, int pid, char fmt);
R_API RDebugPid *r_debug_pid_new(const char *path, int pid, char status, ut64 pc);
R_API RDebugPid *r_debug_pid_new(const char *path, int pid, int uid, char status, ut64 pc);
R_API RDebugPid *r_debug_pid_free(RDebugPid *pid);
R_API RList *r_debug_pids(RDebug *dbg, int pid);