// keep filter for seccomp option int seccomp_filter_keep(void) { filter_init(); // these 4 syscalls are used by firejail after the seccomp filter is initialized filter_add_whitelist(SYS_setuid); filter_add_whitelist(SYS_setgid); filter_add_whitelist(SYS_setgroups); filter_add_whitelist(SYS_dup); // apply keep list if (arg_seccomp_list_keep) { if (syscall_check_list(arg_seccomp_list_keep, filter_add_whitelist)) { exechelp_logerrv("firejail", FIREJAIL_ERROR, "Error: cannot load seccomp filter\n"); exit(1); } } filter_end_whitelist(); if (arg_debug) filter_debug(); // save seccomp filter in /tmp/firejail/mnt/seccomp // in order to use it in --join operations write_seccomp_file(); struct sock_fprog prog = { .len = sfilter_index, .filter = sfilter, }; if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { exechelp_logerrv("firejail", FIREJAIL_WARNING, "Error: seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n"); return 1; } else if (arg_debug) { printf("seccomp enabled\n"); } return 0; }
// errno filter for seccomp option int seccomp_filter_errno(void) { int i; int higest_errno = errno_highest_nr(); filter_init(); // apply errno list for (i = 0; i < higest_errno; i++) { if (cfg.seccomp_list_errno[i]) { if (syscall_check_list(cfg.seccomp_list_errno[i], filter_add_errno, i)) { fprintf(stderr, "Error: cannot load seccomp filter\n"); exit(1); } } } filter_end_blacklist(); if (arg_debug) filter_debug(); // save seccomp filter in /tmp/firejail/mnt/seccomp // in order to use it in --join operations write_seccomp_file(); struct sock_fprog prog = { .len = sfilter_index, .filter = sfilter, }; if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { fprintf(stderr, "Warning: seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n"); return 1; } else if (arg_debug) { printf("seccomp enabled\n"); } return 0; }
// drop filter for seccomp option int seccomp_filter_drop(void) { filter_init(); // default seccomp if (arg_seccomp_list_drop == NULL) { #ifdef SYS_mount filter_add_blacklist(SYS_mount); #endif #ifdef SYS_umount2 filter_add_blacklist(SYS_umount2); #endif #ifdef SYS_ptrace filter_add_blacklist(SYS_ptrace); #endif #ifdef SYS_kexec_load filter_add_blacklist(SYS_kexec_load); #endif #ifdef SYS_open_by_handle_at filter_add_blacklist(SYS_open_by_handle_at); #endif #ifdef SYS_init_module filter_add_blacklist(SYS_init_module); #endif #ifdef SYS_finit_module // introduced in 2013 filter_add_blacklist(SYS_finit_module); #endif #ifdef SYS_delete_module filter_add_blacklist(SYS_delete_module); #endif #ifdef SYS_iopl filter_add_blacklist(SYS_iopl); #endif #ifdef SYS_ioperm filter_add_blacklist(SYS_ioperm); #endif #ifdef SYS_ni_syscall // new io permisions call on arm devices filter_add_blacklist(SYS_ni_syscall); #endif #ifdef SYS_swapon filter_add_blacklist(SYS_swapon); #endif #ifdef SYS_swapoff filter_add_blacklist(SYS_swapoff); #endif #ifdef SYS_syslog filter_add_blacklist(SYS_syslog); #endif #ifdef SYS_process_vm_readv filter_add_blacklist(SYS_process_vm_readv); #endif #ifdef SYS_process_vm_writev filter_add_blacklist(SYS_process_vm_writev); #endif // mknod removed in 0.9.29 //#ifdef SYS_mknod // filter_add_blacklist(SYS_mknod); //#endif // new syscalls in 0.9,23 #ifdef SYS_sysfs filter_add_blacklist(SYS_sysfs); #endif #ifdef SYS__sysctl filter_add_blacklist(SYS__sysctl); #endif #ifdef SYS_adjtimex filter_add_blacklist(SYS_adjtimex); #endif #ifdef SYS_clock_adjtime filter_add_blacklist(SYS_clock_adjtime); #endif #ifdef SYS_lookup_dcookie filter_add_blacklist(SYS_lookup_dcookie); #endif #ifdef SYS_perf_event_open filter_add_blacklist(SYS_perf_event_open); #endif #ifdef SYS_fanotify_init filter_add_blacklist(SYS_fanotify_init); #endif #ifdef SYS_kcmp filter_add_blacklist(SYS_kcmp); #endif } // default seccomp filter with additional drop list if (arg_seccomp_list && arg_seccomp_list_drop == NULL) { if (syscall_check_list(arg_seccomp_list, filter_add_blacklist)) { exechelp_logerrv("firejail", FIREJAIL_ERROR, "Error: cannot load seccomp filter\n"); exit(1); } } // drop list else if (arg_seccomp_list == NULL && arg_seccomp_list_drop) { if (syscall_check_list(arg_seccomp_list_drop, filter_add_blacklist)) { exechelp_logerrv("firejail", FIREJAIL_ERROR, "Error: cannot load seccomp filter\n"); exit(1); } } filter_end_blacklist(); if (arg_debug) filter_debug(); // save seccomp filter in /tmp/firejail/mnt/seccomp // in order to use it in --join operations write_seccomp_file(); struct sock_fprog prog = { .len = sfilter_index, .filter = sfilter, }; if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { exechelp_logerrv("firejail", FIREJAIL_WARNING, "Error: seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n"); return 1; } else if (arg_debug) { printf("seccomp enabled\n"); } return 0; }
// i386 filter installed on amd64 architectures void seccomp_filter_32(void) { // hardcoded syscall values struct sock_filter filter[] = { VALIDATE_ARCHITECTURE_32, EXAMINE_SYSCALL, BLACKLIST(21), // mount BLACKLIST(52), // umount2 BLACKLIST(26), // ptrace BLACKLIST(283), // kexec_load BLACKLIST(342), // open_by_handle_at BLACKLIST(128), // init_module BLACKLIST(350), // finit_module BLACKLIST(129), // delete_module BLACKLIST(110), // iopl BLACKLIST(101), // ioperm BLACKLIST(87), // swapon BLACKLIST(115), // swapoff BLACKLIST(103), // syslog BLACKLIST(347), // process_vm_readv BLACKLIST(348), // process_vm_writev BLACKLIST(135), // sysfs BLACKLIST(149), // _sysctl BLACKLIST(124), // adjtimex BLACKLIST(343), // clock_adjtime BLACKLIST(253), // lookup_dcookie BLACKLIST(336), // perf_event_open BLACKLIST(338), // fanotify_init BLACKLIST(349), // kcmp BLACKLIST(286), // add_key BLACKLIST(287), // request_key BLACKLIST(288), // keyctl BLACKLIST(86), // uselib BLACKLIST(51), // acct BLACKLIST(123), // modify_ldt BLACKLIST(217), // pivot_root BLACKLIST(245), // io_setup BLACKLIST(246), // io_destroy BLACKLIST(247), // io_getevents BLACKLIST(248), // io_submit BLACKLIST(249), // io_cancel BLACKLIST(257), // remap_file_pages BLACKLIST(274), // mbind BLACKLIST(275), // get_mempolicy BLACKLIST(276), // set_mempolicy BLACKLIST(294), // migrate_pages BLACKLIST(317), // move_pages BLACKLIST(316), // vmsplice BLACKLIST(61), // chroot BLACKLIST(88), // reboot BLACKLIST(169), // nfsservctl BLACKLIST(130), // get_kernel_syms RETURN_ALLOW }; struct sock_fprog prog = { .len = (unsigned short)(sizeof(filter) / sizeof(filter[0])), .filter = filter, }; if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { ; } else if (arg_debug) { printf("Dual i386/amd64 seccomp filter configured\n"); } } // amd64 filter installed on i386 architectures void seccomp_filter_64(void) { // hardcoded syscall values struct sock_filter filter[] = { VALIDATE_ARCHITECTURE_64, EXAMINE_SYSCALL, BLACKLIST(165), // mount BLACKLIST(166), // umount2 BLACKLIST(101), // ptrace BLACKLIST(246), // kexec_load BLACKLIST(304), // open_by_handle_at BLACKLIST(175), // init_module BLACKLIST(313), // finit_module BLACKLIST(176), // delete_module BLACKLIST(172), // iopl BLACKLIST(173), // ioperm BLACKLIST(167), // swapon BLACKLIST(168), // swapoff BLACKLIST(103), // syslog BLACKLIST(310), // process_vm_readv BLACKLIST(311), // process_vm_writev BLACKLIST(139), // sysfs BLACKLIST(156), // _sysctl BLACKLIST(159), // adjtimex BLACKLIST(305), // clock_adjtime BLACKLIST(212), // lookup_dcookie BLACKLIST(298), // perf_event_open BLACKLIST(300), // fanotify_init BLACKLIST(312), // kcmp BLACKLIST(248), // add_key BLACKLIST(249), // request_key BLACKLIST(250), // keyctl BLACKLIST(134), // uselib BLACKLIST(163), // acct BLACKLIST(154), // modify_ldt BLACKLIST(155), // pivot_root BLACKLIST(206), // io_setup BLACKLIST(207), // io_destroy BLACKLIST(208), // io_getevents BLACKLIST(209), // io_submit BLACKLIST(210), // io_cancel BLACKLIST(216), // remap_file_pages BLACKLIST(237), // mbind BLACKLIST(239), // get_mempolicy BLACKLIST(238), // set_mempolicy BLACKLIST(256), // migrate_pages BLACKLIST(279), // move_pages BLACKLIST(278), // vmsplice BLACKLIST(161), // chroot BLACKLIST(184), // tuxcall BLACKLIST(169), // reboot BLACKLIST(180), // nfsservctl BLACKLIST(177), // get_kernel_syms RETURN_ALLOW }; struct sock_fprog prog = { .len = (unsigned short)(sizeof(filter) / sizeof(filter[0])), .filter = filter, }; if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { ; } else if (arg_debug) { printf("Dual i386/amd64 seccomp filter configured\n"); } } // drop filter for seccomp option int seccomp_filter_drop(int enforce_seccomp) { filter_init(); // default seccomp if (cfg.seccomp_list_drop == NULL) { #if defined(__x86_64__) seccomp_filter_32(); #endif #if defined(__i386__) seccomp_filter_64(); #endif #ifdef SYS_mount filter_add_blacklist(SYS_mount, 0); #endif #ifdef SYS_umount2 filter_add_blacklist(SYS_umount2, 0); #endif #ifdef SYS_ptrace filter_add_blacklist(SYS_ptrace, 0); #endif #ifdef SYS_kexec_load filter_add_blacklist(SYS_kexec_load, 0); #endif #ifdef SYS_kexec_file_load filter_add_blacklist(SYS_kexec_file_load, 0); #endif #ifdef SYS_open_by_handle_at filter_add_blacklist(SYS_open_by_handle_at, 0); #endif #ifdef SYS_init_module filter_add_blacklist(SYS_init_module, 0); #endif #ifdef SYS_finit_module // introduced in 2013 filter_add_blacklist(SYS_finit_module, 0); #endif #ifdef SYS_delete_module filter_add_blacklist(SYS_delete_module, 0); #endif #ifdef SYS_iopl filter_add_blacklist(SYS_iopl, 0); #endif #ifdef SYS_ioperm filter_add_blacklist(SYS_ioperm, 0); #endif #ifdef SYS_ni_syscall // new io permissions call on arm devices filter_add_blacklist(SYS_ni_syscall, 0); #endif #ifdef SYS_swapon filter_add_blacklist(SYS_swapon, 0); #endif #ifdef SYS_swapoff filter_add_blacklist(SYS_swapoff, 0); #endif #ifdef SYS_syslog filter_add_blacklist(SYS_syslog, 0); #endif #ifdef SYS_process_vm_readv filter_add_blacklist(SYS_process_vm_readv, 0); #endif #ifdef SYS_process_vm_writev filter_add_blacklist(SYS_process_vm_writev, 0); #endif // mknod removed in 0.9.29 - it brakes Zotero extension //#ifdef SYS_mknod // filter_add_blacklist(SYS_mknod, 0); //#endif // new syscalls in 0.9,23 #ifdef SYS_sysfs filter_add_blacklist(SYS_sysfs, 0); #endif #ifdef SYS__sysctl filter_add_blacklist(SYS__sysctl, 0); #endif #ifdef SYS_adjtimex filter_add_blacklist(SYS_adjtimex, 0); #endif #ifdef SYS_clock_adjtime filter_add_blacklist(SYS_clock_adjtime, 0); #endif #ifdef SYS_lookup_dcookie filter_add_blacklist(SYS_lookup_dcookie, 0); #endif #ifdef SYS_perf_event_open filter_add_blacklist(SYS_perf_event_open, 0); #endif #ifdef SYS_fanotify_init filter_add_blacklist(SYS_fanotify_init, 0); #endif #ifdef SYS_kcmp filter_add_blacklist(SYS_kcmp, 0); #endif // 0.9.32 #ifdef SYS_add_key filter_add_blacklist(SYS_add_key, 0); #endif #ifdef SYS_request_key filter_add_blacklist(SYS_request_key, 0); #endif #ifdef SYS_keyctl filter_add_blacklist(SYS_keyctl, 0); #endif #ifdef SYS_uselib filter_add_blacklist(SYS_uselib, 0); #endif #ifdef SYS_acct filter_add_blacklist(SYS_acct, 0); #endif #ifdef SYS_modify_ldt filter_add_blacklist(SYS_modify_ldt, 0); #endif //#ifdef SYS_unshare // filter_add_blacklist(SYS_unshare, 0); //#endif #ifdef SYS_pivot_root filter_add_blacklist(SYS_pivot_root, 0); #endif //#ifdef SYS_quotactl // filter_add_blacklist(SYS_quotactl, 0); //#endif #ifdef SYS_io_setup filter_add_blacklist(SYS_io_setup, 0); #endif #ifdef SYS_io_destroy filter_add_blacklist(SYS_io_destroy, 0); #endif #ifdef SYS_io_getevents filter_add_blacklist(SYS_io_getevents, 0); #endif #ifdef SYS_io_submit filter_add_blacklist(SYS_io_submit, 0); #endif #ifdef SYS_io_cancel filter_add_blacklist(SYS_io_cancel, 0); #endif #ifdef SYS_remap_file_pages filter_add_blacklist(SYS_remap_file_pages, 0); #endif #ifdef SYS_mbind filter_add_blacklist(SYS_mbind, 0); #endif #ifdef SYS_get_mempolicy filter_add_blacklist(SYS_get_mempolicy, 0); #endif #ifdef SYS_set_mempolicy filter_add_blacklist(SYS_set_mempolicy, 0); #endif #ifdef SYS_migrate_pages filter_add_blacklist(SYS_migrate_pages, 0); #endif #ifdef SYS_move_pages filter_add_blacklist(SYS_move_pages, 0); #endif #ifdef SYS_vmsplice filter_add_blacklist(SYS_vmsplice, 0); #endif #ifdef SYS_chroot filter_add_blacklist(SYS_chroot, 0); #endif //#ifdef SYS_set_robust_list // filter_add_blacklist(SYS_set_robust_list, 0); //#endif //#ifdef SYS_get_robust_list // filter_add_blacklist(SYS_get_robust_list, 0); //#endif // CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(clone), 1, // SCMP_A0(SCMP_CMP_MASKED_EQ, CLONE_NEWUSER, CLONE_NEWUSER))); // 0.9.39 #ifdef SYS_tuxcall filter_add_blacklist(SYS_tuxcall, 0); #endif #ifdef SYS_reboot filter_add_blacklist(SYS_reboot, 0); #endif #ifdef SYS_nfsservctl filter_add_blacklist(SYS_nfsservctl, 0); #endif #ifdef SYS_get_kernel_syms filter_add_blacklist(SYS_get_kernel_syms, 0); #endif } // default seccomp filter with additional drop list if (cfg.seccomp_list && cfg.seccomp_list_drop == NULL) { if (syscall_check_list(cfg.seccomp_list, filter_add_blacklist, 0)) { fprintf(stderr, "Error: cannot load seccomp filter\n"); exit(1); } } // drop list else if (cfg.seccomp_list == NULL && cfg.seccomp_list_drop) { if (syscall_check_list(cfg.seccomp_list_drop, filter_add_blacklist, 0)) { fprintf(stderr, "Error: cannot load seccomp filter\n"); exit(1); } } filter_end_blacklist(); if (arg_debug) filter_debug(); // save seccomp filter in /tmp/firejail/mnt/seccomp // in order to use it in --join operations write_seccomp_file(); struct sock_fprog prog = { .len = sfilter_index, .filter = sfilter, }; if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { if (enforce_seccomp) { fprintf(stderr, "Error: a seccomp-enabled Linux kernel is required, exiting...\n"); exit(1); } else fprintf(stderr, "Warning: seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n"); return 1; } return 0; } // keep filter for seccomp option int seccomp_filter_keep(void) { filter_init(); // these 4 syscalls are used by firejail after the seccomp filter is initialized filter_add_whitelist(SYS_setuid, 0); filter_add_whitelist(SYS_setgid, 0); filter_add_whitelist(SYS_setgroups, 0); filter_add_whitelist(SYS_dup, 0); // apply keep list if (cfg.seccomp_list_keep) { if (syscall_check_list(cfg.seccomp_list_keep, filter_add_whitelist, 0)) { fprintf(stderr, "Error: cannot load seccomp filter\n"); exit(1); } } filter_end_whitelist(); if (arg_debug) filter_debug(); // save seccomp filter in /tmp/firejail/mnt/seccomp // in order to use it in --join operations write_seccomp_file(); struct sock_fprog prog = { .len = sfilter_index, .filter = sfilter, }; if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { fprintf(stderr, "Warning: seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n"); return 1; } else if (arg_debug) { printf("seccomp enabled\n"); } return 0; }
// drop filter for seccomp option int seccomp_filter_drop(void) { filter_init(); // default seccomp if (arg_seccomp_list_drop == NULL) { filter_add_blacklist(SYS_mount); filter_add_blacklist(SYS_umount2); filter_add_blacklist(SYS_ptrace); filter_add_blacklist(SYS_kexec_load); filter_add_blacklist(SYS_open_by_handle_at); filter_add_blacklist(SYS_init_module); #ifdef SYS_finit_module // introduced in 2013 filter_add_blacklist(SYS_finit_module); #endif filter_add_blacklist(SYS_delete_module); filter_add_blacklist(SYS_iopl); filter_add_blacklist(SYS_ioperm); filter_add_blacklist(SYS_swapon); filter_add_blacklist(SYS_swapoff); filter_add_blacklist(SYS_syslog); filter_add_blacklist(SYS_process_vm_readv); filter_add_blacklist(SYS_process_vm_writev); filter_add_blacklist(SYS_mknod); // new syscalls in 0.9,23 filter_add_blacklist(SYS_sysfs); filter_add_blacklist(SYS__sysctl); filter_add_blacklist(SYS_adjtimex); filter_add_blacklist(SYS_clock_adjtime); filter_add_blacklist(SYS_lookup_dcookie); filter_add_blacklist(SYS_perf_event_open); filter_add_blacklist(SYS_fanotify_init); #ifdef SYS_kcmp // todo: check it on newer distros; it is not in Debian 7 filter_add_blacklist(SYS_kcmp); #endif } // default seccomp filter with additional drop list if (arg_seccomp_list && arg_seccomp_list_drop == NULL) { if (syscall_check_list(arg_seccomp_list, filter_add_blacklist)) { fprintf(stderr, "Error: cannot load seccomp filter\n"); exit(1); } } // drop list else if (arg_seccomp_list == NULL && arg_seccomp_list_drop) { if (syscall_check_list(arg_seccomp_list_drop, filter_add_blacklist)) { fprintf(stderr, "Error: cannot load seccomp filter\n"); exit(1); } } filter_end_blacklist(); if (arg_debug) filter_debug(); // save seccomp filter in /tmp/firejail/mnt/seccomp // in order to use it in --join operations write_seccomp_file(); struct sock_fprog prog = { .len = sfilter_index, .filter = sfilter, }; if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { fprintf(stderr, "Warning: seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n"); return 1; } else if (arg_debug) { printf("seccomp enabled\n"); } return 0; }
// check profile line; if line == 0, this was generated from a command line option // return 1 if the command is to be added to the linked list of profile commands // return 0 if the command was already executed inside the function int profile_check_line(char *ptr, int lineno) { // seccomp, caps, private if (strcmp(ptr, "seccomp") == 0) { arg_seccomp = 1; return 0; } else if (strcmp(ptr, "caps") == 0) { arg_caps = 1; return 0; } else if (strcmp(ptr, "private") == 0) { arg_private = 1; return 0; } // seccomp list if (strncmp(ptr, "seccomp ", 8) == 0) { arg_seccomp = 1; #ifdef HAVE_SECCOMP arg_seccomp_list = strdup(ptr + 8); if (!arg_seccomp_list) errExit("strdup"); // verify seccomp list and exit if problems if (syscall_check_list(arg_seccomp_list, NULL)) exit(1); #endif return 0; } // private directory if (strncmp(ptr, "private ", 8) == 0) { cfg.home_private = ptr + 8; check_private_dir(); arg_private = 1; return 0; } // filesystem bind if (strncmp(ptr, "bind ", 5) == 0) { if (getuid() != 0) { fprintf(stderr, "Error: --bind option is available only if running as root\n"); exit(1); } // extract two directories char *dname1 = ptr + 5; char *dname2 = split_comma(dname1); // this inserts a '0 to separate the two dierctories if (dname2 == NULL) { fprintf(stderr, "Error: mising second directory for bind\n"); exit(1); } // check directories check_file_name(dname1, lineno); check_file_name(dname2, lineno); // insert comma back *(dname2 - 1) = ','; return 1; } // rlimit if (strncmp(ptr, "rlimit", 6) == 0) { if (strncmp(ptr, "rlimit-nofile ", 14) == 0) { ptr += 14; if (not_unsigned(ptr)) { fprintf(stderr, "Invalid rlimit option on line %d\n", lineno); exit(1); } sscanf(ptr, "%u", &cfg.rlimit_nofile); arg_rlimit_nofile = 1; } else if (strncmp(ptr, "rlimit-nproc ", 13) == 0) { ptr += 13; if (not_unsigned(ptr)) { fprintf(stderr, "Invalid rlimit option on line %d\n", lineno); exit(1); } sscanf(ptr, "%u", &cfg.rlimit_nproc); arg_rlimit_nproc = 1; } else if (strncmp(ptr, "rlimit-fsize ", 13) == 0) { ptr += 13; if (not_unsigned(ptr)) { fprintf(stderr, "Invalid rlimit option on line %d\n", lineno); exit(1); } sscanf(ptr, "%u", &cfg.rlimit_fsize); arg_rlimit_fsize = 1; } else if (strncmp(ptr, "rlimit-sigpending ", 18) == 0) { ptr += 18; if (not_unsigned(ptr)) { fprintf(stderr, "Invalid rlimit option on line %d\n", lineno); exit(1); } sscanf(ptr, "%u", &cfg.rlimit_sigpending); arg_rlimit_sigpending = 1; } else { fprintf(stderr, "Invalid rlimit option on line %d\n", lineno); exit(1); } return 0; } // rest of filesystem if (strncmp(ptr, "blacklist ", 10) == 0) ptr += 10; else if (strncmp(ptr, "read-only ", 10) == 0) ptr += 10; else if (strncmp(ptr, "tmpfs ", 6) == 0) ptr += 6; else { if (lineno == 0) fprintf(stderr, "Error: \"%s\" as a command line option is invalid\n", ptr); else fprintf(stderr, "Error: line %d in the custom profile is invalid\n", lineno); exit(1); } // some characters just don't belong in filenames check_file_name(ptr, lineno); return 1; }