blob: 0b6ff5fda4339168e3e634835e4d38b56e00145d [file] [log] [blame]
/*
* Chromium OS alt-syscall tables
*
* Copyright (C) 2015 Google, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/alt-syscall.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/prctl.h>
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/syscalls.h>
#include <asm/unistd.h>
struct syscall_whitelist_entry {
unsigned int nr;
sys_call_ptr_t alt;
};
struct syscall_whitelist {
const char *name;
const struct syscall_whitelist_entry *whitelist;
unsigned int nr_whitelist;
#ifdef CONFIG_COMPAT
const struct syscall_whitelist_entry *compat_whitelist;
unsigned int nr_compat_whitelist;
#endif
bool permissive;
};
static struct alt_sys_call_table default_table;
/* Intercept and log blocked syscalls. */
static asmlinkage long block_syscall(void)
{
struct task_struct *task = current;
struct pt_regs *regs = task_pt_regs(task);
pr_warn("[%d] %s: blocked syscall %d\n", task_pid_nr(task),
task->comm, syscall_get_nr(task, regs));
return -ENOSYS;
}
typedef asmlinkage long (*raw_sys_call_ptr_t)(unsigned long, unsigned long,
unsigned long, unsigned long,
unsigned long, unsigned long);
/*
* In permissive mode, warn that the syscall was blocked, but still allow
* it to go through. Note that since we don't have an easy way to map from
* syscall to number of arguments, we pass the maximum (6).
*/
static long do_syscall(raw_sys_call_ptr_t fn)
{
struct task_struct *task = current;
struct pt_regs *regs = task_pt_regs(task);
unsigned long args[6];
syscall_get_arguments(task, regs, 0, ARRAY_SIZE(args), args);
return fn(args[0], args[1], args[2], args[3], args[4], args[5]);
}
static asmlinkage long warn_syscall(void)
{
struct task_struct *task = current;
struct pt_regs *regs = task_pt_regs(task);
int nr = syscall_get_nr(task, regs);
raw_sys_call_ptr_t fn = (raw_sys_call_ptr_t)default_table.table[nr];
pr_warn_ratelimited("[%d] %s: syscall %d not whitelisted\n",
task_pid_nr(task), task->comm, nr);
return do_syscall(fn);
}
#ifdef CONFIG_COMPAT
static asmlinkage long warn_compat_syscall(void)
{
struct task_struct *task = current;
struct pt_regs *regs = task_pt_regs(task);
int nr = syscall_get_nr(task, regs);
raw_sys_call_ptr_t fn = (raw_sys_call_ptr_t)default_table.compat_table[nr];
pr_warn_ratelimited("[%d] %s: compat syscall %d not whitelisted\n",
task_pid_nr(task), task->comm, nr);
return do_syscall(fn);
}
#endif
/*
* If an alt_syscall table allows prctl(), override it to prevent a process
* from changing its syscall table.
*/
static asmlinkage long alt_sys_prctl(int option, unsigned long arg2,
unsigned long arg3, unsigned long arg4,
unsigned long arg5)
{
if (option == PR_ALT_SYSCALL &&
arg2 == PR_ALT_SYSCALL_SET_SYSCALL_TABLE)
return -EPERM;
return sys_prctl(option, arg2, arg3, arg4, arg5);
}
#ifdef CONFIG_COMPAT
#define SYSCALL_WHITELIST_COMPAT(x) \
.compat_whitelist = x ## _compat_whitelist, \
.nr_compat_whitelist = ARRAY_SIZE(x ## _compat_whitelist),
#else
#define SYSCALL_WHITELIST_COMPAT(x)
#endif
#define SYSCALL_WHITELIST(x) \
{ \
.name = #x, \
.whitelist = x ## _whitelist, \
.nr_whitelist = ARRAY_SIZE(x ## _whitelist), \
SYSCALL_WHITELIST_COMPAT(x) \
}
#define PERMISSIVE_SYSCALL_WHITELIST(x) \
{ \
.name = #x "_permissive", \
.permissive = true, \
.whitelist = x ## _whitelist, \
.nr_whitelist = ARRAY_SIZE(x ## _whitelist), \
SYSCALL_WHITELIST_COMPAT(x) \
}
#ifdef CONFIG_COMPAT
#ifdef CONFIG_X86_64
#define __NR_compat_access __NR_ia32_access
#define __NR_compat_brk __NR_ia32_brk
#define __NR_compat_capget __NR_ia32_capget
#define __NR_compat_capset __NR_ia32_capset
#define __NR_compat_chdir __NR_ia32_chdir
#define __NR_compat_chmod __NR_ia32_chmod
#define __NR_compat_clock_gettime __NR_ia32_clock_gettime
#define __NR_compat_clock_getres __NR_ia32_clock_getres
#define __NR_compat_clock_nanosleep __NR_ia32_clock_nanosleep
#define __NR_compat_clock_settime __NR_ia32_clock_settime
#define __NR_compat_clone __NR_ia32_clone
#define __NR_compat_close __NR_ia32_close
#define __NR_compat_creat __NR_ia32_creat
#define __NR_compat_dup __NR_ia32_dup
#define __NR_compat_dup2 __NR_ia32_dup2
#define __NR_compat_dup3 __NR_ia32_dup3
#define __NR_compat_epoll_create __NR_ia32_epoll_create
#define __NR_compat_epoll_create1 __NR_ia32_epoll_create1
#define __NR_compat_epoll_ctl __NR_ia32_epoll_ctl
#define __NR_compat_epoll_wait __NR_ia32_epoll_wait
#define __NR_compat_epoll_pwait __NR_ia32_epoll_pwait
#define __NR_compat_eventfd __NR_ia32_eventfd
#define __NR_compat_eventfd2 __NR_ia32_eventfd2
#define __NR_compat_execve __NR_ia32_execve
#define __NR_compat_exit __NR_ia32_exit
#define __NR_compat_exit_group __NR_ia32_exit_group
#define __NR_compat_faccessat __NR_ia32_faccessat
#define __NR_compat_fallocate __NR_ia32_fallocate
#define __NR_compat_fchdir __NR_ia32_fchdir
#define __NR_compat_fchmod __NR_ia32_fchmod
#define __NR_compat_fchmodat __NR_ia32_fchmodat
#define __NR_compat_fchown __NR_ia32_fchown
#define __NR_compat_fchownat __NR_ia32_fchownat
#define __NR_compat_fcntl __NR_ia32_fcntl
#define __NR_compat_fdatasync __NR_ia32_fdatasync
#define __NR_compat_fgetxattr __NR_ia32_fgetxattr
#define __NR_compat_flistxattr __NR_ia32_flistxattr
#define __NR_compat_flock __NR_ia32_flock
#define __NR_compat_fork __NR_ia32_fork
#define __NR_compat_fremovexattr __NR_ia32_fremovexattr
#define __NR_compat_fsetxattr __NR_ia32_fsetxattr
#define __NR_compat_fstat __NR_ia32_fstat
#define __NR_compat_fstatfs __NR_ia32_fstatfs
#define __NR_compat_fsync __NR_ia32_fsync
#define __NR_compat_ftruncate __NR_ia32_ftruncate
#define __NR_compat_futex __NR_ia32_futex
#define __NR_compat_futimesat __NR_ia32_futimesat
#define __NR_compat_getcwd __NR_ia32_getcwd
#define __NR_compat_getdents __NR_ia32_getdents
#define __NR_compat_getdents64 __NR_ia32_getdents64
#define __NR_compat_getegid __NR_ia32_getegid
#define __NR_compat_geteuid __NR_ia32_geteuid
#define __NR_compat_getgid __NR_ia32_getgid
#define __NR_compat_getgroups32 __NR_ia32_getgroups32
#define __NR_compat_getpgid __NR_ia32_getpgid
#define __NR_compat_getpgrp __NR_ia32_getpgrp
#define __NR_compat_getpid __NR_ia32_getpid
#define __NR_compat_getppid __NR_ia32_getppid
#define __NR_compat_getpriority __NR_ia32_getpriority
#define __NR_compat_getrlimit __NR_ia32_getrlimit
#define __NR_compat_getrusage __NR_ia32_getrusage
#define __NR_compat_getsid __NR_ia32_getsid
#define __NR_compat_gettid __NR_ia32_gettid
#define __NR_compat_gettimeofday __NR_ia32_gettimeofday
#define __NR_compat_getuid __NR_ia32_getuid
#define __NR_compat_getxattr __NR_ia32_getxattr
#define __NR_compat_inotify_add_watch __NR_ia32_inotify_add_watch
#define __NR_compat_inotify_init __NR_ia32_inotify_init
#define __NR_compat_inotify_init1 __NR_ia32_inotify_init1
#define __NR_compat_inotify_rm_watch __NR_ia32_inotify_rm_watch
#define __NR_compat_ioctl __NR_ia32_ioctl
#define __NR_compat_ioprio_set __NR_ia32_ioprio_set
#define __NR_compat_kill __NR_ia32_kill
#define __NR_compat_lgetxattr __NR_ia32_lgetxattr
#define __NR_compat_link __NR_ia32_link
#define __NR_compat_linkat __NR_ia32_linkat
#define __NR_compat_listxattr __NR_ia32_listxattr
#define __NR_compat_llistxattr __NR_ia32_llistxattr
#define __NR_compat_lremovexattr __NR_ia32_lremovexattr
#define __NR_compat_lseek __NR_ia32_lseek
#define __NR_compat_lsetxattr __NR_ia32_lsetxattr
#define __NR_compat_lstat __NR_ia32_lstat
#define __NR_compat_madvise __NR_ia32_madvise
#define __NR_compat_mincore __NR_ia32_mincore
#define __NR_compat_mkdir __NR_ia32_mkdir
#define __NR_compat_mkdirat __NR_ia32_mkdirat
#define __NR_compat_mknod __NR_ia32_mknod
#define __NR_compat_mknodat __NR_ia32_mknodat
#define __NR_compat_mlock __NR_ia32_mlock
#define __NR_compat_munlock __NR_ia32_munlock
#define __NR_compat_mlockall __NR_ia32_mlockall
#define __NR_compat_munlockall __NR_ia32_munlockall
#define __NR_compat_modify_ldt __NR_ia32_modify_ldt
#define __NR_compat_mount __NR_ia32_mount
#define __NR_compat_mprotect __NR_ia32_mprotect
#define __NR_compat_mremap __NR_ia32_mremap
#define __NR_compat_msync __NR_ia32_msync
#define __NR_compat_munmap __NR_ia32_munmap
#define __NR_compat_name_to_handle_at __NR_ia32_name_to_handle_at
#define __NR_compat_nanosleep __NR_ia32_nanosleep
#define __NR_compat_open __NR_ia32_open
#define __NR_compat_open_by_handle_at __NR_ia32_open_by_handle_at
#define __NR_compat_openat __NR_ia32_openat
#define __NR_compat_personality __NR_ia32_personality
#define __NR_compat_pipe __NR_ia32_pipe
#define __NR_compat_pipe2 __NR_ia32_pipe2
#define __NR_compat_poll __NR_ia32_poll
#define __NR_compat_ppoll __NR_ia32_ppoll
#define __NR_compat_prctl __NR_ia32_prctl
#define __NR_compat_pread64 __NR_ia32_pread64
#define __NR_compat_preadv __NR_ia32_preadv
#define __NR_compat_prlimit64 __NR_ia32_prlimit64
#define __NR_compat_process_vm_readv __NR_ia32_process_vm_readv
#define __NR_compat_process_vm_writev __NR_ia32_process_vm_writev
#define __NR_compat_pselect6 __NR_ia32_pselect6
#define __NR_compat_ptrace __NR_ia32_ptrace
#define __NR_compat_pwrite64 __NR_ia32_pwrite64
#define __NR_compat_pwritev __NR_ia32_pwritev
#define __NR_compat_read __NR_ia32_read
#define __NR_compat_readahead __NR_ia32_readahead
#define __NR_compat_readv __NR_ia32_readv
#define __NR_compat_readlink __NR_ia32_readlink
#define __NR_compat_readlinkat __NR_ia32_readlinkat
#define __NR_compat_recvmmsg __NR_ia32_recvmmsg
#define __NR_compat_remap_file_pages __NR_ia32_remap_file_pages
#define __NR_compat_removexattr __NR_ia32_removexattr
#define __NR_compat_rename __NR_ia32_rename
#define __NR_compat_renameat __NR_ia32_renameat
#define __NR_compat_restart_syscall __NR_ia32_restart_syscall
#define __NR_compat_rmdir __NR_ia32_rmdir
#define __NR_compat_rt_sigaction __NR_ia32_rt_sigaction
#define __NR_compat_rt_sigpending __NR_ia32_rt_sigpending
#define __NR_compat_rt_sigprocmask __NR_ia32_rt_sigprocmask
#define __NR_compat_rt_sigqueueinfo __NR_ia32_rt_sigqueueinfo
#define __NR_compat_rt_sigreturn __NR_ia32_rt_sigreturn
#define __NR_compat_rt_sigsuspend __NR_ia32_rt_sigsuspend
#define __NR_compat_rt_sigtimedwait __NR_ia32_rt_sigtimedwait
#define __NR_compat_rt_tgsigqueueinfo __NR_ia32_rt_tgsigqueueinfo
#define __NR_compat_sched_get_priority_max __NR_ia32_sched_get_priority_max
#define __NR_compat_sched_get_priority_min __NR_ia32_sched_get_priority_min
#define __NR_compat_sched_getparam __NR_ia32_sched_getparam
#define __NR_compat_sched_getscheduler __NR_ia32_sched_getscheduler
#define __NR_compat_sched_setaffinity __NR_ia32_sched_setaffinity
#define __NR_compat_sched_setscheduler __NR_ia32_sched_setscheduler
#define __NR_compat_sched_yield __NR_ia32_sched_yield
#define __NR_compat_seccomp __NR_ia32_seccomp
#define __NR_compat_sendfile __NR_ia32_sendfile
#define __NR_compat_sendfile64 __NR_ia32_sendfile64
#define __NR_compat_sendmmsg __NR_ia32_sendmmsg
#define __NR_compat_set_tid_address __NR_ia32_set_tid_address
#define __NR_compat_set_thread_area __NR_ia32_set_thread_area
#define __NR_compat_setgid __NR_ia32_setgid
#define __NR_compat_setgroups __NR_ia32_setgroups
#define __NR_compat_setitimer __NR_ia32_setitimer
#define __NR_compat_setns __NR_ia32_setns
#define __NR_compat_setpgid __NR_ia32_setpgid
#define __NR_compat_setpriority __NR_ia32_setpriority
#define __NR_compat_setregid __NR_ia32_setregid
#define __NR_compat_setresgid __NR_ia32_setresgid
#define __NR_compat_setresuid __NR_ia32_setresuid
#define __NR_compat_setrlimit __NR_ia32_setrlimit
#define __NR_compat_setsid __NR_ia32_setsid
#define __NR_compat_settimeofday __NR_ia32_settimeofday
#define __NR_compat_setuid __NR_ia32_setuid
#define __NR_compat_setxattr __NR_ia32_setxattr
#define __NR_compat_sigaltstack __NR_ia32_sigaltstack
#define __NR_compat_socketcall __NR_ia32_socketcall
#define __NR_compat_splice __NR_ia32_splice
#define __NR_compat_stat __NR_ia32_stat
#define __NR_compat_statfs __NR_ia32_statfs
#define __NR_compat_symlink __NR_ia32_symlink
#define __NR_compat_symlinkat __NR_ia32_symlinkat
#define __NR_compat_sync_file_range __NR_ia32_sync_file_range
#define __NR_compat_sysinfo __NR_ia32_sysinfo
#define __NR_compat_syslog __NR_ia32_syslog
#define __NR_compat_tee __NR_ia32_tee
#define __NR_compat_tgkill __NR_ia32_tgkill
#define __NR_compat_tkill __NR_ia32_tkill
#define __NR_compat_timer_create __NR_ia32_timer_create
#define __NR_compat_timer_delete __NR_ia32_timer_delete
#define __NR_compat_timer_getoverrun __NR_ia32_timer_getoverrun
#define __NR_compat_timer_gettime __NR_ia32_timer_gettime
#define __NR_compat_timer_settime __NR_ia32_timer_settime
#define __NR_compat_timerfd_create __NR_ia32_timerfd_create
#define __NR_compat_timerfd_gettime __NR_ia32_timerfd_gettime
#define __NR_compat_timerfd_settime __NR_ia32_timerfd_settime
#define __NR_compat_times __NR_ia32_times
#define __NR_compat_truncate __NR_ia32_truncate
#define __NR_compat_umask __NR_ia32_umask
#define __NR_compat_umount2 __NR_ia32_umount2
#define __NR_compat_uname __NR_ia32_uname
#define __NR_compat_unlink __NR_ia32_unlink
#define __NR_compat_unlinkat __NR_ia32_unlinkat
#define __NR_compat_unshare __NR_ia32_unshare
#define __NR_compat_ustat __NR_ia32_ustat
#define __NR_compat_utimensat __NR_ia32_utimensat
#define __NR_compat_utimes __NR_ia32_utimes
#define __NR_compat_vfork __NR_ia32_vfork
#define __NR_compat_vmsplice __NR_ia32_vmsplice
#define __NR_compat_wait4 __NR_ia32_wait4
#define __NR_compat_waitid __NR_ia32_waitid
#define __NR_compat_waitpid __NR_ia32_waitpid
#define __NR_compat_write __NR_ia32_write
#define __NR_compat_writev __NR_ia32_writev
#define __NR_compat_chown32 __NR_ia32_chown32
#define __NR_compat_fadvise64 __NR_ia32_fadvise64
#define __NR_compat_fadvise64_64 __NR_ia32_fadvise64_64
#define __NR_compat_fchown32 __NR_ia32_fchown32
#define __NR_compat_fcntl64 __NR_ia32_fcntl64
#define __NR_compat_fstat64 __NR_ia32_fstat64
#define __NR_compat_fstatat64 __NR_ia32_fstatat64
#define __NR_compat_fstatfs64 __NR_ia32_fstatfs64
#define __NR_compat_ftruncate64 __NR_ia32_ftruncate64
#define __NR_compat_getegid32 __NR_ia32_getegid32
#define __NR_compat_geteuid32 __NR_ia32_geteuid32
#define __NR_compat_getgid32 __NR_ia32_getgid32
#define __NR_compat_getuid32 __NR_ia32_getuid32
#define __NR_compat_lchown32 __NR_ia32_lchown32
#define __NR_compat_lstat64 __NR_ia32_lstat64
#define __NR_compat_mmap2 __NR_ia32_mmap2
#define __NR_compat__newselect __NR_ia32__newselect
#define __NR_compat__llseek __NR_ia32__llseek
#define __NR_compat_sigaction __NR_ia32_sigaction
#define __NR_compat_sigpending __NR_ia32_sigpending
#define __NR_compat_sigprocmask __NR_ia32_sigprocmask
#define __NR_compat_sigreturn __NR_ia32_sigreturn
#define __NR_compat_sigsuspend __NR_ia32_sigsuspend
#define __NR_compat_setgid32 __NR_ia32_setgid32
#define __NR_compat_setgroups32 __NR_ia32_setgroups32
#define __NR_compat_setregid32 __NR_ia32_setregid32
#define __NR_compat_setresgid32 __NR_ia32_setresgid32
#define __NR_compat_setresuid32 __NR_ia32_setresuid32
#define __NR_compat_setreuid32 __NR_ia32_setreuid32
#define __NR_compat_setuid32 __NR_ia32_setuid32
#define __NR_compat_stat64 __NR_ia32_stat64
#define __NR_compat_statfs64 __NR_ia32_statfs64
#define __NR_compat_truncate64 __NR_ia32_truncate64
#define __NR_compat_ugetrlimit __NR_ia32_ugetrlimit
#endif
#endif
#define SYSCALL_ENTRY_ALT(name, func) \
{ \
.nr = __NR_ ## name, \
.alt = (sys_call_ptr_t)func, \
}
#define SYSCALL_ENTRY(name) SYSCALL_ENTRY_ALT(name, NULL)
#define COMPAT_SYSCALL_ENTRY_ALT(name, func) \
{ \
.nr = __NR_compat_ ## name, \
.alt = (sys_call_ptr_t)func, \
}
#define COMPAT_SYSCALL_ENTRY(name) COMPAT_SYSCALL_ENTRY_ALT(name, NULL)
static struct syscall_whitelist_entry read_write_test_whitelist[] = {
SYSCALL_ENTRY(exit),
SYSCALL_ENTRY(openat),
SYSCALL_ENTRY(close),
SYSCALL_ENTRY(read),
SYSCALL_ENTRY(write),
SYSCALL_ENTRY_ALT(prctl, alt_sys_prctl),
/* open(2) is deprecated and not wired up on ARM64. */
#ifndef CONFIG_ARM64
SYSCALL_ENTRY(open),
#endif
};
/*
* Syscall overrides for android.
*/
/* Make sure nothing sets a nice value more favorable than -10. */
long android_setpriority(int which, int who, int niceval)
{
if (niceval < 0) {
if (niceval < -20)
niceval = -20;
niceval = niceval / 2;
}
return sys_setpriority(which, who, niceval);
}
int android_sched_setscheduler(pid_t pid, int policy,
const struct sched_param *param)
{
struct sched_param lparam;
struct task_struct *p;
int retval;
/* negative values for policy are not valid */
if (policy < 0)
return -EINVAL;
if (!param || pid < 0)
return -EINVAL;
if (copy_from_user(&lparam, param, sizeof(struct sched_param)))
return -EFAULT;
rcu_read_lock();
retval = -ESRCH;
p = pid ? find_task_by_vpid(pid) : current;
if (p != NULL) {
const struct cred *cred = current_cred();
kuid_t android_root_uid, android_system_uid;
/*
* Allow root(0) and system(1000) processes to set RT scheduler.
*
* The system_server process run under system provides
* SchedulingPolicyService which is used by audioflinger and
* other services to boost their threads, so allow it to set RT
* scheduler for other threads.
*/
android_root_uid = make_kuid(cred->user_ns, 0);
android_system_uid = make_kuid(cred->user_ns, 1000);
if ((uid_eq(cred->euid, android_root_uid) ||
uid_eq(cred->euid, android_system_uid)) &&
ns_capable(cred->user_ns, CAP_SYS_NICE))
retval = sched_setscheduler_nocheck(p, policy, &lparam);
else
retval = sched_setscheduler(p, policy, &lparam);
}
rcu_read_unlock();
return retval;
}
static int android_fallocate(int fd, int mode, loff_t offset, loff_t len)
{
int retval;
struct kstat st;
retval = sys_fallocate(fd, mode, offset, len);
if (retval != -EOPNOTSUPP || mode != 0)
return retval;
/* Emulate fallocate by ftruncate and fstat. */
retval = vfs_fstat(fd, &st);
if (retval < 0)
return -EOPNOTSUPP; /* Do not expose errno from fstat. */
len += offset;
if (len <= st.size) {
/*
* When the file size is already larger than requested, do a
* no-op ftruncate by specifying the current file size. In this
* way, this function will return -1 appropriately when |fd| is
* opened for reading.
*/
len = st.size;
}
return sys_ftruncate(fd, len);
}
/*
* The 64 bit values are passed by using two 32 bit registers. Its order
* depends on the endian.
*/
#ifdef CONFIG_CPU_BIG_ENDIGAN
#define PACK64(hi, lo) (((u64)(hi) << 32) | (lo))
#else
#define PACK64(lo, hi) (((u64)(hi) << 32) | (lo))
#endif
static int android_fallocate32(int fd, int mode,
unsigned long offset1, unsigned long offset2,
unsigned long len1, unsigned long len2)
{
return android_fallocate(fd, mode, (loff_t) PACK64(offset1, offset2),
(loff_t) PACK64(len1, len2));
}
#undef PACK64
static struct syscall_whitelist_entry android_whitelist[] = {
SYSCALL_ENTRY(brk),
SYSCALL_ENTRY(capget),
SYSCALL_ENTRY(capset),
SYSCALL_ENTRY(chdir),
SYSCALL_ENTRY(clock_gettime),
SYSCALL_ENTRY(clock_getres),
SYSCALL_ENTRY(clock_nanosleep),
SYSCALL_ENTRY(clock_settime),
SYSCALL_ENTRY(clone),
SYSCALL_ENTRY(close),
SYSCALL_ENTRY(dup),
SYSCALL_ENTRY(dup3),
SYSCALL_ENTRY(epoll_create1),
SYSCALL_ENTRY(epoll_ctl),
SYSCALL_ENTRY(epoll_pwait),
SYSCALL_ENTRY(eventfd2),
SYSCALL_ENTRY(execve),
SYSCALL_ENTRY(exit),
SYSCALL_ENTRY(exit_group),
SYSCALL_ENTRY(faccessat),
SYSCALL_ENTRY(fchdir),
SYSCALL_ENTRY(fchmod),
SYSCALL_ENTRY(fchmodat),
SYSCALL_ENTRY(fchownat),
SYSCALL_ENTRY(fcntl),
SYSCALL_ENTRY(fdatasync),
SYSCALL_ENTRY(fgetxattr),
SYSCALL_ENTRY(flistxattr),
SYSCALL_ENTRY(flock),
SYSCALL_ENTRY(fremovexattr),
SYSCALL_ENTRY(fsetxattr),
SYSCALL_ENTRY(fstat),
SYSCALL_ENTRY(fstatfs),
SYSCALL_ENTRY(fsync),
SYSCALL_ENTRY(ftruncate),
SYSCALL_ENTRY(futex),
SYSCALL_ENTRY(getcwd),
SYSCALL_ENTRY(getdents64),
SYSCALL_ENTRY(getpgid),
SYSCALL_ENTRY(getpid),
SYSCALL_ENTRY(getppid),
SYSCALL_ENTRY(getpriority),
SYSCALL_ENTRY(getrlimit),
SYSCALL_ENTRY(getrusage),
SYSCALL_ENTRY(getsid),
SYSCALL_ENTRY(gettid),
SYSCALL_ENTRY(gettimeofday),
SYSCALL_ENTRY(getxattr),
SYSCALL_ENTRY(inotify_add_watch),
SYSCALL_ENTRY(inotify_init1),
SYSCALL_ENTRY(inotify_rm_watch),
SYSCALL_ENTRY(ioctl),
SYSCALL_ENTRY(ioprio_set),
SYSCALL_ENTRY(kill),
SYSCALL_ENTRY(lgetxattr),
SYSCALL_ENTRY(linkat),
SYSCALL_ENTRY(listxattr),
SYSCALL_ENTRY(llistxattr),
SYSCALL_ENTRY(lremovexattr),
SYSCALL_ENTRY(lseek),
SYSCALL_ENTRY(lsetxattr),
SYSCALL_ENTRY(madvise),
SYSCALL_ENTRY(mincore),
SYSCALL_ENTRY(mkdirat),
SYSCALL_ENTRY(mknodat),
SYSCALL_ENTRY(mlock),
SYSCALL_ENTRY(mlockall),
SYSCALL_ENTRY(munlock),
SYSCALL_ENTRY(munlockall),
SYSCALL_ENTRY(mount),
SYSCALL_ENTRY(mprotect),
SYSCALL_ENTRY(mremap),
SYSCALL_ENTRY(msync),
SYSCALL_ENTRY(munmap),
SYSCALL_ENTRY(name_to_handle_at),
SYSCALL_ENTRY(nanosleep),
SYSCALL_ENTRY(open_by_handle_at),
SYSCALL_ENTRY(openat),
SYSCALL_ENTRY(personality),
SYSCALL_ENTRY(pipe2),
SYSCALL_ENTRY(ppoll),
SYSCALL_ENTRY_ALT(prctl, alt_sys_prctl),
SYSCALL_ENTRY(pread64),
SYSCALL_ENTRY(preadv),
SYSCALL_ENTRY(prlimit64),
SYSCALL_ENTRY(process_vm_readv),
SYSCALL_ENTRY(process_vm_writev),
SYSCALL_ENTRY(pselect6),
SYSCALL_ENTRY(ptrace),
SYSCALL_ENTRY(pwrite64),
SYSCALL_ENTRY(pwritev),
SYSCALL_ENTRY(read),
SYSCALL_ENTRY(readahead),
SYSCALL_ENTRY(readv),
SYSCALL_ENTRY(readlinkat),
SYSCALL_ENTRY(recvmmsg),
SYSCALL_ENTRY(remap_file_pages),
SYSCALL_ENTRY(removexattr),
SYSCALL_ENTRY(renameat),
SYSCALL_ENTRY(restart_syscall),
SYSCALL_ENTRY(rt_sigaction),
SYSCALL_ENTRY(rt_sigpending),
SYSCALL_ENTRY(rt_sigprocmask),
SYSCALL_ENTRY(rt_sigqueueinfo),
SYSCALL_ENTRY(rt_sigreturn),
SYSCALL_ENTRY(rt_sigsuspend),
SYSCALL_ENTRY(rt_sigtimedwait),
SYSCALL_ENTRY(rt_tgsigqueueinfo),
SYSCALL_ENTRY(sched_get_priority_max),
SYSCALL_ENTRY(sched_get_priority_min),
SYSCALL_ENTRY(sched_getparam),
SYSCALL_ENTRY(sched_getscheduler),
SYSCALL_ENTRY(sched_setaffinity),
SYSCALL_ENTRY_ALT(sched_setscheduler, android_sched_setscheduler),
SYSCALL_ENTRY(sched_yield),
SYSCALL_ENTRY(seccomp),
SYSCALL_ENTRY(sendfile),
SYSCALL_ENTRY(sendmmsg),
SYSCALL_ENTRY(set_tid_address),
SYSCALL_ENTRY(setitimer),
SYSCALL_ENTRY(setns),
SYSCALL_ENTRY(setpgid),
SYSCALL_ENTRY_ALT(setpriority, android_setpriority),
SYSCALL_ENTRY(setrlimit),
SYSCALL_ENTRY(setsid),
SYSCALL_ENTRY(settimeofday),
SYSCALL_ENTRY(setxattr),
SYSCALL_ENTRY(sigaltstack),
SYSCALL_ENTRY(splice),
SYSCALL_ENTRY(statfs),
SYSCALL_ENTRY(symlinkat),
SYSCALL_ENTRY(sysinfo),
SYSCALL_ENTRY(syslog),
SYSCALL_ENTRY(tee),
SYSCALL_ENTRY(tgkill),
SYSCALL_ENTRY(tkill),
SYSCALL_ENTRY(timer_create),
SYSCALL_ENTRY(timer_delete),
SYSCALL_ENTRY(timer_gettime),
SYSCALL_ENTRY(timer_getoverrun),
SYSCALL_ENTRY(timer_settime),
SYSCALL_ENTRY(timerfd_create),
SYSCALL_ENTRY(timerfd_gettime),
SYSCALL_ENTRY(timerfd_settime),
SYSCALL_ENTRY(times),
SYSCALL_ENTRY(truncate),
SYSCALL_ENTRY(umask),
SYSCALL_ENTRY(umount2),
SYSCALL_ENTRY(uname),
SYSCALL_ENTRY(unlinkat),
SYSCALL_ENTRY(unshare),
SYSCALL_ENTRY(utimensat),
SYSCALL_ENTRY(vmsplice),
SYSCALL_ENTRY(wait4),
SYSCALL_ENTRY(waitid),
SYSCALL_ENTRY(write),
SYSCALL_ENTRY(writev),
/*
* Deprecated syscalls which are not wired up on new architectures
* such as ARM64.
*/
#ifndef CONFIG_ARM64
SYSCALL_ENTRY(access),
SYSCALL_ENTRY(chmod),
SYSCALL_ENTRY(open),
SYSCALL_ENTRY(creat),
SYSCALL_ENTRY(dup2),
SYSCALL_ENTRY(epoll_create),
SYSCALL_ENTRY(epoll_wait),
SYSCALL_ENTRY(eventfd),
SYSCALL_ENTRY(fork),
SYSCALL_ENTRY(futimesat),
SYSCALL_ENTRY(getdents),
SYSCALL_ENTRY(getpgrp),
SYSCALL_ENTRY(inotify_init),
SYSCALL_ENTRY(link),
SYSCALL_ENTRY(lstat),
SYSCALL_ENTRY(mkdir),
SYSCALL_ENTRY(mknod),
SYSCALL_ENTRY(pipe),
SYSCALL_ENTRY(poll),
SYSCALL_ENTRY(readlink),
SYSCALL_ENTRY(rename),
SYSCALL_ENTRY(rmdir),
SYSCALL_ENTRY(stat),
SYSCALL_ENTRY(symlink),
SYSCALL_ENTRY(unlink),
SYSCALL_ENTRY(ustat),
SYSCALL_ENTRY(utimes),
SYSCALL_ENTRY(vfork),
#endif
/*
* waitpid(2) is deprecated on most architectures, but still exists
* on IA32.
*/
#ifdef CONFIG_X86_32
SYSCALL_ENTRY(waitpid),
#endif
/* IA32 uses the common socketcall(2) entrypoint for socket calls. */
#ifdef CONFIG_X86_32
SYSCALL_ENTRY(socketcall),
#else
SYSCALL_ENTRY(accept),
SYSCALL_ENTRY(accept4),
SYSCALL_ENTRY(bind),
SYSCALL_ENTRY(connect),
SYSCALL_ENTRY(getpeername),
SYSCALL_ENTRY(getsockname),
SYSCALL_ENTRY(getsockopt),
SYSCALL_ENTRY(listen),
SYSCALL_ENTRY(recvfrom),
SYSCALL_ENTRY(recvmsg),
SYSCALL_ENTRY(sendmsg),
SYSCALL_ENTRY(sendto),
SYSCALL_ENTRY(setsockopt),
SYSCALL_ENTRY(shutdown),
SYSCALL_ENTRY(socket),
SYSCALL_ENTRY(socketpair),
/*
* recv(2)/send(2) are officially deprecated, but their entry-points
* still exist on ARM.
*/
#ifdef CONFIG_ARM
SYSCALL_ENTRY(recv),
SYSCALL_ENTRY(send),
#endif
#endif
/* Inject fallocate. */
#if defined(CONFIG_X86_64) || defined(CONFIG_ARM64)
SYSCALL_ENTRY_ALT(fallocate, android_fallocate),
#else
SYSCALL_ENTRY_ALT(fallocate, android_fallocate32),
#endif
/*
* posix_fadvise(2) and sync_file_range(2) have ARM-specific wrappers
* to deal with register alignment.
*/
#ifdef CONFIG_ARM
SYSCALL_ENTRY(arm_fadvise64_64),
SYSCALL_ENTRY(sync_file_range2),
#else
#ifdef CONFIG_X86_32
SYSCALL_ENTRY(fadvise64_64),
#endif
SYSCALL_ENTRY(fadvise64),
SYSCALL_ENTRY(sync_file_range),
#endif
/* 64-bit only syscalls. */
#if defined(CONFIG_X86_64) || defined(CONFIG_ARM64)
SYSCALL_ENTRY(fchown),
SYSCALL_ENTRY(getegid),
SYSCALL_ENTRY(geteuid),
SYSCALL_ENTRY(getgid),
SYSCALL_ENTRY(getgroups),
SYSCALL_ENTRY(getuid),
SYSCALL_ENTRY(newfstatat),
SYSCALL_ENTRY(mmap),
SYSCALL_ENTRY(setgid),
SYSCALL_ENTRY(setgroups),
SYSCALL_ENTRY(setregid),
SYSCALL_ENTRY(setresgid),
SYSCALL_ENTRY(setresuid),
SYSCALL_ENTRY(setreuid),
SYSCALL_ENTRY(setuid),
/*
* chown(2), lchown(2), and select(2) are deprecated and not wired up
* on ARM64.
*/
#ifndef CONFIG_ARM64
SYSCALL_ENTRY(chown),
SYSCALL_ENTRY(lchown),
SYSCALL_ENTRY(select),
#endif
#endif
/* 32-bit only syscalls. */
#if defined(CONFIG_ARM) || defined(CONFIG_X86_32)
SYSCALL_ENTRY(chown32),
SYSCALL_ENTRY(fchown32),
SYSCALL_ENTRY(fcntl64),
SYSCALL_ENTRY(fstat64),
SYSCALL_ENTRY(fstatat64),
SYSCALL_ENTRY(fstatfs64),
SYSCALL_ENTRY(ftruncate64),
SYSCALL_ENTRY(getegid32),
SYSCALL_ENTRY(geteuid32),
SYSCALL_ENTRY(getgid32),
SYSCALL_ENTRY(getgroups32),
SYSCALL_ENTRY(getuid32),
SYSCALL_ENTRY(lchown32),
SYSCALL_ENTRY(lstat64),
SYSCALL_ENTRY(mmap2),
SYSCALL_ENTRY(_newselect),
SYSCALL_ENTRY(_llseek),
SYSCALL_ENTRY(sigaction),
SYSCALL_ENTRY(sigpending),
SYSCALL_ENTRY(sigprocmask),
SYSCALL_ENTRY(sigreturn),
SYSCALL_ENTRY(sigsuspend),
SYSCALL_ENTRY(sendfile64),
SYSCALL_ENTRY(setgid32),
SYSCALL_ENTRY(setgroups32),
SYSCALL_ENTRY(setregid32),
SYSCALL_ENTRY(setresgid32),
SYSCALL_ENTRY(setresuid32),
SYSCALL_ENTRY(setreuid32),
SYSCALL_ENTRY(setuid32),
SYSCALL_ENTRY(stat64),
SYSCALL_ENTRY(statfs64),
SYSCALL_ENTRY(truncate64),
SYSCALL_ENTRY(ugetrlimit),
#endif
/* X86-specific syscalls. */
#ifdef CONFIG_X86
SYSCALL_ENTRY(modify_ldt),
SYSCALL_ENTRY(set_thread_area),
#endif
};
#ifdef CONFIG_COMPAT
static struct syscall_whitelist_entry read_write_test_compat_whitelist[] = {
COMPAT_SYSCALL_ENTRY(exit),
COMPAT_SYSCALL_ENTRY(open),
COMPAT_SYSCALL_ENTRY(close),
COMPAT_SYSCALL_ENTRY(read),
COMPAT_SYSCALL_ENTRY(write),
COMPAT_SYSCALL_ENTRY_ALT(prctl, alt_sys_prctl),
};
static struct syscall_whitelist_entry android_compat_whitelist[] = {
COMPAT_SYSCALL_ENTRY(access),
COMPAT_SYSCALL_ENTRY(brk),
COMPAT_SYSCALL_ENTRY(capget),
COMPAT_SYSCALL_ENTRY(capset),
COMPAT_SYSCALL_ENTRY(chdir),
COMPAT_SYSCALL_ENTRY(chmod),
COMPAT_SYSCALL_ENTRY(clock_gettime),
COMPAT_SYSCALL_ENTRY(clock_getres),
COMPAT_SYSCALL_ENTRY(clock_nanosleep),
COMPAT_SYSCALL_ENTRY(clock_settime),
COMPAT_SYSCALL_ENTRY(clone),
COMPAT_SYSCALL_ENTRY(close),
COMPAT_SYSCALL_ENTRY(creat),
COMPAT_SYSCALL_ENTRY(dup),
COMPAT_SYSCALL_ENTRY(dup2),
COMPAT_SYSCALL_ENTRY(dup3),
COMPAT_SYSCALL_ENTRY(epoll_create),
COMPAT_SYSCALL_ENTRY(epoll_create1),
COMPAT_SYSCALL_ENTRY(epoll_ctl),
COMPAT_SYSCALL_ENTRY(epoll_wait),
COMPAT_SYSCALL_ENTRY(epoll_pwait),
COMPAT_SYSCALL_ENTRY(eventfd),
COMPAT_SYSCALL_ENTRY(eventfd2),
COMPAT_SYSCALL_ENTRY(execve),
COMPAT_SYSCALL_ENTRY(exit),
COMPAT_SYSCALL_ENTRY(exit_group),
COMPAT_SYSCALL_ENTRY(faccessat),
COMPAT_SYSCALL_ENTRY_ALT(fallocate, android_fallocate32),
COMPAT_SYSCALL_ENTRY(fchdir),
COMPAT_SYSCALL_ENTRY(fchmod),
COMPAT_SYSCALL_ENTRY(fchmodat),
COMPAT_SYSCALL_ENTRY(fchownat),
COMPAT_SYSCALL_ENTRY(fcntl),
COMPAT_SYSCALL_ENTRY(fdatasync),
COMPAT_SYSCALL_ENTRY(fgetxattr),
COMPAT_SYSCALL_ENTRY(flistxattr),
COMPAT_SYSCALL_ENTRY(flock),
COMPAT_SYSCALL_ENTRY(fork),
COMPAT_SYSCALL_ENTRY(fremovexattr),
COMPAT_SYSCALL_ENTRY(fsetxattr),
COMPAT_SYSCALL_ENTRY(fstat),
COMPAT_SYSCALL_ENTRY(fstatfs),
COMPAT_SYSCALL_ENTRY(fsync),
COMPAT_SYSCALL_ENTRY(ftruncate),
COMPAT_SYSCALL_ENTRY(futex),
COMPAT_SYSCALL_ENTRY(futimesat),
COMPAT_SYSCALL_ENTRY(getcwd),
COMPAT_SYSCALL_ENTRY(getdents),
COMPAT_SYSCALL_ENTRY(getdents64),
COMPAT_SYSCALL_ENTRY(getpgid),
COMPAT_SYSCALL_ENTRY(getpgrp),
COMPAT_SYSCALL_ENTRY(getpid),
COMPAT_SYSCALL_ENTRY(getppid),
COMPAT_SYSCALL_ENTRY(getpriority),
COMPAT_SYSCALL_ENTRY(getrusage),
COMPAT_SYSCALL_ENTRY(getsid),
COMPAT_SYSCALL_ENTRY(gettid),
COMPAT_SYSCALL_ENTRY(gettimeofday),
COMPAT_SYSCALL_ENTRY(getxattr),
COMPAT_SYSCALL_ENTRY(inotify_add_watch),
COMPAT_SYSCALL_ENTRY(inotify_init),
COMPAT_SYSCALL_ENTRY(inotify_init1),
COMPAT_SYSCALL_ENTRY(inotify_rm_watch),
COMPAT_SYSCALL_ENTRY(ioctl),
COMPAT_SYSCALL_ENTRY(ioprio_set),
COMPAT_SYSCALL_ENTRY(kill),
COMPAT_SYSCALL_ENTRY(lgetxattr),
COMPAT_SYSCALL_ENTRY(link),
COMPAT_SYSCALL_ENTRY(linkat),
COMPAT_SYSCALL_ENTRY(listxattr),
COMPAT_SYSCALL_ENTRY(llistxattr),
COMPAT_SYSCALL_ENTRY(lremovexattr),
COMPAT_SYSCALL_ENTRY(lseek),
COMPAT_SYSCALL_ENTRY(lsetxattr),
COMPAT_SYSCALL_ENTRY(lstat),
COMPAT_SYSCALL_ENTRY(madvise),
COMPAT_SYSCALL_ENTRY(mincore),
COMPAT_SYSCALL_ENTRY(mkdir),
COMPAT_SYSCALL_ENTRY(mkdirat),
COMPAT_SYSCALL_ENTRY(mknod),
COMPAT_SYSCALL_ENTRY(mknodat),
COMPAT_SYSCALL_ENTRY(mlock),
COMPAT_SYSCALL_ENTRY(mlockall),
COMPAT_SYSCALL_ENTRY(munlock),
COMPAT_SYSCALL_ENTRY(munlockall),
COMPAT_SYSCALL_ENTRY(mount),
COMPAT_SYSCALL_ENTRY(mprotect),
COMPAT_SYSCALL_ENTRY(mremap),
COMPAT_SYSCALL_ENTRY(msync),
COMPAT_SYSCALL_ENTRY(munmap),
COMPAT_SYSCALL_ENTRY(name_to_handle_at),
COMPAT_SYSCALL_ENTRY(nanosleep),
COMPAT_SYSCALL_ENTRY(open),
COMPAT_SYSCALL_ENTRY(open_by_handle_at),
COMPAT_SYSCALL_ENTRY(openat),
COMPAT_SYSCALL_ENTRY(personality),
COMPAT_SYSCALL_ENTRY(pipe),
COMPAT_SYSCALL_ENTRY(pipe2),
COMPAT_SYSCALL_ENTRY(poll),
COMPAT_SYSCALL_ENTRY(ppoll),
COMPAT_SYSCALL_ENTRY_ALT(prctl, alt_sys_prctl),
COMPAT_SYSCALL_ENTRY(pread64),
COMPAT_SYSCALL_ENTRY(preadv),
COMPAT_SYSCALL_ENTRY(prlimit64),
COMPAT_SYSCALL_ENTRY(process_vm_readv),
COMPAT_SYSCALL_ENTRY(process_vm_writev),
COMPAT_SYSCALL_ENTRY(pselect6),
COMPAT_SYSCALL_ENTRY(ptrace),
COMPAT_SYSCALL_ENTRY(pwrite64),
COMPAT_SYSCALL_ENTRY(pwritev),
COMPAT_SYSCALL_ENTRY(read),
COMPAT_SYSCALL_ENTRY(readahead),
COMPAT_SYSCALL_ENTRY(readv),
COMPAT_SYSCALL_ENTRY(readlink),
COMPAT_SYSCALL_ENTRY(readlinkat),
COMPAT_SYSCALL_ENTRY(recvmmsg),
COMPAT_SYSCALL_ENTRY(remap_file_pages),
COMPAT_SYSCALL_ENTRY(removexattr),
COMPAT_SYSCALL_ENTRY(rename),
COMPAT_SYSCALL_ENTRY(renameat),
COMPAT_SYSCALL_ENTRY(restart_syscall),
COMPAT_SYSCALL_ENTRY(rmdir),
COMPAT_SYSCALL_ENTRY(rt_sigaction),
COMPAT_SYSCALL_ENTRY(rt_sigpending),
COMPAT_SYSCALL_ENTRY(rt_sigprocmask),
COMPAT_SYSCALL_ENTRY(rt_sigqueueinfo),
COMPAT_SYSCALL_ENTRY(rt_sigreturn),
COMPAT_SYSCALL_ENTRY(rt_sigsuspend),
COMPAT_SYSCALL_ENTRY(rt_sigtimedwait),
COMPAT_SYSCALL_ENTRY(rt_tgsigqueueinfo),
COMPAT_SYSCALL_ENTRY(sched_get_priority_max),
COMPAT_SYSCALL_ENTRY(sched_get_priority_min),
COMPAT_SYSCALL_ENTRY(sched_getparam),
COMPAT_SYSCALL_ENTRY(sched_getscheduler),
COMPAT_SYSCALL_ENTRY(sched_setaffinity),
COMPAT_SYSCALL_ENTRY_ALT(sched_setscheduler,
android_sched_setscheduler),
COMPAT_SYSCALL_ENTRY(sched_yield),
COMPAT_SYSCALL_ENTRY(seccomp),
COMPAT_SYSCALL_ENTRY(sendfile),
COMPAT_SYSCALL_ENTRY(sendfile64),
COMPAT_SYSCALL_ENTRY(sendmmsg),
COMPAT_SYSCALL_ENTRY(set_tid_address),
COMPAT_SYSCALL_ENTRY(setitimer),
COMPAT_SYSCALL_ENTRY(setns),
COMPAT_SYSCALL_ENTRY(setpgid),
COMPAT_SYSCALL_ENTRY_ALT(setpriority, android_setpriority),
COMPAT_SYSCALL_ENTRY(setrlimit),
COMPAT_SYSCALL_ENTRY(setsid),
COMPAT_SYSCALL_ENTRY(settimeofday),
COMPAT_SYSCALL_ENTRY(setxattr),
COMPAT_SYSCALL_ENTRY(sigaltstack),
COMPAT_SYSCALL_ENTRY(splice),
COMPAT_SYSCALL_ENTRY(stat),
COMPAT_SYSCALL_ENTRY(statfs),
COMPAT_SYSCALL_ENTRY(symlink),
COMPAT_SYSCALL_ENTRY(symlinkat),
COMPAT_SYSCALL_ENTRY(sysinfo),
COMPAT_SYSCALL_ENTRY(syslog),
COMPAT_SYSCALL_ENTRY(tgkill),
COMPAT_SYSCALL_ENTRY(tee),
COMPAT_SYSCALL_ENTRY(tkill),
COMPAT_SYSCALL_ENTRY(timer_create),
COMPAT_SYSCALL_ENTRY(timer_delete),
COMPAT_SYSCALL_ENTRY(timer_gettime),
COMPAT_SYSCALL_ENTRY(timer_getoverrun),
COMPAT_SYSCALL_ENTRY(timer_settime),
COMPAT_SYSCALL_ENTRY(timerfd_create),
COMPAT_SYSCALL_ENTRY(timerfd_gettime),
COMPAT_SYSCALL_ENTRY(timerfd_settime),
COMPAT_SYSCALL_ENTRY(times),
COMPAT_SYSCALL_ENTRY(truncate),
COMPAT_SYSCALL_ENTRY(umask),
COMPAT_SYSCALL_ENTRY(umount2),
COMPAT_SYSCALL_ENTRY(uname),
COMPAT_SYSCALL_ENTRY(unlink),
COMPAT_SYSCALL_ENTRY(unlinkat),
COMPAT_SYSCALL_ENTRY(unshare),
COMPAT_SYSCALL_ENTRY(ustat),
COMPAT_SYSCALL_ENTRY(utimensat),
COMPAT_SYSCALL_ENTRY(utimes),
COMPAT_SYSCALL_ENTRY(vfork),
COMPAT_SYSCALL_ENTRY(vmsplice),
COMPAT_SYSCALL_ENTRY(wait4),
COMPAT_SYSCALL_ENTRY(waitid),
COMPAT_SYSCALL_ENTRY(write),
COMPAT_SYSCALL_ENTRY(writev),
COMPAT_SYSCALL_ENTRY(chown32),
COMPAT_SYSCALL_ENTRY(fchown32),
COMPAT_SYSCALL_ENTRY(fcntl64),
COMPAT_SYSCALL_ENTRY(fstat64),
COMPAT_SYSCALL_ENTRY(fstatat64),
COMPAT_SYSCALL_ENTRY(fstatfs64),
COMPAT_SYSCALL_ENTRY(ftruncate64),
COMPAT_SYSCALL_ENTRY(getegid),
COMPAT_SYSCALL_ENTRY(getegid32),
COMPAT_SYSCALL_ENTRY(geteuid),
COMPAT_SYSCALL_ENTRY(geteuid32),
COMPAT_SYSCALL_ENTRY(getgid),
COMPAT_SYSCALL_ENTRY(getgid32),
COMPAT_SYSCALL_ENTRY(getgroups32),
COMPAT_SYSCALL_ENTRY(getuid),
COMPAT_SYSCALL_ENTRY(getuid32),
COMPAT_SYSCALL_ENTRY(lchown32),
COMPAT_SYSCALL_ENTRY(lstat64),
COMPAT_SYSCALL_ENTRY(mmap2),
COMPAT_SYSCALL_ENTRY(_newselect),
COMPAT_SYSCALL_ENTRY(_llseek),
COMPAT_SYSCALL_ENTRY(sigaction),
COMPAT_SYSCALL_ENTRY(sigpending),
COMPAT_SYSCALL_ENTRY(sigprocmask),
COMPAT_SYSCALL_ENTRY(sigreturn),
COMPAT_SYSCALL_ENTRY(sigsuspend),
COMPAT_SYSCALL_ENTRY(setgid32),
COMPAT_SYSCALL_ENTRY(setgroups32),
COMPAT_SYSCALL_ENTRY(setregid32),
COMPAT_SYSCALL_ENTRY(setresgid32),
COMPAT_SYSCALL_ENTRY(setresuid32),
COMPAT_SYSCALL_ENTRY(setreuid32),
COMPAT_SYSCALL_ENTRY(setuid32),
COMPAT_SYSCALL_ENTRY(stat64),
COMPAT_SYSCALL_ENTRY(statfs64),
COMPAT_SYSCALL_ENTRY(truncate64),
COMPAT_SYSCALL_ENTRY(ugetrlimit),
/*
* waitpid(2) is deprecated on most architectures, but still exists
* on IA32.
*/
#ifdef CONFIG_X86
COMPAT_SYSCALL_ENTRY(waitpid),
#endif
/*
* posix_fadvise(2) and sync_file_range(2) have ARM-specific wrappers
* to deal with register alignment.
*/
#ifdef CONFIG_ARM64
COMPAT_SYSCALL_ENTRY(arm_fadvise64_64),
COMPAT_SYSCALL_ENTRY(sync_file_range2),
#else
COMPAT_SYSCALL_ENTRY(fadvise64_64),
COMPAT_SYSCALL_ENTRY(fadvise64),
COMPAT_SYSCALL_ENTRY(sync_file_range),
#endif
/* IA32 uses the common socketcall(2) entrypoint for socket calls. */
#ifdef CONFIG_X86
COMPAT_SYSCALL_ENTRY(socketcall),
#else
COMPAT_SYSCALL_ENTRY(accept),
COMPAT_SYSCALL_ENTRY(accept4),
COMPAT_SYSCALL_ENTRY(bind),
COMPAT_SYSCALL_ENTRY(connect),
COMPAT_SYSCALL_ENTRY(getpeername),
COMPAT_SYSCALL_ENTRY(getsockname),
COMPAT_SYSCALL_ENTRY(getsockopt),
COMPAT_SYSCALL_ENTRY(listen),
COMPAT_SYSCALL_ENTRY(recvfrom),
COMPAT_SYSCALL_ENTRY(recvmsg),
COMPAT_SYSCALL_ENTRY(sendmsg),
COMPAT_SYSCALL_ENTRY(sendto),
COMPAT_SYSCALL_ENTRY(setsockopt),
COMPAT_SYSCALL_ENTRY(shutdown),
COMPAT_SYSCALL_ENTRY(socket),
COMPAT_SYSCALL_ENTRY(socketpair),
COMPAT_SYSCALL_ENTRY(recv),
COMPAT_SYSCALL_ENTRY(send),
#endif
/*
* getrlimit(2) is deprecated and not wired in the ARM compat table
* on ARM64.
*/
#ifndef CONFIG_ARM64
COMPAT_SYSCALL_ENTRY(getrlimit),
#endif
/* x86-specific syscalls. */
#ifdef CONFIG_X86
COMPAT_SYSCALL_ENTRY(modify_ldt),
COMPAT_SYSCALL_ENTRY(set_thread_area),
#endif
};
#endif
static struct syscall_whitelist whitelists[] = {
SYSCALL_WHITELIST(read_write_test),
SYSCALL_WHITELIST(android),
PERMISSIVE_SYSCALL_WHITELIST(android),
};
static int alt_syscall_apply_whitelist(const struct syscall_whitelist *wl,
struct alt_sys_call_table *t)
{
unsigned int i;
DECLARE_BITMAP(whitelist, t->size);
bitmap_zero(whitelist, t->size);
for (i = 0; i < wl->nr_whitelist; i++) {
unsigned int nr = wl->whitelist[i].nr;
if (nr >= t->size)
return -EINVAL;
bitmap_set(whitelist, nr, 1);
if (wl->whitelist[i].alt)
t->table[nr] = wl->whitelist[i].alt;
}
for (i = 0; i < t->size; i++) {
if (!test_bit(i, whitelist)) {
t->table[i] = wl->permissive ?
(sys_call_ptr_t)warn_syscall :
(sys_call_ptr_t)block_syscall;
}
}
return 0;
}
#ifdef CONFIG_COMPAT
static int
alt_syscall_apply_compat_whitelist(const struct syscall_whitelist *wl,
struct alt_sys_call_table *t)
{
unsigned int i;
DECLARE_BITMAP(whitelist, t->compat_size);
bitmap_zero(whitelist, t->compat_size);
for (i = 0; i < wl->nr_compat_whitelist; i++) {
unsigned int nr = wl->compat_whitelist[i].nr;
if (nr >= t->compat_size)
return -EINVAL;
bitmap_set(whitelist, nr, 1);
if (wl->compat_whitelist[i].alt)
t->compat_table[nr] = wl->compat_whitelist[i].alt;
}
for (i = 0; i < t->compat_size; i++) {
if (!test_bit(i, whitelist)) {
t->compat_table[i] = wl->permissive ?
(sys_call_ptr_t)warn_compat_syscall :
(sys_call_ptr_t)block_syscall;
}
}
return 0;
}
#else
static inline int
alt_syscall_apply_compat_whitelist(const struct syscall_whitelist *wl,
struct alt_sys_call_table *t)
{
return 0;
}
#endif
static int alt_syscall_init_one(const struct syscall_whitelist *wl)
{
struct alt_sys_call_table *t;
int err;
t = kzalloc(sizeof(*t), GFP_KERNEL);
if (!t)
return -ENOMEM;
strncpy(t->name, wl->name, sizeof(t->name));
err = arch_dup_sys_call_table(t);
if (err)
return err;
err = alt_syscall_apply_whitelist(wl, t);
if (err)
return err;
err = alt_syscall_apply_compat_whitelist(wl, t);
if (err)
return err;
return register_alt_sys_call_table(t);
}
/*
* Register an alternate syscall table for each whitelist. Note that the
* lack of a module_exit() is intentional - once a syscall table is registered
* it cannot be unregistered.
*
* TODO(abrestic) Support unregistering syscall tables?
*/
static int chromiumos_alt_syscall_init(void)
{
unsigned int i;
int err;
err = arch_dup_sys_call_table(&default_table);
if (err)
return err;
for (i = 0; i < ARRAY_SIZE(whitelists); i++) {
err = alt_syscall_init_one(&whitelists[i]);
if (err)
pr_warn("Failed to register syscall table %s: %d\n",
whitelists[i].name, err);
}
return 0;
}
module_init(chromiumos_alt_syscall_init);