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

selftests/seccomp: powerpc: Set syscall return during ptrace syscall exit

Some archs (like powerpc) only support changing the return code during
syscall exit when ptrace is used. Test entry vs exit phases for which
portions of the syscall number and return values need to be set at which
different phases. For non-powerpc, all changes are made during ptrace
syscall entry, as before. For powerpc, the syscall number is changed at
ptrace syscall entry and the syscall return value is changed on ptrace
syscall exit.

Reported-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
Suggested-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
Link: https://lore.kernel.org/linux-kselftest/20200911181012.171027-1-cascardo@canonical.com/
Fixes: 58d0a862f573 ("seccomp: add tests for ptrace hole")
Acked-by: Christian Brauner <christian.brauner@ubuntu.com>
Link: https://lore.kernel.org/lkml/20200921075300.7iylzof2w5vrutah@wittgenstein/
Signed-off-by: Kees Cook <keescook@chromium.org>

+21 -4
+21 -4
tools/testing/selftests/seccomp/seccomp_bpf.c
··· 1765 1765 (_regs).ccr &= ~0x10000000; \ 1766 1766 } \ 1767 1767 } while (0) 1768 + # define SYSCALL_RET_SET_ON_PTRACE_EXIT 1768 1769 #elif defined(__s390__) 1769 1770 # define ARCH_REGS s390_regs 1770 1771 # define SYSCALL_NUM(_regs) (_regs).gprs[2] ··· 1852 1851 EXPECT_EQ(val, action); \ 1853 1852 } \ 1854 1853 } while (0) 1854 + #endif 1855 + 1856 + /* 1857 + * Some architectures (e.g. powerpc) can only set syscall 1858 + * return values on syscall exit during ptrace. 1859 + */ 1860 + const bool ptrace_entry_set_syscall_nr = true; 1861 + const bool ptrace_entry_set_syscall_ret = 1862 + #ifndef SYSCALL_RET_SET_ON_PTRACE_EXIT 1863 + true; 1864 + #else 1865 + false; 1855 1866 #endif 1856 1867 1857 1868 /* ··· 2019 2006 */ 2020 2007 if (entry) 2021 2008 self->syscall_nr = get_syscall(_metadata, tracee); 2022 - else 2023 - return; 2024 2009 2025 - syscall_nr = &syscall_nr_val; 2026 - syscall_ret = &syscall_ret_val; 2010 + /* 2011 + * Depending on the architecture's syscall setting abilities, we 2012 + * pick which things to set during this phase (entry or exit). 2013 + */ 2014 + if (entry == ptrace_entry_set_syscall_nr) 2015 + syscall_nr = &syscall_nr_val; 2016 + if (entry == ptrace_entry_set_syscall_ret) 2017 + syscall_ret = &syscall_ret_val; 2027 2018 2028 2019 /* Now handle the actual rewriting cases. */ 2029 2020 switch (self->syscall_nr) {