static void seccomp_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_gettimeofday); /* Used by logging. */ 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); if (tunable_mysql_enable) { allow_nr_2_arg_match(__NR_mmap, 3, PROT_READ|PROT_WRITE, 4, MAP_PRIVATE|MAP_ANONYMOUS); allow_nr_1_arg_match(__NR_futex, 2, FUTEX_WAKE_PRIVATE); allow_nr_1_arg_match(__NR_futex, 2, FUTEX_WAKE); allow_nr(__NR_poll); } }
static void seccomp_sandbox_setup_data_connections() { allow_nr_3_arg_match(__NR_socket, 1, PF_INET, 2, SOCK_STREAM, 3, IPPROTO_TCP); allow_nr_3_arg_match(__NR_socket, 1, PF_INET6, 2, SOCK_STREAM, 3, IPPROTO_TCP); allow_nr(__NR_bind); allow_nr(__NR_select); if (tunable_port_enable) { allow_nr(__NR_connect); allow_nr_2_arg_match(__NR_getsockopt, 2, SOL_SOCKET, 3, SO_ERROR); allow_nr_2_arg_match(__NR_setsockopt, 2, SOL_SOCKET, 3, SO_REUSEADDR); allow_nr_1_arg_match(__NR_fcntl, 2, F_GETFL); allow_nr_2_arg_match(__NR_fcntl, 2, F_SETFL, 3, O_RDWR|O_NONBLOCK); allow_nr_2_arg_match(__NR_fcntl, 2, F_SETFL, 3, O_RDWR); } if (tunable_pasv_enable) { allow_nr(__NR_listen); allow_nr(__NR_accept); } }
void sandbox_setup() { sandbox_setup_base(); sandbox_setup_data_connections(); /* Misc simple low-risk calls */ allow_nr(__NR_nanosleep); /* Used for bandwidth / login throttling. */ allow_nr(__NR_getpid); /* Used by logging. */ allow_nr(__NR_shutdown); /* Used for QUIT or a timeout. */ allow_nr_1_arg_match(__NR_fcntl, 2, F_GETFL); /* It's safe to allow O_RDWR in fcntl because these flags cannot be changed. * Also, sockets are O_RDWR. */ allow_nr_2_arg_mask_match(__NR_fcntl, 3, kOpenFlags|O_ACCMODE, 2, F_SETFL); return; }
void seccomp_sandbox_setup_prelogin(const struct vsf_session* p_sess) { (void) p_sess; seccomp_sandbox_setup_base(); /* Peeking FTP commands from the network. */ allow_nr_1_arg_match(__NR_recvfrom, 4, MSG_PEEK); /* Misc simple low-risk calls */ allow_nr(__NR_nanosleep); /* Used for bandwidth / login throttling. */ allow_nr(__NR_getpid); /* Used by logging. */ allow_nr(__NR_shutdown); /* Used for QUIT or a timeout. */ allow_nr_1_arg_match(__NR_fcntl, 2, F_GETFL); /* It's safe to allow O_RDWR in fcntl because these flags cannot be changed. * Also, sockets are O_RDWR. */ allow_nr_2_arg_mask_match(__NR_fcntl, 3, kOpenFlags|O_ACCMODE, 2, F_SETFL); /* Config-dependent items follow. */ if (tunable_idle_session_timeout > 0) { allow_nr(__NR_rt_sigaction); allow_nr(__NR_alarm); } if (tunable_xferlog_enable || tunable_dual_log_enable) { /* For file locking. */ allow_nr_1_arg_match(__NR_fcntl, 2, F_SETLKW); allow_nr_1_arg_match(__NR_fcntl, 2, F_SETLK); } if (tunable_ssl_enable) { allow_nr_1_arg_match(__NR_recvmsg, 3, 0); allow_nr_2_arg_match(__NR_setsockopt, 2, IPPROTO_TCP, 3, TCP_NODELAY); } if (tunable_syslog_enable) { reject_nr(__NR_socket, EACCES); } }
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); } } }