static void sandbox_setup_base() { /* Simple reads and writes on existing descriptors. */ allow_nr(__NR_read); allow_nr(__NR_write); /* Needed for memory management. */ allow_nr_2_arg_match(__NR_mmap, 3, PROT_READ|PROT_WRITE, 4, MAP_PRIVATE|MAP_ANON); allow_nr_1_arg_mask(__NR_mprotect, 3, PROT_READ); allow_nr(__NR_munmap); allow_nr(__NR_brk); /* glibc falls back gracefully if mremap() fails during realloc(). */ reject_nr(__NR_mremap, ENOSYS); /* Misc simple low-risk calls. */ allow_nr(__NR_rt_sigreturn); /* Used to handle SIGPIPE. */ allow_nr(__NR_restart_syscall); allow_nr(__NR_close); /* Always need to be able to exit ! */ allow_nr(__NR_exit_group); }
void seccomp_sandbox_setup_postlogin(const struct vsf_session* p_sess) { int is_anon = p_sess->is_anonymous; int open_flag = kOpenFlags; if (tunable_write_enable) { open_flag |= O_ACCMODE; } /* Put lstat() first because it is a very hot syscall for large directory * listings. And the current BPF only allows a linear scan of allowed * syscalls. */ allow_nr(__NR_lstat); /* Allow all the simple pre-login things and then expand upon them. */ seccomp_sandbox_setup_prelogin(p_sess); /* Simple file descriptor-based operations. */ if (tunable_xferlog_enable || tunable_dual_log_enable || tunable_lock_upload_files) { allow_nr_1_arg_match(__NR_fcntl, 2, F_SETLKW); allow_nr_1_arg_match(__NR_fcntl, 2, F_SETLK); } if (tunable_async_abor_enable) { allow_nr_2_arg_match(__NR_fcntl, 2, F_SETOWN, 3, vsf_sysutil_getpid()); } allow_nr_2_arg_match(__NR_setsockopt, 2, SOL_SOCKET, 3, SO_KEEPALIVE); allow_nr_2_arg_match(__NR_setsockopt, 2, SOL_SOCKET, 3, SO_LINGER); allow_nr_2_arg_match(__NR_setsockopt, 2, IPPROTO_IP, 3, IP_TOS); allow_nr(__NR_fstat); allow_nr(__NR_lseek); /* Since we use chroot() to restrict filesystem access, we can just blanket * allow open(). */ allow_nr_1_arg_mask(__NR_open, 2, open_flag); allow_nr_1_arg_mask(__NR_openat, 3, open_flag); /* Other pathname-based metadata queries. */ allow_nr(__NR_stat); allow_nr(__NR_readlink); /* Directory handling: query, change, read. */ allow_nr(__NR_getcwd); allow_nr(__NR_chdir); allow_nr(__NR_getdents); /* Misc */ allow_nr(__NR_umask); /* Config-dependent items follow. */ if (tunable_use_sendfile) { allow_nr(__NR_sendfile); } if (tunable_idle_session_timeout > 0 || tunable_data_connection_timeout > 0 || tunable_async_abor_enable) { allow_nr(__NR_rt_sigaction); } if (tunable_idle_session_timeout > 0 || tunable_data_connection_timeout > 0) { allow_nr(__NR_alarm); } if (tunable_one_process_model) { seccomp_sandbox_setup_data_connections(); if (is_anon && tunable_chown_uploads) { allow_nr(__NR_fchmod); allow_nr(__NR_fchown); } } else { /* Need to receieve file descriptors from privileged broker. */ allow_nr_1_arg_match(__NR_recvmsg, 3, 0); if ((is_anon && tunable_chown_uploads) || tunable_ssl_enable) { /* Need to send file descriptors to privileged broker. */ allow_nr_1_arg_match(__NR_sendmsg, 3, 0); } } if (tunable_syslog_enable) { /* The ability to pass an address spec isn't needed so disable it. We ensure * the 6th arg (socklen) is 0. We could have checked the 5th arg (sockptr) * but I don't know if 64-bit compares work in the kernel filter, so we're * happy to check the socklen arg, which is 32 bits. */ allow_nr_1_arg_match(__NR_sendto, 6, 0); } if (tunable_text_userdb_names) { reject_nr(__NR_socket, EACCES); allow_nr_2_arg_match(__NR_mmap, 3, PROT_READ, 4, MAP_SHARED); } if (tunable_write_enable) { if (!is_anon || tunable_anon_mkdir_write_enable) { allow_nr(__NR_mkdir); } if (!is_anon || tunable_anon_other_write_enable || tunable_delete_failed_uploads) { allow_nr(__NR_unlink); } if (!is_anon || tunable_anon_other_write_enable) { allow_nr(__NR_rmdir); allow_nr(__NR_rename); allow_nr(__NR_ftruncate); if (tunable_mdtm_write) { allow_nr(__NR_utime); allow_nr(__NR_utimes); } } if (!is_anon && tunable_chmod_enable) { allow_nr(__NR_chmod); } } }