static void sanitize_home(void) { assert(getuid() != 0); // this code works only for regular users if (arg_debug) printf("Cleaning /home directory\n"); struct stat s; if (stat(cfg.homedir, &s) == -1) { // cannot find home directory, just return fprintf(stderr, "Warning: cannot find home directory\n"); return; } fs_build_mnt_dir(); if (mkdir(RUN_WHITELIST_HOME_DIR, 0755) == -1) errExit("mkdir"); // keep a copy of the user home directory if (mount(cfg.homedir, RUN_WHITELIST_HOME_DIR, NULL, MS_BIND|MS_REC, NULL) < 0) errExit("mount bind"); // mount tmpfs in the new home if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) errExit("mount tmpfs"); fs_logger("tmpfs /home"); // create user home directory if (mkdir(cfg.homedir, 0755) == -1) { if (mkpath_as_root(cfg.homedir)) errExit("mkpath"); if (mkdir(cfg.homedir, 0755) == -1) errExit("mkdir"); } fs_logger2("mkdir", cfg.homedir); // set mode and ownership if (chown(cfg.homedir, s.st_uid, s.st_gid) == -1) errExit("chown"); if (chmod(cfg.homedir, s.st_mode) == -1) errExit("chmod"); // mount user home directory if (mount(RUN_WHITELIST_HOME_DIR, cfg.homedir, NULL, MS_BIND|MS_REC, NULL) < 0) errExit("mount bind"); // mask home dir under /run if (mount("tmpfs", RUN_WHITELIST_HOME_DIR, "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) errExit("mount tmpfs"); fs_logger2("tmpfs", RUN_WHITELIST_HOME_DIR); if (!arg_private) fs_logger2("whitelist", cfg.homedir); }
// private mode (--private): // mount tmpfs over /home/user, // tmpfs on top of /root in nonroot mode, // set skel files, // restore .Xauthority void fs_private(void) { char *homedir = cfg.homedir; assert(homedir); uid_t u = getuid(); gid_t g = getgid(); int xflag = store_xauthority(); int aflag = store_asoundrc(); // mask /home if (arg_debug) printf("Mounting a new /home directory\n"); if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) errExit("mounting home directory"); fs_logger("tmpfs /home"); // mask /root if (arg_debug) printf("Mounting a new /root directory\n"); if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_STRICTATIME | MS_REC, "mode=700,gid=0") < 0) errExit("mounting root directory"); fs_logger("tmpfs /root"); if (u != 0) { // create /home/user if (arg_debug) printf("Create a new user directory\n"); if (mkdir(homedir, S_IRWXU) == -1) { if (mkpath_as_root(homedir) == -1) errExit("mkpath"); if (mkdir(homedir, S_IRWXU) == -1) errExit("mkdir"); } if (chown(homedir, u, g) < 0) errExit("chown"); fs_logger2("mkdir", homedir); } skel(homedir, u, g); if (xflag) copy_xauthority(); if (aflag) copy_asoundrc(); }