aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/lguest/lguest.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
index dc73bc54cc4e..f64b85bcd6d4 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>
@@ -1872,6 +1875,8 @@ static struct option opts[] = {
1872 { "block", 1, NULL, 'b' }, 1875 { "block", 1, NULL, 'b' },
1873 { "rng", 0, NULL, 'r' }, 1876 { "rng", 0, NULL, 'r' },
1874 { "initrd", 1, NULL, 'i' }, 1877 { "initrd", 1, NULL, 'i' },
1878 { "username", 1, NULL, 'u' },
1879 { "chroot", 1, NULL, 'c' },
1875 { NULL }, 1880 { NULL },
1876}; 1881};
1877static void usage(void) 1882static void usage(void)
@@ -1894,6 +1899,12 @@ int main(int argc, char *argv[])
1894 /* If they specify an initrd file to load. */ 1899 /* If they specify an initrd file to load. */
1895 const char *initrd_name = NULL; 1900 const char *initrd_name = NULL;
1896 1901
1902 /* Password structure for initgroups/setres[gu]id */
1903 struct passwd *user_details = NULL;
1904
1905 /* Directory to chroot to */
1906 char *chroot_path = NULL;
1907
1897 /* Save the args: we "reboot" by execing ourselves again. */ 1908 /* Save the args: we "reboot" by execing ourselves again. */
1898 main_args = argv; 1909 main_args = argv;
1899 1910
@@ -1950,6 +1961,14 @@ int main(int argc, char *argv[])
1950 case 'i': 1961 case 'i':
1951 initrd_name = optarg; 1962 initrd_name = optarg;
1952 break; 1963 break;
1964 case 'u':
1965 user_details = getpwnam(optarg);
1966 if (!user_details)
1967 err(1, "getpwnam failed, incorrect username?");
1968 break;
1969 case 'c':
1970 chroot_path = optarg;
1971 break;
1953 default: 1972 default:
1954 warnx("Unknown argument %s", argv[optind]); 1973 warnx("Unknown argument %s", argv[optind]);
1955 usage(); 1974 usage();
@@ -2021,6 +2040,37 @@ int main(int argc, char *argv[])
2021 /* If we exit via err(), this kills all the threads, restores tty. */ 2040 /* If we exit via err(), this kills all the threads, restores tty. */
2022 atexit(cleanup_devices); 2041 atexit(cleanup_devices);
2023 2042
2043 /* If requested, chroot to a directory */
2044 if (chroot_path) {
2045 if (chroot(chroot_path) != 0)
2046 err(1, "chroot(\"%s\") failed", chroot_path);
2047
2048 if (chdir("/") != 0)
2049 err(1, "chdir(\"/\") failed");
2050
2051 verbose("chroot done\n");
2052 }
2053
2054 /* If requested, drop privileges */
2055 if (user_details) {
2056 uid_t u;
2057 gid_t g;
2058
2059 u = user_details->pw_uid;
2060 g = user_details->pw_gid;
2061
2062 if (initgroups(user_details->pw_name, g) != 0)
2063 err(1, "initgroups failed");
2064
2065 if (setresgid(g, g, g) != 0)
2066 err(1, "setresgid failed");
2067
2068 if (setresuid(u, u, u) != 0)
2069 err(1, "setresuid failed");
2070
2071 verbose("Dropping privileges completed\n");
2072 }
2073
2024 /* Finally, run the Guest. This doesn't return. */ 2074 /* Finally, run the Guest. This doesn't return. */
2025 run_guest(); 2075 run_guest();
2026} 2076}