Patches look good; except it's missing the initgroups() / setresgid() / setresuid() code.<br><br>I wasn't sure how gmail would handle pasting code into it.<br><br><div class="gmail_quote">On Thu, Nov 11, 2010 at 2:02 PM, Rusty Russell <span dir="ltr"><<a href="mailto:rusty@rustcorp.com.au" target="_blank">rusty@rustcorp.com.au</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
Hi Philip,<br>
<br>
   There was some whitespace damage so I ended up reworking and splitting<br>
your patches.  Mainly flipped it to kernel-style coding, and added some<br>
commentry (some extracted from our email conversation).<br>
<br>
Here they are, for your ack/Signed-off-by.<br>
<br>
Thanks!<br>
Rusty.<br>
<br>
Subject: lguest: example launcher to use guard pages, drop PROT_EXEC, fix limit logic<br>
From: Philip Sanderson <<a href="mailto:philip.k.sanderson@gmail.com" target="_blank">philip.k.sanderson@gmail.com</a>><br>
<br>
PROT_EXEC seems to be completely unnecessary (as the lguest binary<br>
never executes there), and will allow it to work with SELinux (and<br>
more importantly, PaX :-) as they can/do forbid writable and<br>
executable mappings.<br>
<br>
Also, map PROT_NONE guard pages at start and end of guest memory for extra<br>
paranoia.<br>
<br>
I changed the length check to addr + size > guest_limit because >= is wrong<br>
(addr of 0, size of getpagesize() with a guest_limit of getpagesize() would<br>
false positive).<br>
<br>
Signed-off-by: Rusty Russell <<a href="mailto:rusty@rustcorp.com.au" target="_blank">rusty@rustcorp.com.au</a>><br>
<br>
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c<br>
--- a/Documentation/lguest/lguest.c<br>
+++ b/Documentation/lguest/lguest.c<br>
@@ -298,10 +298,12 @@ static void *map_zeroed_pages(unsigned i<br>
<br>
        /*<br>
         * We use a private mapping (ie. if we write to the page, it will be<br>
-        * copied).<br>
+        * copied). We allocate an extra two pages PROT_NONE to act as guard<br>
+        * pages against invalid read/write attempts that exceed allocated space.<br>
         */<br>
-       addr = mmap(NULL, getpagesize() * num,<br>
-                   PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, fd, 0);<br>
+       addr = mmap(NULL, getpagesize() * (num+2),<br>
+                   PROT_NONE, MAP_PRIVATE, fd, 0);<br>
+<br>
        if (addr == MAP_FAILED)<br>
                err(1, "Mmapping %u pages of /dev/zero", num);<br>
<br>
@@ -343,7 +345,7 @@ static void map_at(int fd, void *addr, u<br>
         * done to it.  This allows us to share untouched memory between<br>
         * Guests.<br>
         */<br>
-       if (mmap(addr, len, PROT_READ|PROT_WRITE|PROT_EXEC,<br>
+       if (mmap(addr, len, PROT_READ|PROT_WRITE,<br>
                 MAP_FIXED|MAP_PRIVATE, fd, offset) != MAP_FAILED)<br>
                return;<br>
<br>
@@ -573,10 +575,10 @@ static void *_check_pointer(unsigned lon<br>
                            unsigned int line)<br>
 {<br>
        /*<br>
-        * We have to separately check addr and addr+size, because size could<br>
-        * be huge and addr + size might wrap around.<br>
+        * Check if the requested address and size exceeds the allocated memory,<br>
+        * or addr + size wraps around.<br>
         */<br>
-       if (addr >= guest_limit || addr + size >= guest_limit)<br>
+       if ((addr + size) > guest_limit || (addr + size) < addr)<br>
                errx(1, "%s:%i: Invalid address %#lx", __FILE__, line, addr);<br>
        /*<br>
         * We return a pointer for the caller's convenience, now we know it's<br>
<br>
<br>
Subject: lguest: --username and --chroot options<br>
From: Philip Sanderson <<a href="mailto:philip.k.sanderson@gmail.com" target="_blank">philip.k.sanderson@gmail.com</a>><br>
<br>
I've attached a patch which implements dropping to privileges<br>
and chrooting to a directory.<br>
<br>
Signed-off-by: Rusty Russell <<a href="mailto:rusty@rustcorp.com.au" target="_blank">rusty@rustcorp.com.au</a>><br>
<br>
diff -ur linux-2.6.35.8-orig/Documentation/lguest/lguest.c<br>
linux-2.6.35.8/Documentation/lguest/lguest.c<br>
<br>
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c<br>
--- a/Documentation/lguest/lguest.c<br>
+++ b/Documentation/lguest/lguest.c<br>
@@ -39,6 +39,9 @@<br>
 #include <limits.h><br>
 #include <stddef.h><br>
 #include <signal.h><br>
+#include <pwd.h><br>
+#include <grp.h><br>
+<br>
 #include <linux/virtio_config.h><br>
 #include <linux/virtio_net.h><br>
 #include <linux/virtio_blk.h><br>
@@ -1874,6 +1877,8 @@ static struct option opts[] = {<br>
        { "block", 1, NULL, 'b' },<br>
        { "rng", 0, NULL, 'r' },<br>
        { "initrd", 1, NULL, 'i' },<br>
+       { "username", 1, NULL, 'u' },<br>
+       { "chroot", 1, NULL, 'c' },<br>
        { NULL },<br>
 };<br>
 static void usage(void)<br>
@@ -1896,6 +1901,12 @@ int main(int argc, char *argv[])<br>
        /* If they specify an initrd file to load. */<br>
        const char *initrd_name = NULL;<br>
<br>
+       /* Password structure for initgroups/setres[gu]id */<br>
+       struct passwd *user_details = NULL;<br>
+<br>
+       /* Directory to chroot to */<br>
+       char *chroot_path = NULL;<br>
+<br>
        /* Save the args: we "reboot" by execing ourselves again. */<br>
        main_args = argv;<br>
<br>
@@ -1952,6 +1963,14 @@ int main(int argc, char *argv[])<br>
                case 'i':<br>
                        initrd_name = optarg;<br>
                        break;<br>
+               case 'u':<br>
+                       user_details = getpwnam(optarg);<br>
+                       if (!user_details)<br>
+                               err(1, "getpwnam failed, incorrect username?");<br>
+                       break;<br>
+               case 'c':<br>
+                       chroot_path = optarg;<br>
+                       break;<br>
                default:<br>
                        warnx("Unknown argument %s", argv[optind]);<br>
                        usage();<br>
<br>
<br>
Subject: lguest: document --rng in example Launcher<br>
From: Philip Sanderson <<a href="mailto:philip.k.sanderson@gmail.com" target="_blank">philip.k.sanderson@gmail.com</a>><br>
<br>
Rusty Russell wrote:<br>
> Ah, it will appear as /dev/hwrng.  It's a weirdness of Linux that our actual<br>
> hardware number generators are not wired up to /dev/random...<br>
<br>
Reflected this in the documentation, thanks :-)<br>
<br>
Signed-off-by: Rusty Russell <<a href="mailto:rusty@rustcorp.com.au" target="_blank">rusty@rustcorp.com.au</a>><br>
<br>
diff --git a/Documentation/lguest/lguest.txt b/Documentation/lguest/lguest.txt<br>
--- a/Documentation/lguest/lguest.txt<br>
+++ b/Documentation/lguest/lguest.txt<br>
@@ -114,6 +114,11 @@ Running Lguest:<br>
   See <a href="http://linux-net.osdl.org/index.php/Bridge" target="_blank">http://linux-net.osdl.org/index.php/Bridge</a> for general information<br>
   on how to get bridging working.<br>
<br>
+- Random number generation. Using the --rng option will provide a<br>
+  /dev/hwrng in the guest that will read from the host's /dev/random.<br>
+  Use this option in conjunction with rng-tools (see ../hw_random.txt)<br>
+  to provide entropy to the guest kernel's /dev/random.<br>
+<br>
 There is a helpful mailing list at <a href="http://ozlabs.org/mailman/listinfo/lguest" target="_blank">http://ozlabs.org/mailman/listinfo/lguest</a><br>
<br>
 Good luck!<br>
</blockquote></div><br>