From 5a499cf36ecef6035344d042b415980a32f354f8 Mon Sep 17 00:00:00 2001 From: Jed Davis Date: Thu, 20 Mar 2014 10:19:42 -0400 Subject: [PATCH] Bug 985227 - Part 3: Replace the seccomp filter arch ifdefs with syscall existence tests. r=kang --- security/sandbox/linux/SandboxFilter.cpp | 118 +++++++++++++---------- 1 file changed, 65 insertions(+), 53 deletions(-) diff --git a/security/sandbox/linux/SandboxFilter.cpp b/security/sandbox/linux/SandboxFilter.cpp index fce4313ad8c4..496ac36bfd74 100644 --- a/security/sandbox/linux/SandboxFilter.cpp +++ b/security/sandbox/linux/SandboxFilter.cpp @@ -15,10 +15,22 @@ namespace mozilla { +#define SYSCALL_EXISTS(name) defined(__NR_##name) + static struct sock_filter seccomp_filter[] = { VALIDATE_ARCHITECTURE, EXAMINE_SYSCALL, + // Some architectures went through a transition from 32-bit to + // 64-bit off_t and had to version all the syscalls that referenced + // it; others (newer and/or 64-bit ones) didn't. Adjust the + // conditional as needed. +#if SYSCALL_EXISTS(stat64) +#define ALLOW_SYSCALL_LARGEFILE(plain, versioned) ALLOW_SYSCALL(versioned) +#else +#define ALLOW_SYSCALL_LARGEFILE(plain, versioned) ALLOW_SYSCALL(plain) +#endif + /* Most used system calls should be at the top of the whitelist * for performance reasons. The whitelist BPF filter exits after * processing any ALLOW_SYSCALL macro. @@ -37,18 +49,22 @@ static struct sock_filter seccomp_filter[] = { */ ALLOW_SYSCALL(futex), + // FIXME, bug 920372: i386 multiplexes all the socket-related + // interfaces into a single syscall. We should check the selector. +#if SYSCALL_EXISTS(socketcall) + ALLOW_SYSCALL(socketcall), +#else + ALLOW_SYSCALL(recvmsg), + ALLOW_SYSCALL(sendmsg), +#endif - /* Architecture-specific frequently used syscalls */ -#if defined(__arm__) - ALLOW_SYSCALL(recvmsg), - ALLOW_SYSCALL(sendmsg), + // mmap2 is a little different from most off_t users, because it's + // passed in a register (so it's a problem for even a "new" 32-bit + // arch) -- and the workaround, mmap2, passes a page offset instead. +#if SYSCALL_EXISTS(mmap2) ALLOW_SYSCALL(mmap2), -#elif defined(__i386__) - ALLOW_SYSCALL(ipc), - ALLOW_SYSCALL(mmap2), -#elif defined(__x86_64__) - ALLOW_SYSCALL(recvmsg), - ALLOW_SYSCALL(sendmsg), +#else + ALLOW_SYSCALL(mmap), #endif /* B2G specific high-frequency syscalls */ @@ -59,6 +75,10 @@ static struct sock_filter seccomp_filter[] = { #endif ALLOW_SYSCALL(read), ALLOW_SYSCALL(write), + // 32-bit lseek is used, at least on Android, to implement ANSI fseek. +#if SYSCALL_EXISTS(_llseek) + ALLOW_SYSCALL(_llseek), +#endif ALLOW_SYSCALL(lseek), /* ioctl() is for GL. Remove when GL proxy is implemented. @@ -72,53 +92,44 @@ static struct sock_filter seccomp_filter[] = { ALLOW_SYSCALL(clone), ALLOW_SYSCALL(brk), - /* B2G specific medium-frequency syscalls */ -#ifdef MOZ_WIDGET_GONK ALLOW_SYSCALL(getpid), - ALLOW_SYSCALL(rt_sigreturn), -#endif - ALLOW_SYSCALL(poll), ALLOW_SYSCALL(gettid), ALLOW_SYSCALL(getrusage), ALLOW_SYSCALL(madvise), ALLOW_SYSCALL(dup), ALLOW_SYSCALL(nanosleep), - - /* Architecture-specific infrequently used syscalls */ -#if defined(__arm__) + ALLOW_SYSCALL(poll), + // select()'s arguments used to be passed by pointer as a struct. +#if SYSCALL_EXISTS(_newselect) ALLOW_SYSCALL(_newselect), - ALLOW_SYSCALL(_llseek), - ALLOW_SYSCALL(getuid32), - ALLOW_SYSCALL(geteuid32), - ALLOW_SYSCALL(sigreturn), - ALLOW_SYSCALL(fcntl64), -#elif defined(__i386__) - ALLOW_SYSCALL(_newselect), - ALLOW_SYSCALL(_llseek), - ALLOW_SYSCALL(getuid32), - ALLOW_SYSCALL(geteuid32), - ALLOW_SYSCALL(sigreturn), - ALLOW_SYSCALL(fcntl64), #else ALLOW_SYSCALL(select), #endif + // Some archs used to have 16-bit uid/gid instead of 32-bit. +#if SYSCALL_EXISTS(getuid32) + ALLOW_SYSCALL(getuid32), + ALLOW_SYSCALL(geteuid32), +#else + ALLOW_SYSCALL(getuid), + ALLOW_SYSCALL(geteuid), +#endif + // Some newer archs (e.g., x64 and x32) have only rt_sigreturn, but + // ARM has and uses both syscalls -- rt_sigreturn for SA_SIGINFO + // handlers and classic sigreturn otherwise. +#if SYSCALL_EXISTS(sigreturn) + ALLOW_SYSCALL(sigreturn), +#endif + ALLOW_SYSCALL(rt_sigreturn), + ALLOW_SYSCALL_LARGEFILE(fcntl, fcntl64), /* Must remove all of the following in the future, when no longer used */ /* open() is for some legacy APIs such as font loading. */ /* See bug 906996 for removing unlink(). */ -#if defined(__arm__) - ALLOW_SYSCALL(fstat64), - ALLOW_SYSCALL(stat64), - ALLOW_SYSCALL(lstat64), - ALLOW_SYSCALL(socketpair), - ALLOW_SYSCALL(sigprocmask), - DENY_SYSCALL(socket, EACCES), -#elif defined(__i386__) - ALLOW_SYSCALL(fstat64), - ALLOW_SYSCALL(stat64), - ALLOW_SYSCALL(lstat64), - ALLOW_SYSCALL(sigprocmask), -#else + ALLOW_SYSCALL_LARGEFILE(fstat, fstat64), + ALLOW_SYSCALL_LARGEFILE(stat, stat64), + ALLOW_SYSCALL_LARGEFILE(lstat, lstat64), + // FIXME, bug 920372: see above. +#if !SYSCALL_EXISTS(socketcall) ALLOW_SYSCALL(socketpair), DENY_SYSCALL(socket, EACCES), #endif @@ -135,6 +146,12 @@ static struct sock_filter seccomp_filter[] = { ALLOW_SYSCALL(sched_get_priority_min), ALLOW_SYSCALL(sched_get_priority_max), ALLOW_SYSCALL(setpriority), + // rt_sigprocmask is passed the sigset_t size. On older archs, + // sigprocmask is a compatibility shim that assumes the pre-RT size. +#if SYSCALL_EXISTS(sigprocmask) + ALLOW_SYSCALL(sigprocmask), +#endif + ALLOW_SYSCALL(rt_sigprocmask), /* System calls used by the profiler */ #ifdef MOZ_PROFILING @@ -143,11 +160,11 @@ static struct sock_filter seccomp_filter[] = { /* B2G specific low-frequency syscalls */ #ifdef MOZ_WIDGET_GONK -#if !defined(__i386__) +#if !SYSCALL_EXISTS(socketcall) ALLOW_SYSCALL(sendto), ALLOW_SYSCALL(recvfrom), #endif - ALLOW_SYSCALL(getdents64), + ALLOW_SYSCALL_LARGEFILE(getdents, getdents64), ALLOW_SYSCALL(epoll_ctl), ALLOW_SYSCALL(sched_yield), ALLOW_SYSCALL(sched_getscheduler), @@ -156,19 +173,16 @@ static struct sock_filter seccomp_filter[] = { /* Always last and always OK calls */ /* Architecture-specific very infrequently used syscalls */ -#if defined(__arm__) +#if SYSCALL_EXISTS(sigaction) ALLOW_SYSCALL(sigaction), +#endif ALLOW_SYSCALL(rt_sigaction), +#ifdef ALLOW_ARM_SYSCALL ALLOW_ARM_SYSCALL(breakpoint), ALLOW_ARM_SYSCALL(cacheflush), ALLOW_ARM_SYSCALL(usr26), ALLOW_ARM_SYSCALL(usr32), ALLOW_ARM_SYSCALL(set_tls), -#elif defined(__i386__) - ALLOW_SYSCALL(sigaction), - ALLOW_SYSCALL(rt_sigaction), -#elif defined(__x86_64__) - ALLOW_SYSCALL(rt_sigaction), #endif /* restart_syscall is called internally, generally when debugging */ @@ -186,8 +200,6 @@ static struct sock_filter seccomp_filter[] = { ALLOW_SYSCALL(fstat), ALLOW_SYSCALL(readlink), ALLOW_SYSCALL(getsockname), - /* duplicate rt_sigaction in SECCOMP_WHITELIST_PROFILING */ - ALLOW_SYSCALL(rt_sigaction), ALLOW_SYSCALL(getuid), ALLOW_SYSCALL(geteuid), ALLOW_SYSCALL(mkdir),