diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-20 19:31:20 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-20 19:31:20 -0500 |
commit | e55fdbd7414a3ee991d7081a256153f61ea98b9f (patch) | |
tree | 252d30f5821bbb10d95a0c2d77cf21a7f4e7d5e3 /Documentation | |
parent | c522682d7433d27461d631d03a2a1a3b741e9c91 (diff) | |
parent | 8b3bb3ecf1934ac4a7005ad9017de1127e2fbd2f (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus
* git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus:
virtio: remove virtio-pci root device
LGUEST_GUEST: fix unmet direct dependencies (VIRTUALIZATION && VIRTIO)
lguest: compile fixes
lguest: Use this_cpu_ops
lguest: document --rng in example Launcher
lguest: example launcher to use guard pages, drop PROT_EXEC, fix limit logic
lguest: --username and --chroot options
Diffstat (limited to 'Documentation')
-rw-r--r-- | Documentation/lguest/lguest.c | 73 | ||||
-rw-r--r-- | Documentation/lguest/lguest.txt | 5 |
2 files changed, 70 insertions, 8 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c index dc73bc54cc4e..d9da7e148538 100644 --- a/Documentation/lguest/lguest.c +++ b/Documentation/lguest/lguest.c | |||
@@ -39,6 +39,9 @@ | |||
39 | #include <limits.h> | 39 | #include <limits.h> |
40 | #include <stddef.h> | 40 | #include <stddef.h> |
41 | #include <signal.h> | 41 | #include <signal.h> |
42 | #include <pwd.h> | ||
43 | #include <grp.h> | ||
44 | |||
42 | #include <linux/virtio_config.h> | 45 | #include <linux/virtio_config.h> |
43 | #include <linux/virtio_net.h> | 46 | #include <linux/virtio_net.h> |
44 | #include <linux/virtio_blk.h> | 47 | #include <linux/virtio_blk.h> |
@@ -298,20 +301,27 @@ static void *map_zeroed_pages(unsigned int num) | |||
298 | 301 | ||
299 | /* | 302 | /* |
300 | * We use a private mapping (ie. if we write to the page, it will be | 303 | * We use a private mapping (ie. if we write to the page, it will be |
301 | * copied). | 304 | * copied). We allocate an extra two pages PROT_NONE to act as guard |
305 | * pages against read/write attempts that exceed allocated space. | ||
302 | */ | 306 | */ |
303 | addr = mmap(NULL, getpagesize() * num, | 307 | addr = mmap(NULL, getpagesize() * (num+2), |
304 | PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, fd, 0); | 308 | PROT_NONE, MAP_PRIVATE, fd, 0); |
309 | |||
305 | if (addr == MAP_FAILED) | 310 | if (addr == MAP_FAILED) |
306 | err(1, "Mmapping %u pages of /dev/zero", num); | 311 | err(1, "Mmapping %u pages of /dev/zero", num); |
307 | 312 | ||
313 | if (mprotect(addr + getpagesize(), getpagesize() * num, | ||
314 | PROT_READ|PROT_WRITE) == -1) | ||
315 | err(1, "mprotect rw %u pages failed", num); | ||
316 | |||
308 | /* | 317 | /* |
309 | * One neat mmap feature is that you can close the fd, and it | 318 | * One neat mmap feature is that you can close the fd, and it |
310 | * stays mapped. | 319 | * stays mapped. |
311 | */ | 320 | */ |
312 | close(fd); | 321 | close(fd); |
313 | 322 | ||
314 | return addr; | 323 | /* Return address after PROT_NONE page */ |
324 | return addr + getpagesize(); | ||
315 | } | 325 | } |
316 | 326 | ||
317 | /* Get some more pages for a device. */ | 327 | /* Get some more pages for a device. */ |
@@ -343,7 +353,7 @@ static void map_at(int fd, void *addr, unsigned long offset, unsigned long len) | |||
343 | * done to it. This allows us to share untouched memory between | 353 | * done to it. This allows us to share untouched memory between |
344 | * Guests. | 354 | * Guests. |
345 | */ | 355 | */ |
346 | if (mmap(addr, len, PROT_READ|PROT_WRITE|PROT_EXEC, | 356 | if (mmap(addr, len, PROT_READ|PROT_WRITE, |
347 | MAP_FIXED|MAP_PRIVATE, fd, offset) != MAP_FAILED) | 357 | MAP_FIXED|MAP_PRIVATE, fd, offset) != MAP_FAILED) |
348 | return; | 358 | return; |
349 | 359 | ||
@@ -573,10 +583,10 @@ static void *_check_pointer(unsigned long addr, unsigned int size, | |||
573 | unsigned int line) | 583 | unsigned int line) |
574 | { | 584 | { |
575 | /* | 585 | /* |
576 | * We have to separately check addr and addr+size, because size could | 586 | * Check if the requested address and size exceeds the allocated memory, |
577 | * be huge and addr + size might wrap around. | 587 | * or addr + size wraps around. |
578 | */ | 588 | */ |
579 | if (addr >= guest_limit || addr + size >= guest_limit) | 589 | if ((addr + size) > guest_limit || (addr + size) < addr) |
580 | errx(1, "%s:%i: Invalid address %#lx", __FILE__, line, addr); | 590 | errx(1, "%s:%i: Invalid address %#lx", __FILE__, line, addr); |
581 | /* | 591 | /* |
582 | * We return a pointer for the caller's convenience, now we know it's | 592 | * We return a pointer for the caller's convenience, now we know it's |
@@ -1872,6 +1882,8 @@ static struct option opts[] = { | |||
1872 | { "block", 1, NULL, 'b' }, | 1882 | { "block", 1, NULL, 'b' }, |
1873 | { "rng", 0, NULL, 'r' }, | 1883 | { "rng", 0, NULL, 'r' }, |
1874 | { "initrd", 1, NULL, 'i' }, | 1884 | { "initrd", 1, NULL, 'i' }, |
1885 | { "username", 1, NULL, 'u' }, | ||
1886 | { "chroot", 1, NULL, 'c' }, | ||
1875 | { NULL }, | 1887 | { NULL }, |
1876 | }; | 1888 | }; |
1877 | static void usage(void) | 1889 | static void usage(void) |
@@ -1894,6 +1906,12 @@ int main(int argc, char *argv[]) | |||
1894 | /* If they specify an initrd file to load. */ | 1906 | /* If they specify an initrd file to load. */ |
1895 | const char *initrd_name = NULL; | 1907 | const char *initrd_name = NULL; |
1896 | 1908 | ||
1909 | /* Password structure for initgroups/setres[gu]id */ | ||
1910 | struct passwd *user_details = NULL; | ||
1911 | |||
1912 | /* Directory to chroot to */ | ||
1913 | char *chroot_path = NULL; | ||
1914 | |||
1897 | /* Save the args: we "reboot" by execing ourselves again. */ | 1915 | /* Save the args: we "reboot" by execing ourselves again. */ |
1898 | main_args = argv; | 1916 | main_args = argv; |
1899 | 1917 | ||
@@ -1950,6 +1968,14 @@ int main(int argc, char *argv[]) | |||
1950 | case 'i': | 1968 | case 'i': |
1951 | initrd_name = optarg; | 1969 | initrd_name = optarg; |
1952 | break; | 1970 | break; |
1971 | case 'u': | ||
1972 | user_details = getpwnam(optarg); | ||
1973 | if (!user_details) | ||
1974 | err(1, "getpwnam failed, incorrect username?"); | ||
1975 | break; | ||
1976 | case 'c': | ||
1977 | chroot_path = optarg; | ||
1978 | break; | ||
1953 | default: | 1979 | default: |
1954 | warnx("Unknown argument %s", argv[optind]); | 1980 | warnx("Unknown argument %s", argv[optind]); |
1955 | usage(); | 1981 | usage(); |
@@ -2021,6 +2047,37 @@ int main(int argc, char *argv[]) | |||
2021 | /* If we exit via err(), this kills all the threads, restores tty. */ | 2047 | /* If we exit via err(), this kills all the threads, restores tty. */ |
2022 | atexit(cleanup_devices); | 2048 | atexit(cleanup_devices); |
2023 | 2049 | ||
2050 | /* If requested, chroot to a directory */ | ||
2051 | if (chroot_path) { | ||
2052 | if (chroot(chroot_path) != 0) | ||
2053 | err(1, "chroot(\"%s\") failed", chroot_path); | ||
2054 | |||
2055 | if (chdir("/") != 0) | ||
2056 | err(1, "chdir(\"/\") failed"); | ||
2057 | |||
2058 | verbose("chroot done\n"); | ||
2059 | } | ||
2060 | |||
2061 | /* If requested, drop privileges */ | ||
2062 | if (user_details) { | ||
2063 | uid_t u; | ||
2064 | gid_t g; | ||
2065 | |||
2066 | u = user_details->pw_uid; | ||
2067 | g = user_details->pw_gid; | ||
2068 | |||
2069 | if (initgroups(user_details->pw_name, g) != 0) | ||
2070 | err(1, "initgroups failed"); | ||
2071 | |||
2072 | if (setresgid(g, g, g) != 0) | ||
2073 | err(1, "setresgid failed"); | ||
2074 | |||
2075 | if (setresuid(u, u, u) != 0) | ||
2076 | err(1, "setresuid failed"); | ||
2077 | |||
2078 | verbose("Dropping privileges completed\n"); | ||
2079 | } | ||
2080 | |||
2024 | /* Finally, run the Guest. This doesn't return. */ | 2081 | /* Finally, run the Guest. This doesn't return. */ |
2025 | run_guest(); | 2082 | run_guest(); |
2026 | } | 2083 | } |
diff --git a/Documentation/lguest/lguest.txt b/Documentation/lguest/lguest.txt index 6ccaf8e1a00e..dad99978a6a8 100644 --- a/Documentation/lguest/lguest.txt +++ b/Documentation/lguest/lguest.txt | |||
@@ -117,6 +117,11 @@ Running Lguest: | |||
117 | 117 | ||
118 | for general information on how to get bridging to work. | 118 | for general information on how to get bridging to work. |
119 | 119 | ||
120 | - Random number generation. Using the --rng option will provide a | ||
121 | /dev/hwrng in the guest that will read from the host's /dev/random. | ||
122 | Use this option in conjunction with rng-tools (see ../hw_random.txt) | ||
123 | to provide entropy to the guest kernel's /dev/random. | ||
124 | |||
120 | There is a helpful mailing list at http://ozlabs.org/mailman/listinfo/lguest | 125 | There is a helpful mailing list at http://ozlabs.org/mailman/listinfo/lguest |
121 | 126 | ||
122 | Good luck! | 127 | Good luck! |