void fs_check_etc_list(void) { EUID_ASSERT(); if (strstr(cfg.etc_private_keep, "..")) { fprintf(stderr, "Error: invalid private etc list\n"); exit(1); } char *dlist = strdup(cfg.etc_private_keep); if (!dlist) errExit("strdup"); // build a new list only with the files found char *newlist = malloc(strlen(cfg.etc_private_keep) + 1); if (!newlist) errExit("malloc"); *newlist = '\0'; char *ptr = strtok(dlist, ","); if (check_dir_or_file(ptr)) strcat(newlist, ptr); while ((ptr = strtok(NULL, ",")) != NULL) { if (check_dir_or_file(ptr)) { strcat(newlist, ","); strcat(newlist, ptr); } } cfg.etc_private_keep = newlist; free(dlist); }
void fs_check_bin_list(void) { EUID_ASSERT(); if (strstr(cfg.bin_private_keep, "..")) { fprintf(stderr, "Error: invalid private bin list\n"); exit(1); } char *dlist = strdup(cfg.bin_private_keep); if (!dlist) errExit("strdup"); // create a new list removing files not found char *newlist = malloc(strlen(dlist) + 1 + 1); // +',' + '\0' if (!newlist) errExit("malloc"); *newlist = '\0'; char *newlistptr = newlist; // check the first file char *ptr = strtok(dlist, ","); int notfound = 0; if (check_dir_or_file(ptr)) { // file found, copy the name in the new list strcpy(newlistptr, ptr); strcat(newlistptr, ","); newlistptr += strlen(newlistptr); } else notfound = 1; // check the rest of the list while ((ptr = strtok(NULL, ",")) != NULL) { if (check_dir_or_file(ptr)) { // file found, copy the name in the new list strcpy(newlistptr, ptr); strcat(newlistptr, ","); newlistptr += strlen(newlistptr); } else notfound = 1; } if (*newlist == '\0') { // fprintf(stderr, "Warning: no --private-bin list executable found, option disabled\n"); // cfg.bin_private_keep = NULL; // arg_private_bin = 0; free(newlist); } else { ptr = strrchr(newlist, ','); assert(ptr); *ptr = '\0'; if (notfound && !arg_quiet) fprintf(stderr, "Warning: not all executables from --private-bin list were found. The current list is %s\n", newlist); cfg.bin_private_keep = newlist; } free(dlist); }
static void duplicate(char *name) { char *fname = check_dir_or_file(name); if (arg_debug) printf("Private home: duplicating %s\n", fname); assert(strncmp(fname, cfg.homedir, strlen(cfg.homedir)) == 0); struct stat s; if (lstat(fname, &s) == -1) { free(fname); return; } else if (S_ISDIR(s.st_mode)) { // create the directory in RUN_HOME_DIR char *name; char *ptr = strrchr(fname, '/'); ptr++; if (asprintf(&name, "%s/%s", RUN_HOME_DIR, ptr) == -1) errExit("asprintf"); mkdir_attr(name, 0755, getuid(), getgid()); sbox_run(SBOX_USER| SBOX_CAPS_NONE | SBOX_SECCOMP, 3, PATH_FCOPY, fname, name); free(name); } else sbox_run(SBOX_USER| SBOX_CAPS_NONE | SBOX_SECCOMP, 3, PATH_FCOPY, fname, RUN_HOME_DIR); fs_logger2("clone", fname); fs_logger_print(); // save the current log free(fname); }
// check directory list specified by user (--private-home option) - exit if it fails void fs_check_home_list(void) { if (strstr(cfg.home_private_keep, "..")) { exechelp_logerrv("firejail", FIREJAIL_ERROR, "Error: invalid private-home list\n"); exit(1); } char *dlist = strdup(cfg.home_private_keep); if (!dlist) errExit("strdup"); char *ptr = strtok(dlist, ","); check_dir_or_file(ptr); while ((ptr = strtok(NULL, ",")) != NULL) check_dir_or_file(ptr); free(dlist); }
// check directory list specified by user (--private-home option) - exit if it fails void fs_check_home_list(void) { if (strstr(cfg.home_private_keep, "..")) { fprintf(stderr, "Error: invalid private-home list\n"); exit(1); } char *dlist = strdup(cfg.home_private_keep); if (!dlist) errExit("strdup"); char *ptr = strtok(dlist, ","); check_dir_or_file(ptr); while ((ptr = strtok(NULL, ",")) != NULL) check_dir_or_file(ptr); free(dlist); }
static void duplicate(char *fname) { char *path = check_dir_or_file(fname); if (!path) return; // expand path, just in case this is a symbolic link char *full_path; if (asprintf(&full_path, "%s/%s", path, fname) == -1) errExit("asprintf"); char *actual_path = realpath(full_path, NULL); if (actual_path) { // if the file is a symbolic link not under path, make a symbolic link if (is_link(full_path) && strncmp(actual_path, path, strlen(path))) { char *lnkname; if (asprintf(&lnkname, "%s/%s", RUN_BIN_DIR, fname) == -1) errExit("asprintf"); int rv = symlink(actual_path, lnkname); if (rv) fprintf(stderr, "Warning cannot create symbolic link %s\n", lnkname); else if (arg_debug) printf("Created symbolic link %s -> %s\n", lnkname, actual_path); free(lnkname); } else { // copy the file if (arg_debug) printf("running: %s -a %s %s/%s", RUN_CP_COMMAND, actual_path, RUN_BIN_DIR, fname); pid_t child = fork(); if (child < 0) errExit("fork"); if (child == 0) { char *f; if (asprintf(&f, "%s/%s", RUN_BIN_DIR, fname) == -1) errExit("asprintf"); execlp(RUN_CP_COMMAND, RUN_CP_COMMAND, "-a", actual_path, f, NULL); } // wait for the child to finish waitpid(child, NULL, 0); } free(actual_path); } free(full_path); }
static void duplicate(char *fname) { char *cmd; char *path = check_dir_or_file(fname); if (!path) return; // expand path, just in case this is a symbolic link char *full_path; if (asprintf(&full_path, "%s/%s", path, fname) == -1) errExit("asprintf"); char *actual_path = realpath(full_path, NULL); if (actual_path) { // if the file is a symbolic link not under path, make a symbolic link if (is_link(full_path) && strncmp(actual_path, path, strlen(path))) { char *lnkname; if (asprintf(&lnkname, "%s/%s", RUN_BIN_DIR, fname) == -1) errExit("asprintf"); int rv = symlink(actual_path, lnkname); if (rv) fprintf(stderr, "Warning cannot create symbolic link %s\n", lnkname); else if (arg_debug) printf("Created symbolic link %s -> %s\n", lnkname, actual_path); free(lnkname); } else { // copy the file if (asprintf(&cmd, "%s -a %s %s/%s", RUN_CP_COMMAND, actual_path, RUN_BIN_DIR, fname) == -1) errExit("asprintf"); if (arg_debug) printf("%s\n", cmd); if (system(cmd)) errExit("system cp -a"); free(cmd); } free(actual_path); } free(full_path); }