int binary_search_first(int now) { int from=now+1,to=nreal,mid; if(now>=nreal) { return -1; } if(is_link(now,from,to)==0) { return -1; } while(from<to) { /* fprintf(stderr,"%d %d %d\n",from,to,mid); */ mid=(from+to)/2; if(is_link(now,from,mid)) { to=mid; } else if(is_link(now,mid,mid+1)) { return mid; } else if(is_link(now,mid+1,to)) { from=mid+1; } } return from; }
QIcon FileTreeItem::icon() const { if (m_icon.isNull()) { FileTreeItem * p_this = (FileTreeItem *)this; if (is_dir()) p_this->m_icon=IconProvider::instance()->dirIcon(m_encripted,is_link()); else p_this->m_icon=IconProvider::instance()->fileIcon(name(),m_encripted,is_link()); } return m_icon; }
// check new private home directory (--private= option) - exit if it fails void fs_check_private_dir(void) { // Expand the home directory char *tmp = expand_home(cfg.home_private, cfg.homedir); cfg.home_private = realpath(tmp, NULL); free(tmp); if (!cfg.home_private || !is_dir(cfg.home_private) || is_link(cfg.home_private) || strstr(cfg.home_private, "..")) { exechelp_logerrv("firejail", FIREJAIL_ERROR, "Error: invalid private directory\n"); exit(1); } // check home directory and chroot home directory have the same owner struct stat s2; int rv = stat(cfg.home_private, &s2); if (rv < 0) { exechelp_logerrv("firejail", FIREJAIL_ERROR, "Error: cannot find %s directory\n", cfg.home_private); exit(1); } struct stat s1; rv = stat(cfg.homedir, &s1); if (rv < 0) { exechelp_logerrv("firejail", FIREJAIL_ERROR, "Error: cannot find %s directory, full path name required\n", cfg.homedir); exit(1); } if (s1.st_uid != s2.st_uid) { printf("Error: the two home directories must have the same owner\n"); exit(1); } }
// return 0 if file not found, 1 if found static int check_dir_or_file(const char *name) { assert(name); invalid_filename(name); struct stat s; char *fname; if (asprintf(&fname, "/etc/%s", name) == -1) errExit("asprintf"); if (arg_debug) printf("Checking %s\n", fname); if (stat(fname, &s) == -1) { if (arg_debug) printf("Warning: file %s not found.\n", fname); return 0; } // dir or regular file if (S_ISDIR(s.st_mode) || S_ISREG(s.st_mode)) { free(fname); return 1; } if (!is_link(fname)) { free(fname); return 1; } fprintf(stderr, "Error: invalid file type, %s.\n", fname); exit(1); }
// grab a copy of cp command void fs_build_cp_command(void) { struct stat s; fs_build_mnt_dir(); if (stat(RUN_CP_COMMAND, &s)) { char* fname = realpath("/bin/cp", NULL); if (fname == NULL) { fprintf(stderr, "Error: /bin/cp not found\n"); exit(1); } if (stat(fname, &s)) { fprintf(stderr, "Error: /bin/cp not found\n"); exit(1); } if (is_link(fname)) { fprintf(stderr, "Error: invalid /bin/cp file\n"); exit(1); } int rv = copy_file(fname, RUN_CP_COMMAND); if (rv) { fprintf(stderr, "Error: cannot access /bin/cp\n"); exit(1); } /* coverity[toctou] */ if (chown(RUN_CP_COMMAND, 0, 0)) errExit("chown"); if (chmod(RUN_CP_COMMAND, 0755)) errExit("chmod"); free(fname); } }
static int store_xauthority(void) { // put a copy of .Xauthority in XAUTHORITY_FILE fs_build_mnt_dir(); char *src; char *dest = RUN_XAUTHORITY_FILE; if (asprintf(&src, "%s/.Xauthority", cfg.homedir) == -1) errExit("asprintf"); struct stat s; if (stat(src, &s) == 0) { if (is_link(src)) { fprintf(stderr, "Error: invalid .Xauthority file\n"); exit(1); } int rv = copy_file(src, dest); if (rv) { fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n"); return 0; } return 1; // file copied } return 0; }
void fs_dev_disable_sound(void) { unsigned i = 0; while (dev[i].dev_fname != NULL) { if (dev[i].type == DEV_SOUND) disable_file_or_dir(dev[i].dev_fname); i++; } // disable all jack sockets in /dev/shm glob_t globbuf; int globerr = glob("/dev/shm/jack*", GLOB_NOSORT, NULL, &globbuf); if (globerr) return; for (i = 0; i < globbuf.gl_pathc; i++) { char *path = globbuf.gl_pathv[i]; assert(path); if (is_link(path)) { fwarning("skipping nosound for %s because it is a symbolic link\n", path); continue; } disable_file_or_dir(path); } globfree(&globbuf); }
int seek_step_line(char *line, t_map *map) { if (map->step == 0) { if (is_nbr_ant(line)) save_nbr_ant(ft_atoi(line), map); else return (0); } else if (map->step == 1) { if (is_room(line)) save_room(line, map); else return (0); } else if (map->step == 2) { if (is_link(line)) save_link(line, map); else return (0); } return (1); }
static void check_dir_or_file(const char *name) { assert(name); struct stat s; char *fname; if (asprintf(&fname, "/etc/%s", name) == -1) errExit("asprintf"); if (arg_debug) printf("Checking %s\n", fname); if (stat(fname, &s) == -1) { exechelp_logerrv("firejail", FIREJAIL_ERROR, "Error: file %s not found.\n", fname); exit(1); } // dir or regular file if (S_ISDIR(s.st_mode) || S_ISREG(s.st_mode)) { free(fname); return; } if (!is_link(fname)) { free(fname); return; } exechelp_logerrv("firejail", FIREJAIL_ERROR, "Error: invalid file type, %s.\n", fname); exit(1); }
int check_link(t_lem_env *env, char *s) { int i; int j; int k; int a; env->r.nolink = 0; if (matrice_visit0(env, &i, &j, &k) == 0) return (ft_error(env, 1)); a = -1; if (!is_link(s) || (a = check_link2(env, s, &i, &j)) != 0) return (ft_error(env, 2)); while (++k < env->nbroom) { if ((a = ft_strcmp(env->room[k], &s[i + 1])) == 0) break ; } if (a != 0 || j == k) return (ft_error(env, 2)); if (env->matrice[j][k] == 1) return (ft_error(env, 2)); env->matrice[k][j] += 1; env->matrice[j][k] += 1; env->r.nbline += add_file(env, s); return (1); }
// check new private home directory (--private= option) - exit if it fails void fs_check_private_dir(void) { invalid_filename(cfg.home_private); // Expand the home directory char *tmp = expand_home(cfg.home_private, cfg.homedir); cfg.home_private = realpath(tmp, NULL); free(tmp); if (!cfg.home_private || !is_dir(cfg.home_private) || is_link(cfg.home_private) || strstr(cfg.home_private, "..")) { fprintf(stderr, "Error: invalid private directory\n"); exit(1); } // check home directory and chroot home directory have the same owner struct stat s2; int rv = stat(cfg.home_private, &s2); if (rv < 0) { fprintf(stderr, "Error: cannot find %s directory\n", cfg.home_private); exit(1); } struct stat s1; rv = stat(cfg.homedir, &s1); if (rv < 0) { fprintf(stderr, "Error: cannot find %s directory, full path name required\n", cfg.homedir); exit(1); } if (s1.st_uid != s2.st_uid) { printf("Error: --private directory should be owned by the current user\n"); exit(1); } }
static void list(void) { DIR *dir = opendir("/usr/local/bin"); if (!dir) { fprintf(stderr, "Error: cannot open /usr/local/bin directory\n"); exit(1); } char *firejail_exec; if (asprintf(&firejail_exec, "%s/bin/firejail", PREFIX) == -1) errExit("asprintf"); struct dirent *entry; while ((entry = readdir(dir)) != NULL) { if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; char *fullname; if (asprintf(&fullname, "/usr/local/bin/%s", entry->d_name) == -1) errExit("asprintf"); if (is_link(fullname)) { char* fname = realpath(fullname, NULL); if (fname) { if (strcmp(fname, firejail_exec) == 0) printf("%s\n", fullname); free(fname); } } free(fullname); } closedir(dir); free(firejail_exec); }
// check new private home directory (--private= option) - exit if it fails void fs_check_private_dir(void) { // if the directory starts with ~, expand the home directory if (*cfg.home_private == '~') { char *tmp; if (asprintf(&tmp, "%s%s", cfg.homedir, cfg.home_private + 1) == -1) errExit("asprintf"); cfg.home_private = tmp; } if (!is_dir(cfg.home_private) || is_link(cfg.home_private) || strstr(cfg.home_private, "..")) { fprintf(stderr, "Error: invalid private directory\n"); exit(1); } // check home directory and chroot home directory have the same owner struct stat s2; int rv = stat(cfg.home_private, &s2); if (rv < 0) { fprintf(stderr, "Error: cannot find %s directory\n", cfg.home_private); exit(1); } struct stat s1; rv = stat(cfg.homedir, &s1); if (rv < 0) { fprintf(stderr, "Error: cannot find %s directory, full path name required\n", cfg.homedir); exit(1); } if (s1.st_uid != s2.st_uid) { printf("Error: the two home directories must have the same owner\n"); exit(1); } }
static void check_dir_or_file(const char *name) { assert(name); struct stat s; char *fname; if (asprintf(&fname, "%s/%s", cfg.homedir, name) == -1) errExit("asprintf"); if (arg_debug) printf("***************Checking %s\n", fname); if (stat(fname, &s) == -1) { fprintf(stderr, "Error: file %s not found.\n", fname); exit(1); } // check uid uid_t uid = getuid(); gid_t gid = getgid(); if (s.st_uid != uid || s.st_gid != gid) { fprintf(stderr, "Error: only files or directories created by the current user are allowed.\n"); exit(1); } // dir or regular file if (S_ISDIR(s.st_mode) || S_ISREG(s.st_mode)) { free(fname); return; } if (!is_link(fname)) { free(fname); return; } fprintf(stderr, "Error: invalid file type, %s.\n", fname); exit(1); }
static int store_asoundrc(void) { char *src; char *dest = RUN_ASOUNDRC_FILE; if (asprintf(&src, "%s/.asoundrc", cfg.homedir) == -1) errExit("asprintf"); struct stat s; if (stat(src, &s) == 0) { if (is_link(src)) { // make sure the real path of the file is inside the home directory /* coverity[toctou] */ char* rp = realpath(src, NULL); if (!rp) { fprintf(stderr, "Error: Cannot access %s\n", src); exit(1); } if (strncmp(rp, cfg.homedir, strlen(cfg.homedir)) != 0) { fprintf(stderr, "Error: .asoundrc is a symbolic link pointing to a file outside home directory\n"); exit(1); } free(rp); } int rv = copy_file(src, dest, -1, -1, -0644); if (rv) { fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n"); return 0; } return 1; // file copied } return 0; }
int main(int argc, char **argv) { if (argc < 2) { fprintf(stderr, "Error: please provide a filename to store the program output\n"); usage(); exit(1); } char *fname = argv[1]; // do not accept directories, links, and files with ".." if (strstr(fname, "..") || is_link(fname) || is_dir(fname)) { fprintf(stderr, "Error: invalid output file. Links, directories and files with \"..\" are not allowed.\n"); exit(1); } struct stat s; if (stat(fname, &s) == 0) { // check permissions if (s.st_uid != getuid() || s.st_gid != getgid()) { fprintf(stderr, "Error: the output file needs to be owned by the current user.\n"); exit(1); } // check hard links if (s.st_nlink != 1) { fprintf(stderr, "Error: no hard links allowed.\n"); exit(1); } } // check if we can append to this file /* coverity[toctou] */ FILE *fp = fopen(fname, "a"); if (!fp) { fprintf(stderr, "Error: cannot open output file %s\n", fname); exit(1); } fclose(fp); // preserve the last log file log_rotate(fname); setvbuf (stdout, NULL, _IONBF, 0); while(1) { int n = read(0, buf, sizeof(buf)); if (n < 0 && errno == EINTR) continue; if (n <= 0) break; fwrite(buf, n, 1, stdout); log_write(buf, n, fname); } log_close(); return 0; }
void check_netfilter_file(const char *fname) { EUID_ASSERT(); invalid_filename(fname); if (is_dir(fname) || is_link(fname) || strstr(fname, "..") || access(fname, R_OK )) { fprintf(stderr, "Error: invalid network filter file %s\n", fname); exit(1); } }
linktyp *predlink(linktyp *lp) /* Returnerar pekare till länken före */ { linktyp *ep; if ( is_link(lp->befo) ) ep = lp->befo; else ep = NULL; return ep; }
t_state get_link(t_lem *p, char *str) { if (is_link(str) == 1) { fill_link(p, str); return (LINK); } else if (is_command(str) == 1) return (LINK); return (END); }
linktyp *succlink(linktyp *lp) /* Returnerar pekare till länken efter */ { linktyp *ep; if ( is_link(lp->next) ) ep = lp->next; else ep = NULL; return ep; }
void check_netfilter_file(const char *fname) { if (is_dir(fname) || is_link(fname) || strstr(fname, "..")) { exechelp_logerrv("firejail", FIREJAIL_ERROR, "Error: invalid network filter file\n"); exit(1); } // access call checks as real UID/GID, not as effective UID/GID if (access(fname, R_OK)) { exechelp_logerrv("firejail", FIREJAIL_ERROR, "Error: cannot access network filter file\n"); exit(1); } }
void fs_var_tmp(void) { if (!is_link("/var/tmp")) { if (arg_debug) printf("Mounting tmpfs on /var/tmp\n"); if (mount("tmpfs", "/var/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0) errExit("mounting /var/tmp"); } else { fprintf(stderr, "Warning: /var/tmp not mounted\n"); dbg_test_dir("/var/tmp"); } }
void dbg_test_dir(const char *dir) { if (arg_debug) { if (is_dir(dir)) printf("%s is a directory\n", dir); if (is_link(dir)) { char *lnk = realpath(dir, NULL); if (lnk) { printf("%s is a symbolic link to %s\n", dir, lnk); free(lnk); } } } }
static void check_dir_or_file(const char *name) { assert(name); struct stat s; invalid_filename(name); char *fname = expand_home(name, cfg.homedir); if (!fname) { fprintf(stderr, "Error: file %s not found.\n", name); exit(1); } if (fname[0] != '/') { // If it doesn't start with '/', it must be relative to homedir char* tmp; if (asprintf(&tmp, "%s/%s", cfg.homedir, fname) == -1) errExit("asprintf"); free(fname); fname = tmp; } if (arg_debug) printf("Checking %s\n", fname); if (stat(fname, &s) == -1) { fprintf(stderr, "Error: file %s not found.\n", fname); exit(1); } // check uid uid_t uid = getuid(); gid_t gid = getgid(); if (s.st_uid != uid || s.st_gid != gid) { fprintf(stderr, "Error: only files or directories created by the current user are allowed.\n"); exit(1); } // dir or regular file if (S_ISDIR(s.st_mode) || S_ISREG(s.st_mode)) { free(fname); return; } if (!is_link(fname)) { free(fname); return; } fprintf(stderr, "Error: invalid file type, %s.\n", fname); exit(1); }
// return 1 if found, 0 if not found static char *check_dir_or_file(const char *name) { assert(name); invalid_filename(name); struct stat s; char *fname = NULL; int i = 0; while (paths[i]) { if (asprintf(&fname, "%s/%s", paths[i], name) == -1) errExit("asprintf"); if (arg_debug) printf("Checking %s/%s\n", paths[i], name); if (stat(fname, &s) == 0 && !S_ISDIR(s.st_mode)) { // do not allow directories // check symlink to firejail executable in /usr/local/bin if (strcmp(paths[i], "/usr/local/bin") == 0 && is_link(fname)) { char *actual_path = realpath(fname, NULL); if (actual_path) { char *ptr = strstr(actual_path, "/firejail"); if (ptr && strlen(ptr) == strlen("/firejail")) { if (arg_debug) printf("firejail exec symlink detected\n"); free(actual_path); free(fname); fname = NULL; i++; continue; } free(actual_path); } } break; // file found } free(fname); fname = NULL; i++; } if (!fname) { if (arg_debug) fprintf(stderr, "Warning: file %s not found\n", name); return NULL; } free(fname); return paths[i]; }
int check_room(t_lem_env *env, char *s) { if (is_link(s) && env->fonction[env->r.state + 1](env, s)) return (ft_add_state(env)); if (ft_strcmp("##start", s) == 0 && check_start(env, s)) return (1); if (ft_strcmp("##end", s) == 0 && check_end(env, s)) return (1); if (is_room(s) && add_room(env, s)) { env->r.nbline += add_file(env, s); return (1); } return (ft_error(env, 1)); }
void fs_var_tmp(void) { struct stat s; if (stat("/var/tmp", &s) == 0) { if (!is_link("/var/tmp")) { if (arg_debug) printf("Mounting tmpfs on /var/tmp\n"); if (mount("tmpfs", "/var/tmp", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=1777,gid=0") < 0) errExit("mounting /var/tmp"); fs_logger("tmpfs /var/tmp"); } } else { fwarning("/var/tmp not mounted\n"); dbg_test_dir("/var/tmp"); } }
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); }
void jumpTableEntry::verify() { if (is_unused()) { // Nothing to check in an unused entry return; } if (is_nmethod_stub()) { // Check nmethod char* addr = destination(); if (!Universe::code->contains(addr)) report_verify_error("nmethod not in zone"); if (method()->entryPoint() != addr) report_verify_error("destination doesn't point to beginning of nmethod"); return; } if (is_link()) { // Verify the elements in the list {nmethod} {block_closure}+ jumpTableEntry* head = jumpTable::jump_entry_for_at(link(), 0); if (!head->is_nmethod_stub()) report_verify_error("must be nmethod stub"); head->verify(); nmethod* nm = method(); if (!nm->has_noninlined_blocks()) report_verify_error("nmethod must have noninlined blocks"); for (int index = 1; index <= nm->number_of_noninlined_blocks(); index++) { jumpTableEntry* son = jumpTable::jump_entry_for_at(link(), index); if (!son->is_block_closure_stub()) report_verify_error("must be block closure stub"); son->verify(); } return; } if (is_block_closure_stub()) { char* addr = destination(); if (!Universe::code->contains(addr)) { if (addr != StubRoutines::compile_block_entry()) report_verify_error("destination points neither into zone nor to compile stub"); } else { nmethod* nm = block_nmethod(); if (nm->entryPoint() != addr) report_verify_error("destination doesn't point to beginning of nmethod"); } return; } report_verify_error("invalid state"); }
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); }