Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

seccomp: Use -1 marker for end of mode 1 syscall list

The terminator for the mode 1 syscalls list was a 0, but that could be
a valid syscall number (e.g. x86_64 __NR_read). By luck, __NR_read was
listed first and the loop construct would not test it, so there was no
bug. However, this is fragile. Replace the terminator with -1 instead,
and make the variable name for mode 1 syscall lists more descriptive.

Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Will Drewry <wad@chromium.org>
Signed-off-by: Kees Cook <keescook@chromium.org>

+8 -8
+2 -2
arch/mips/include/asm/seccomp.h
··· 9 9 static const int syscalls_O32[] = { 10 10 __NR_O32_Linux + 3, __NR_O32_Linux + 4, 11 11 __NR_O32_Linux + 1, __NR_O32_Linux + 193, 12 - 0, /* null terminated */ 12 + -1, /* negative terminated */ 13 13 }; 14 14 static const int syscalls_N32[] = { 15 15 __NR_N32_Linux + 0, __NR_N32_Linux + 1, 16 16 __NR_N32_Linux + 58, __NR_N32_Linux + 211, 17 - 0, /* null terminated */ 17 + -1, /* negative terminated */ 18 18 }; 19 19 20 20 if (IS_ENABLED(CONFIG_MIPS32_O32) && test_thread_flag(TIF_32BIT_REGS))
+1 -1
include/asm-generic/seccomp.h
··· 33 33 static const int mode1_syscalls_32[] = { 34 34 __NR_seccomp_read_32, __NR_seccomp_write_32, 35 35 __NR_seccomp_exit_32, __NR_seccomp_sigreturn_32, 36 - 0, /* null terminated */ 36 + -1, /* negative terminated */ 37 37 }; 38 38 return mode1_syscalls_32; 39 39 }
+5 -5
kernel/seccomp.c
··· 742 742 */ 743 743 static const int mode1_syscalls[] = { 744 744 __NR_seccomp_read, __NR_seccomp_write, __NR_seccomp_exit, __NR_seccomp_sigreturn, 745 - 0, /* null terminated */ 745 + -1, /* negative terminated */ 746 746 }; 747 747 748 748 static void __secure_computing_strict(int this_syscall) 749 749 { 750 - const int *syscall_whitelist = mode1_syscalls; 750 + const int *allowed_syscalls = mode1_syscalls; 751 751 #ifdef CONFIG_COMPAT 752 752 if (in_compat_syscall()) 753 - syscall_whitelist = get_compat_mode1_syscalls(); 753 + allowed_syscalls = get_compat_mode1_syscalls(); 754 754 #endif 755 755 do { 756 - if (*syscall_whitelist == this_syscall) 756 + if (*allowed_syscalls == this_syscall) 757 757 return; 758 - } while (*++syscall_whitelist); 758 + } while (*++allowed_syscalls != -1); 759 759 760 760 #ifdef SECCOMP_DEBUG 761 761 dump_stack();