qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [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).