From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KtVho-0000L4-4O for qemu-devel@nongnu.org; Fri, 24 Oct 2008 19:04:32 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KtVhm-0000JT-Pm for qemu-devel@nongnu.org; Fri, 24 Oct 2008 19:04:31 -0400 Received: from [199.232.76.173] (port=38469 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KtVhm-0000JQ-MU for qemu-devel@nongnu.org; Fri, 24 Oct 2008 19:04:30 -0400 Received: from static-71-162-243-5.phlapa.fios.verizon.net ([71.162.243.5]:42275 helo=grelber.thyrsus.com) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1KtVhl-0006T9-UY for qemu-devel@nongnu.org; Fri, 24 Oct 2008 19:04:30 -0400 From: Rob Landley Date: Fri, 24 Oct 2008 18:06:10 -0500 References: <20081024092129.GA5952@mx.loc> In-Reply-To: <20081024092129.GA5952@mx.loc> MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_iTlAJ5nJLmh85lG" Message-Id: <200810241806.10698.rob@landley.net> Subject: [Qemu-devel] [PATCH] Re: option to have qemu chroot() into the target filesystem Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Bernhard Reutner-Fischer Cc: qemu-devel@nongnu.org, 415996@bugs.debian.org --Boundary-00=_iTlAJ5nJLmh85lG Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline On Friday 24 October 2008 04:21:29 Bernhard Reutner-Fischer wrote: > A patch was in this thread: > http://www.mail-archive.com/qemu-devel@nongnu.org/msg16297.html > > Rob promised to respin it tomorrow and resend it in to the list. > thanks The debian bug report in question is: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=415996 I checked and the old patch still applies cleanly (well, with an offset, but no fuzz). I applied it and then did an svn diff, the result of which is attached. (As with all svn diffs, it applies with "patch -p0 -i blah.patch") It's actually a very simple patch, which does this: A) Teach qemu-$TARGET to do a chdir() plus chroot() in response to a -chroot command line option. B) Because A) requires root access, teach qemu-$TARGET to change uid and gid via a -su option (and set both the real and effective user IDs so it's actually dropping priviledges). C) Add error handling if any of the above fails. (I.E. I check the return code so that if you _don't _drop privs I'm not introducing a security hole.) D) Add help text entries describing the new options. The only objection to the original patch was that there's one case it doesn't cover; if the emulated process does an "exec" of another target binary, qemu doesn't handle that: http://www.mail-archive.com/qemu-devel%40nongnu.org/msg16496.html In my opinion this boils down to "qemu doesn't do something before this patch, and still doesn't do it afterwards either". That's really a separate issue, which can be addressed later if necessary. Rob P.S. I note that I did _not_ check to make sure that "qemu-arm -su" actually has an argument after it to avoid a segfault, but then "qemu-arm -cpu", "qemu-arm -s", "qemu-arm -g" and so on all segfault in exactly the same way, so that's another separate issue if anybody cares. --Boundary-00=_iTlAJ5nJLmh85lG Content-Type: text/x-diff; charset="iso-8859-1"; name="chroot2.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="chroot2.patch" Index: linux-user/main.c =================================================================== --- linux-user/main.c (revision 5527) +++ linux-user/main.c (working copy) @@ -2186,6 +2186,10 @@ "-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" @@ -2301,6 +2305,28 @@ 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(); --Boundary-00=_iTlAJ5nJLmh85lG--