On Mon, Nov 8, 2010 at 8:27 PM, Rusty Russell <span dir="ltr"><<a href="mailto:rusty@rustcorp.com.au">rusty@rustcorp.com.au</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div class="im">On Sat, 6 Nov 2010 10:43:26 pm Philip Sanderson wrote:<br>
> Hello,<br>
><br>
> short version:<br>
><br>
> - Any plans for NX bit support?<br>
<br>
</div>I haven't even looked at it. I NX requires PAE, but that's all I know...<br>
<br></blockquote><div><br>Hmm. Well, it sets an extra bit in the PTE entry, which I think is being filtered out somewhere. <br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
Oh, and it's generally preferred in the kernel world to put patches<br>
inline for easier quoting BTW. </blockquote><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div class="im"><br>
> - Patch for Documentation/lguest/lguest.c -- remove prot_exec, adds chroot.<br>
<br>
</div>Hmm, it's an lguest flaw that we don't enforce this in the module, really.<br>
But making life easier for PaX/SELinux makes sense. </blockquote><div><br><br></div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">could you re-send with that fixed?<br>
<div class="im"><br></div></blockquote><div><br>As requested. I have updated lguest.txt to reflect that rng-tools is required.<br><br>diff -ur linux-2.6.35.8-orig/Documentation/lguest/lguest.c linux-2.6.35.8/Documentation/lguest/lguest.c<br>
--- linux-2.6.35.8-orig/Documentation/lguest/lguest.c 2010-10-29 15:52:43.000000000 +1100<br>+++ linux-2.6.35.8/Documentation/lguest/lguest.c 2010-11-08 21:51:34.244586003 +1100<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/lguest_launcher.h"<br> #include "linux/virtio_config.h"<br> #include "linux/virtio_net.h"<br>
@@ -298,20 +301,25 @@<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 pages<br>
+ * 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>+ if(mprotect(addr + getpagesize(), getpagesize() * num, PROT_READ|PROT_WRITE) == -1) <br>
+ err(1, "mprotect rw %u pages failed", num);<br>+<br> /*<br> * One neat mmap feature is that you can close the fd, and it<br> * stays mapped.<br> */<br> close(fd);<br> <br>- return addr;<br>
+ return addr+getpagesize();<br> }<br> <br> /* Get some more pages for a device. */<br>@@ -343,7 +351,7 @@<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,11 +581,13 @@<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>
+<br>+ if ((addr + size) > guest_limit || (addr + size) < addr)<br> errx(1, "%s:%i: Invalid address %#lx", __FILE__, line, addr);<br>+<br> /*<br> * We return a pointer for the caller's convenience, now we know it's<br>
* safe to use.<br>@@ -1882,6 +1892,8 @@<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>@@ -1904,6 +1916,12 @@<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>@@ -1960,6 +1978,16 @@<br> case 'i':<br> initrd_name = optarg;<br> break;<br>+ case 'u':<br>+ user_details = getpwnam(optarg);<br>
+<br>+ if(! user_details) <br>+ err(1, "getpwnam failed, incorrect uername?");<br>+ <br>+ break;<br>+ case 'c':<br>+ chroot_path = optarg;<br>
+ break;<br> default:<br> warnx("Unknown argument %s", argv[optind]);<br> usage();<br>@@ -2031,6 +2059,39 @@<br> /* If we exit via err(), this kills all the threads, restores tty. */<br>
atexit(cleanup_devices);<br> <br>+ /* If requested, chroot to a directory */<br>+<br>+ if(chroot_path) {<br>+ if(chroot(chroot_path) != 0) <br>+ err(1, "chroot(\"%s\") failed", chroot_path);<br>
+<br>+ if(chdir("/") != 0) <br>+ err(1, "chdir(\"/\") failed");<br>+<br>+ verbose("chroot done");<br>+ }<br>+<br>+ /* If requested, drop privileges */<br>
+ if(user_details) {<br>+ uid_t u;<br>+ gid_t g;<br>+<br>+ u = user_details->pw_uid;<br>+ g = user_details->pw_gid;<br>+<br>+ if(initgroups(user_details->pw_name, g) != 0)<br>
+ err(1, "initgroups failed");<br>+<br>+ if(setresgid(g, g, g) != 0) <br>+ err(1, "setresgid failed");<br>+ <br>+ if(setresuid(u, u, u) != 0) <br>+ err(1, "setresuid failed");<br>
+<br>+ verbose("Dropping privileges completed");<br>+ }<br>+<br>+<br> /* Finally, run the Guest. This doesn't return. */<br> run_guest();<br> }<br>diff -ur linux-2.6.35.8-orig/Documentation/lguest/lguest.txt linux-2.6.35.8/Documentation/lguest/lguest.txt<br>
--- linux-2.6.35.8-orig/Documentation/lguest/lguest.txt 2010-10-29 15:52:43.000000000 +1100<br>+++ linux-2.6.35.8/Documentation/lguest/lguest.txt 2010-11-08 21:29:19.188586003 +1100<br>@@ -114,6 +114,11 @@<br> See <a href="http://linux-net.osdl.org/index.php/Bridge">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">http://ozlabs.org/mailman/listinfo/lguest</a><br> <br> Good luck!<br>
<br> <br>I changed the length check to addr + size > guest_limit because >= is wrong (addr of 0, size of getpagesize() with a guest_limit of getpagesize() would false positive).<br><br></div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
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></blockquote><div><br>Reflected this in the documentation, thanks :-)<br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
Thanks!<br>
<font color="#888888">Rusty.<br>
</font></blockquote></div><br>