* [Qemu-devel] [PATCH] -chroot and -su options. @ 2008-03-04 0:28 Rob Landley 2008-03-04 11:22 ` Edgar E. Iglesias 2008-03-14 16:06 ` Anderson Lizardo 0 siblings, 2 replies; 8+ messages in thread From: Rob Landley @ 2008-03-04 0:28 UTC (permalink / raw) To: qemu-devel Quick and dirty patch to teach qemu application emulation how to chroot (and drop privs), so you don't have to pollute a target filesystem with host code, and/or figure out how to build qemu static in order to run a dynamic binary. diff --git a/linux-user/main.c b/linux-user/main.c index 124b98c..b010fd2 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -1905,6 +1905,10 @@ void usage(void) "-cpu model select CPU (-cpu ? for list)\n" "-drop-ld-preload drop LD_PRELOAD for target process\n" "\n" + "Root options:\n" + "-chroot dir chroot to dir\n" + "-su uid:gid set numeric user and group IDs\n" + "\n" "Debug options:\n" "-d options activate log (logfile=%s)\n" "-p pagesize set the host page size to 'pagesize'\n" @@ -2011,6 +2015,28 @@ int main(int argc, char **argv) drop_ld_preload = 1; } else if (!strcmp(r, "strace")) { do_strace = 1; + } else if (!strcmp(r, "chroot")) { + if (chdir(argv[optind++]) || chroot(".")) { + fprintf(stderr, "Can't chroot to '%s' (are you root?)\n", + argv[--optind]); + _exit(1); + } + } else if (!strcmp(r, "su")) { + int temp; + char *gid = strchr(argv[optind], ':'); + if (gid) { + temp = atoi(++gid); + if (setresgid(temp, temp, temp)) { + fprintf(stderr, "Can't set gid to %d (are you root?)\n", + temp); + _exit(1); + } + } + temp = atoi(argv[optind++]); + if (setresuid(temp, temp, temp)) { + fprintf(stderr, "Can't set uid to %d (are you root?)\n", temp); + _exit(1); + } } else { usage(); -- "One of my most productive days was throwing away 1000 lines of code." - Ken Thompson. ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH] -chroot and -su options. 2008-03-04 0:28 [Qemu-devel] [PATCH] -chroot and -su options Rob Landley @ 2008-03-04 11:22 ` Edgar E. Iglesias 2008-03-05 6:51 ` Rob Landley 2008-03-14 16:06 ` Anderson Lizardo 1 sibling, 1 reply; 8+ messages in thread From: Edgar E. Iglesias @ 2008-03-04 11:22 UTC (permalink / raw) To: Rob Landley; +Cc: qemu-devel On Mon, Mar 03, 2008 at 06:28:22PM -0600, Rob Landley wrote: > Quick and dirty patch to teach qemu application emulation how to chroot (and > drop privs), so you don't have to pollute a target filesystem with host code, > and/or figure out how to build qemu static in order to run a dynamic binary. Hi Rob, Right, doing the chroot from within qemu avoids the issue with polluting the target/. Thanks for the example. The chroot approach still suffers from the need of initially having higher privileges. Personally, I still prefer the sysroot option and avoid that need but either way helps me. Best regards -- Edgar E. Iglesias Axis Communications AB ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH] -chroot and -su options. 2008-03-04 11:22 ` Edgar E. Iglesias @ 2008-03-05 6:51 ` Rob Landley 2008-03-05 7:54 ` Edgar E. Iglesias 0 siblings, 1 reply; 8+ messages in thread From: Rob Landley @ 2008-03-05 6:51 UTC (permalink / raw) To: Edgar E. Iglesias; +Cc: qemu-devel On Tuesday 04 March 2008 05:22:12 you wrote: > On Mon, Mar 03, 2008 at 06:28:22PM -0600, Rob Landley wrote: > > Quick and dirty patch to teach qemu application emulation how to chroot > > (and drop privs), so you don't have to pollute a target filesystem with > > host code, and/or figure out how to build qemu static in order to run a > > dynamic binary. > > Hi Rob, > > Right, doing the chroot from within qemu avoids the issue with polluting > the target/. Thanks for the example. > > The chroot approach still suffers from the need of initially having higher > privileges. Personally, I still prefer the sysroot option and avoid that > need but either way helps me. > > Best regards Which sysroot option? (I may have missed a patch, I'm a month behind on the list. This is just something I've meant to submit for... about a year, I think.) You can also teach a bunch of different qemu syscalls (open, unlink, mmap, exec, fcntl, and 3 dozen others...) to append a prefix to its path, and perhaps try to prevent them from playing games with symlinks or ".." to break out of that subdir. But that's a much, much, much more extensive/intrusive patch. Rob -- "One of my most productive days was throwing away 1000 lines of code." - Ken Thompson. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH] -chroot and -su options. 2008-03-05 6:51 ` Rob Landley @ 2008-03-05 7:54 ` Edgar E. Iglesias 2008-03-06 6:47 ` Rob Landley 0 siblings, 1 reply; 8+ messages in thread From: Edgar E. Iglesias @ 2008-03-05 7:54 UTC (permalink / raw) To: Rob Landley; +Cc: qemu-devel On Wed, Mar 05, 2008 at 12:51:36AM -0600, Rob Landley wrote: > On Tuesday 04 March 2008 05:22:12 you wrote: > > On Mon, Mar 03, 2008 at 06:28:22PM -0600, Rob Landley wrote: > > > Quick and dirty patch to teach qemu application emulation how to chroot > > > (and drop privs), so you don't have to pollute a target filesystem with > > > host code, and/or figure out how to build qemu static in order to run a > > > dynamic binary. > > > > Hi Rob, > > > > Right, doing the chroot from within qemu avoids the issue with polluting > > the target/. Thanks for the example. > > > > The chroot approach still suffers from the need of initially having higher > > privileges. Personally, I still prefer the sysroot option and avoid that > > need but either way helps me. > > > > Best regards > > Which sysroot option? (I may have missed a patch, I'm a month behind on the > list. This is just something I've meant to submit for... about a year, I > think.) > > You can also teach a bunch of different qemu syscalls (open, unlink, mmap, > exec, fcntl, and 3 dozen others...) to append a prefix to its path, and > perhaps try to prevent them from playing games with symlinks or ".." to break > out of that subdir. But that's a much, much, much more extensive/intrusive > patch. Hi, This is the updated example from my local git of how it could work, it only maps absolute paths. I don't think taking care of relative paths involves much more code but so far this behaviour has been enough for me. The sim simulators in GDB have a similar --sysroot option which I beleive behaves very similar (or equal). Please note that I'm not trying to jail in a program for security purposes, just for test and debug purposes. My original post can be found here: http://lists.gnu.org/archive/html/qemu-devel/2008-03/msg00027.html Best regards -- Edgar E. Iglesias Axis Communications AB diff --git a/linux-user/main.c b/linux-user/main.c index 0079c7a..8190dbf 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -1904,6 +1904,7 @@ void usage(void) "-h print this help\n" "-g port wait gdb connection to port\n" "-L path set the elf interpreter prefix (default=%s)\n" + "-sysroot Root for system calls with absolute file-names\n" "-s size set the stack size in bytes (default=%ld)\n" "-cpu model select CPU (-cpu ? for list)\n" "-drop-ld-preload drop LD_PRELOAD for target process\n" @@ -1943,6 +1944,7 @@ int main(int argc, char **argv) int gdbstub_port = 0; int drop_ld_preload = 0, environ_count = 0; char **target_environ, **wrk, **dst; + char *sysroot = NULL; if (argc <= 1) usage(); @@ -2014,6 +2016,8 @@ int main(int argc, char **argv) drop_ld_preload = 1; } else if (!strcmp(r, "strace")) { do_strace = 1; + } else if (!strcmp(r, "sysroot")) { + sysroot = argv[optind++]; } else { usage(); @@ -2030,7 +2034,10 @@ int main(int argc, char **argv) memset(info, 0, sizeof(struct image_info)); /* Scan interp_prefix dir for replacement files. */ - init_paths(interp_prefix); + if (sysroot) + init_paths(sysroot, 1); + else + init_paths(interp_prefix, 0); if (cpu_model == NULL) { #if defined(TARGET_I386) diff --git a/linux-user/path.c b/linux-user/path.c index 7da0a8b..5b6abc9 100644 --- a/linux-user/path.c +++ b/linux-user/path.c @@ -25,6 +25,8 @@ struct pathelem }; static struct pathelem *base; +static int use_sysroot; +static size_t sysroot_pathlen; /* First N chars of S1 match S2, and S2 is N chars long. */ static int strneq(const char *s1, unsigned int n, const char *s2) @@ -118,7 +120,7 @@ follow_path(const struct pathelem *cursor, const char *name) return NULL; } -void init_paths(const char *prefix) +void init_paths(const char *prefix, int sysroot) { char pref_buf[PATH_MAX]; @@ -135,15 +137,25 @@ void init_paths(const char *prefix) strcat(pref_buf, prefix); free(cwd); } else - strcpy(pref_buf,prefix + 1); - - base = new_entry("", NULL, pref_buf); - base = add_dir_maybe(base); - if (base->num_entries == 0) { - free (base); - base = NULL; + strcpy(pref_buf, prefix + 1); + + use_sysroot = sysroot; + if (sysroot) { + base = malloc(sizeof (*base)); + sysroot_pathlen = strlen(pref_buf); + base->pathname = malloc(sysroot_pathlen + PATH_MAX + 1); + base->pathname[0] = '/'; + memcpy(base->pathname + 1, pref_buf, sysroot_pathlen); + sysroot_pathlen++; } else { - set_parents(base, base); + base = new_entry("", NULL, pref_buf); + base = add_dir_maybe(base); + if (base->num_entries == 0) { + free (base); + base = NULL; + } else { + set_parents(base, base); + } } } @@ -155,5 +167,12 @@ const char *path(const char *name) if (!base || name[0] != '/') return name; - return follow_path(base, name) ?: name; + if (use_sysroot) { + size_t name_len; + /* Prepend base->pathname to name. */ + name_len = strlen(name); + memcpy (base->pathname + sysroot_pathlen, name, name_len + 1); + return base->pathname; + } else + return follow_path(base, name) ?: name; } diff --git a/linux-user/qemu.h b/linux-user/qemu.h index b33ad89..9e1b4f4 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -166,7 +166,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, void gemu_log(const char *fmt, ...) __attribute__((format(printf,1,2))); extern CPUState *global_env; void cpu_loop(CPUState *env); -void init_paths(const char *prefix); +void init_paths(const char *prefix, int sysroot); const char *path(const char *pathname); char *target_strerror(int err); ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH] -chroot and -su options. 2008-03-05 7:54 ` Edgar E. Iglesias @ 2008-03-06 6:47 ` Rob Landley 2008-03-14 14:08 ` Edgar E. Iglesias 0 siblings, 1 reply; 8+ messages in thread From: Rob Landley @ 2008-03-06 6:47 UTC (permalink / raw) To: Edgar E. Iglesias; +Cc: qemu-devel On Wednesday 05 March 2008 01:54:08 Edgar E. Iglesias wrote: > On Wed, Mar 05, 2008 at 12:51:36AM -0600, Rob Landley wrote: > > On Tuesday 04 March 2008 05:22:12 you wrote: > > > On Mon, Mar 03, 2008 at 06:28:22PM -0600, Rob Landley wrote: > > > > Quick and dirty patch to teach qemu application emulation how to > > > > chroot (and drop privs), so you don't have to pollute a target > > > > filesystem with host code, and/or figure out how to build qemu static > > > > in order to run a dynamic binary. > > > > > > Hi Rob, > > > > > > Right, doing the chroot from within qemu avoids the issue with > > > polluting the target/. Thanks for the example. > > > > > > The chroot approach still suffers from the need of initially having > > > higher privileges. Personally, I still prefer the sysroot option and > > > avoid that need but either way helps me. > > > > > > Best regards > > > > Which sysroot option? (I may have missed a patch, I'm a month behind on > > the list. This is just something I've meant to submit for... about a > > year, I think.) > > > > You can also teach a bunch of different qemu syscalls (open, unlink, > > mmap, exec, fcntl, and 3 dozen others...) to append a prefix to its path, > > and perhaps try to prevent them from playing games with symlinks or ".." > > to break out of that subdir. But that's a much, much, much more > > extensive/intrusive patch. > > Hi, > > This is the updated example from my local git of how it could work, it only > maps absolute paths. I don't think taking care of relative paths involves > much more code but so far this behaviour has been enough for me. The sim > simulators in GDB have a similar --sysroot option which I beleive behaves > very similar (or equal). > > Please note that I'm not trying to jail in a program for security purposes, > just for test and debug purposes. Yeah, linux-user/path.c does seem to be trying to filter the paths. (Does -L do more than just adjust the elf interpreter prefix? The syscalls are wrapped in calls to path() which _could_ do something interesting, but doesn't. (And freeing the string would probably require a static pointer so the next call frees the previous one.) Even then, attempting to deal with things like symlinks that point to absolute paths would be quite a headache, and considering the default busybox install does exactly that, it's not exactly an unheard of corner case... Rob -- "One of my most productive days was throwing away 1000 lines of code." - Ken Thompson. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH] -chroot and -su options. 2008-03-06 6:47 ` Rob Landley @ 2008-03-14 14:08 ` Edgar E. Iglesias 2008-03-14 15:26 ` Rob Landley 0 siblings, 1 reply; 8+ messages in thread From: Edgar E. Iglesias @ 2008-03-14 14:08 UTC (permalink / raw) To: Rob Landley; +Cc: qemu-devel, Edgar E. Iglesias On Thu, Mar 06, 2008 at 12:47:12AM -0600, Rob Landley wrote: > On Wednesday 05 March 2008 01:54:08 Edgar E. Iglesias wrote: > > On Wed, Mar 05, 2008 at 12:51:36AM -0600, Rob Landley wrote: > > > On Tuesday 04 March 2008 05:22:12 you wrote: > > > > On Mon, Mar 03, 2008 at 06:28:22PM -0600, Rob Landley wrote: > > > > > Quick and dirty patch to teach qemu application emulation how to > > > > > chroot (and drop privs), so you don't have to pollute a target > > > > > filesystem with host code, and/or figure out how to build qemu static > > > > > in order to run a dynamic binary. > > > > > > > > Hi Rob, > > > > > > > > Right, doing the chroot from within qemu avoids the issue with > > > > polluting the target/. Thanks for the example. > > > > > > > > The chroot approach still suffers from the need of initially having > > > > higher privileges. Personally, I still prefer the sysroot option and > > > > avoid that need but either way helps me. > > > > > > > > Best regards > > > > > > Which sysroot option? (I may have missed a patch, I'm a month behind on > > > the list. This is just something I've meant to submit for... about a > > > year, I think.) > > > > > > You can also teach a bunch of different qemu syscalls (open, unlink, > > > mmap, exec, fcntl, and 3 dozen others...) to append a prefix to its path, > > > and perhaps try to prevent them from playing games with symlinks or ".." > > > to break out of that subdir. But that's a much, much, much more > > > extensive/intrusive patch. > > > > Hi, > > > > This is the updated example from my local git of how it could work, it only > > maps absolute paths. I don't think taking care of relative paths involves > > much more code but so far this behaviour has been enough for me. The sim > > simulators in GDB have a similar --sysroot option which I beleive behaves > > very similar (or equal). > > > > Please note that I'm not trying to jail in a program for security purposes, > > just for test and debug purposes. > > Yeah, linux-user/path.c does seem to be trying to filter the paths. (Does -L > do more than just adjust the elf interpreter prefix? The syscalls are Yes, -L tries do map all paths. It's behavior depends on wether the file exists on the target dir or not. If the file does not exist on the target dir, I beleive it maps to the host fs. Also, it doesn't do anything with relative paths. > wrapped in calls to path() which _could_ do something interesting, but > doesn't. (And freeing the string would probably require a static pointer so > the next call frees the previous one.) > > Even then, attempting to deal with things like symlinks that point to absolute > paths would be quite a headache, and considering the default busybox install > does exactly that, it's not exactly an unheard of corner case... Hmm, our (axis) version of busybox uses relative paths for all symbolic links. It might be patched though, I haven't dug very deep. But otherwise yes, absolute symbolic links need to be considered with the sysroot approach. Best regards -- Edgar E. Iglesias Axis Communications AB ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH] -chroot and -su options. 2008-03-14 14:08 ` Edgar E. Iglesias @ 2008-03-14 15:26 ` Rob Landley 0 siblings, 0 replies; 8+ messages in thread From: Rob Landley @ 2008-03-14 15:26 UTC (permalink / raw) To: Edgar E. Iglesias; +Cc: qemu-devel On Friday 14 March 2008 09:08:57 Edgar E. Iglesias wrote: > > Even then, attempting to deal with things like symlinks that point to > > absolute paths would be quite a headache, and considering the default > > busybox install does exactly that, it's not exactly an unheard of corner > > case... > > Hmm, our (axis) version of busybox uses relative paths for all symbolic > links. It might be patched though, I haven't dug very deep. But otherwise > yes, absolute symbolic links need to be considered with the sysroot > approach. It might help if you make "--sysroot" a synonym for "-L" and _document_ that it affects all application emulation syscalls. But also document that it's not a full solution. (In addition to relative paths, remember that symlinks can resolve to other symlinks, and that every path component can be a symlink so in a path like "one/two/three" if "two" is a symlink to "../walrus/fruitbasket" and "walrus" is another symlink.... Implementing "readlink -f" isn't trivial. I should know, I worked out how to do it properly for toybox but haven't had time yet.) Probably the easiest thing to do for the moment is have both the --chroot and the --sysroot options. > Best regards Rob -- "One of my most productive days was throwing away 1000 lines of code." - Ken Thompson. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH] -chroot and -su options. 2008-03-04 0:28 [Qemu-devel] [PATCH] -chroot and -su options Rob Landley 2008-03-04 11:22 ` Edgar E. Iglesias @ 2008-03-14 16:06 ` Anderson Lizardo 1 sibling, 0 replies; 8+ messages in thread From: Anderson Lizardo @ 2008-03-14 16:06 UTC (permalink / raw) To: qemu-devel Hi, On Mon, Mar 3, 2008 at 8:28 PM, Rob Landley <rob@landley.net> wrote: > Quick and dirty patch to teach qemu application emulation how to chroot (and > drop privs), so you don't have to pollute a target filesystem with host code, > and/or figure out how to build qemu static in order to run a dynamic binary. I tested your patch, but it doesn't seem to work when the application forks a new process (the new process is attempted to run as a native host executable, instead of with qemu). Is that expected? I tried enabling binfmt for it, but then qemu needs to be static, defeating the purpose of this option. Regards, -- Anderson Lizardo Instituto Nokia de Tecnologia Manaus - Brazil ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2008-03-14 16:06 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-03-04 0:28 [Qemu-devel] [PATCH] -chroot and -su options Rob Landley 2008-03-04 11:22 ` Edgar E. Iglesias 2008-03-05 6:51 ` Rob Landley 2008-03-05 7:54 ` Edgar E. Iglesias 2008-03-06 6:47 ` Rob Landley 2008-03-14 14:08 ` Edgar E. Iglesias 2008-03-14 15:26 ` Rob Landley 2008-03-14 16:06 ` Anderson Lizardo
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).