int chpst_main(int argc ATTRIBUTE_UNUSED, char **argv) { INIT_G(); if (applet_name[3] == 'd') envdir(argc, argv); if (applet_name[1] == 'o') softlimit(argc, argv); if (applet_name[0] == 's') setuidgid(argc, argv); if (applet_name[0] == 'e') envuidgid(argc, argv); // otherwise we are chpst { char *m,*d,*o,*p,*f,*c,*r,*t,*n; getopt32(argv, "+u:U:e:m:d:o:p:f:c:r:t:/:n:vP012", &set_user,&env_user,&env_dir, &m,&d,&o,&p,&f,&c,&r,&t,&root,&n); // if (option_mask32 & 0x1) // -u // if (option_mask32 & 0x2) // -U // if (option_mask32 & 0x4) // -e if (option_mask32 & 0x8) limits = limitl = limita = limitd = xatoul(m); // -m if (option_mask32 & 0x10) limitd = xatoul(d); // -d if (option_mask32 & 0x20) limito = xatoul(o); // -o if (option_mask32 & 0x40) limitp = xatoul(p); // -p if (option_mask32 & 0x80) limitf = xatoul(f); // -f if (option_mask32 & 0x100) limitc = xatoul(c); // -c if (option_mask32 & 0x200) limitr = xatoul(r); // -r if (option_mask32 & 0x400) limitt = xatoul(t); // -t // if (option_mask32 & 0x800) // -/ if (option_mask32 & 0x1000) nicelvl = xatoi(n); // -n // The below consts should match #defines at top! //if (option_mask32 & 0x2000) OPT_verbose = 1; // -v //if (option_mask32 & 0x4000) OPT_pgrp = 1; // -P //if (option_mask32 & 0x8000) OPT_nostdin = 1; // -0 //if (option_mask32 & 0x10000) OPT_nostdout = 1; // -1 //if (option_mask32 & 0x20000) OPT_nostderr = 1; // -2 } argv += optind; if (!argv || !*argv) bb_show_usage(); if (OPT_pgrp) setsid(); if (env_dir) edir(env_dir); if (root) { xchdir(root); xchroot("."); } slimit(); if (nicelvl) { errno = 0; if (nice(nicelvl) == -1) bb_perror_msg_and_die("nice"); } if (env_user) euidgid(env_user); if (set_user) suidgid(set_user); if (OPT_nostdin) close(0); if (OPT_nostdout) close(1); if (OPT_nostderr) close(2); BB_EXECVP(argv[0], argv); bb_perror_msg_and_die("exec %s", argv[0]); }
int switch_root_main(int argc UNUSED_PARAM, char **argv) { char *newroot, *console = NULL; struct stat st1, st2; struct statfs stfs; dev_t rootdev; // Parse args (-c console) opt_complementary = "-2"; // minimum 2 params getopt32(argv, "+c:", &console); // '+': stop parsing at first non-option argv += optind; // Change to new root directory and verify it's a different fs. newroot = *argv++; xchdir(newroot); if (lstat(".", &st1) || lstat("/", &st2) || st1.st_dev == st2.st_dev) { bb_error_msg_and_die("bad newroot %s", newroot); } rootdev = st2.st_dev; // Additional sanity checks: we're about to rm -rf /, so be REALLY SURE // we mean it. (I could make this a CONFIG option, but I would get email // from all the people who WILL eat their filesystems.) if (lstat("/init", &st1) || !S_ISREG(st1.st_mode) || statfs("/", &stfs) || (((unsigned)stfs.f_type != RAMFS_MAGIC) && ((unsigned)stfs.f_type != TMPFS_MAGIC)) || (getpid() != 1) ) { bb_error_msg_and_die("not rootfs"); } // Zap everything out of rootdev delete_contents("/", rootdev); // Overmount / with newdir and chroot into it. The chdir is needed to // recalculate "." and ".." links. if (mount(".", "/", NULL, MS_MOVE, NULL)) bb_error_msg_and_die("error moving root"); xchroot("."); xchdir("/"); // If a new console specified, redirect stdin/stdout/stderr to that. if (console) { close(0); xopen(console, O_RDWR); xdup2(0, 1); xdup2(0, 2); } // Exec real init. (This is why we must be pid 1.) execv(argv[0], argv); bb_perror_msg_and_die("bad init %s", argv[0]); }
int chroot_main(int argc UNUSED_PARAM, char **argv) { ++argv; if (!*argv) bb_show_usage(); xchroot(*argv); ++argv; if (!*argv) { /* no 2nd param (PROG), use shell */ argv -= 2; argv[0] = (char *) get_shell_name(); argv[1] = (char *) "-i"; /* GNU coreutils 8.4 compat */ /*argv[2] = NULL; - already is */ } BB_EXECVP_or_die(argv); }
int chroot_main(int argc UNUSED_PARAM, char **argv) { ++argv; if (!*argv) bb_show_usage(); xchroot(*argv); xchdir("/"); ++argv; if (!*argv) { /* no 2nd param (PROG), use shell */ argv -= 2; argv[0] = getenv("SHELL"); if (!argv[0]) { argv[0] = (char *) DEFAULT_SHELL; } argv[1] = (char *) "-i"; } BB_EXECVP(*argv, argv); bb_perror_msg_and_die("can't execute '%s'", *argv); }
int chroot_main(int argc UNUSED_PARAM, char **argv) { ++argv; if (!*argv) bb_show_usage(); xchroot(*argv); xchdir("/"); ++argv; if (!*argv) { /* no 2nd param (PROG), use shell */ argv -= 2; argv[0] = getenv("SHELL"); if (!argv[0]) { argv[0] = (char *) DEFAULT_SHELL; } argv[1] = (char *) "-i"; } execvp(argv[0], argv); xfunc_error_retval = (errno == ENOENT) ? 127 : 126; bb_perror_msg_and_die("can't execute '%s'", argv[0]); }
int switch_root_main(int argc UNUSED_PARAM, char **argv) { char *newroot, *console = NULL; struct stat st; struct statfs stfs; dev_t rootdev; // Parse args (-c console) opt_complementary = "-2"; // minimum 2 params getopt32(argv, "+c:", &console); // '+': stop at first non-option argv += optind; newroot = *argv++; // Change to new root directory and verify it's a different fs xchdir(newroot); xstat("/", &st); rootdev = st.st_dev; xstat(".", &st); if (st.st_dev == rootdev || getpid() != 1) { // Show usage, it says new root must be a mountpoint // and we must be PID 1 bb_show_usage(); } // Additional sanity checks: we're about to rm -rf /, so be REALLY SURE // we mean it. I could make this a CONFIG option, but I would get email // from all the people who WILL destroy their filesystems. if (stat("/init", &st) != 0 || !S_ISREG(st.st_mode)) { bb_error_msg_and_die("/init is not a regular file"); } statfs("/", &stfs); // this never fails if ((unsigned)stfs.f_type != RAMFS_MAGIC && (unsigned)stfs.f_type != TMPFS_MAGIC ) { bb_error_msg_and_die("root filesystem is not ramfs/tmpfs"); } // Zap everything out of rootdev delete_contents("/", rootdev); // Overmount / with newdir and chroot into it if (mount(".", "/", NULL, MS_MOVE, NULL)) { // For example, fails when newroot is not a mountpoint bb_perror_msg_and_die("error moving root"); } xchroot("."); // The chdir is needed to recalculate "." and ".." links /*xchdir("/"); - done in xchroot */ // If a new console specified, redirect stdin/stdout/stderr to it if (console) { close(0); xopen(console, O_RDWR); xdup2(0, 1); xdup2(0, 2); } // Exec real init execv(argv[0], argv); bb_perror_msg_and_die("can't execute '%s'", argv[0]); }