Skip to content

Commit f04cf78

Browse files
committed
selftests/seccomp: Remove SYSCALL_NUM_RET_SHARE_REG in favor of SYSCALL_RET_SET
Instead of special-casing the specific case of shared registers, create a default SYSCALL_RET_SET() macro (mirroring SYSCALL_NUM_SET()), that writes to the SYSCALL_RET register. For architectures that can't set the return value (for whatever reason), they can define SYSCALL_RET_SET() without an associated SYSCALL_RET() macro. This also paves the way for architectures that need to do special things to set the return value (e.g. powerpc). Signed-off-by: Kees Cook <keescook@chromium.org> Link: https://lore.kernel.org/lkml/20200912110820.597135-12-keescook@chromium.org Acked-by: Christian Brauner <christian.brauner@ubuntu.com>
1 parent e4e8e5d commit f04cf78

1 file changed

Lines changed: 23 additions & 10 deletions

File tree

tools/testing/selftests/seccomp/seccomp_bpf.c

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1753,8 +1753,8 @@ TEST_F(TRACE_poke, getpid_runs_normally)
17531753
#elif defined(__s390__)
17541754
# define ARCH_REGS s390_regs
17551755
# define SYSCALL_NUM(_regs) (_regs).gprs[2]
1756-
# define SYSCALL_RET(_regs) (_regs).gprs[2]
1757-
# define SYSCALL_NUM_RET_SHARE_REG
1756+
# define SYSCALL_RET_SET(_regs, _val) \
1757+
TH_LOG("Can't modify syscall return on this architecture")
17581758
#elif defined(__mips__)
17591759
# include <asm/unistd_nr_n32.h>
17601760
# include <asm/unistd_nr_n64.h>
@@ -1776,8 +1776,8 @@ TEST_F(TRACE_poke, getpid_runs_normally)
17761776
else \
17771777
(_regs).regs[2] = _nr; \
17781778
} while (0)
1779-
# define SYSCALL_RET(_regs) (_regs).regs[2]
1780-
# define SYSCALL_NUM_RET_SHARE_REG
1779+
# define SYSCALL_RET_SET(_regs, _val) \
1780+
TH_LOG("Can't modify syscall return on this architecture")
17811781
#elif defined(__xtensa__)
17821782
# define ARCH_REGS struct user_pt_regs
17831783
# define SYSCALL_NUM(_regs) (_regs).syscall
@@ -1804,9 +1804,26 @@ TEST_F(TRACE_poke, getpid_runs_normally)
18041804
SYSCALL_NUM(_regs) = (_nr); \
18051805
} while (0)
18061806
#endif
1807+
/*
1808+
* Most architectures can change the syscall return value by just
1809+
* writing to the SYSCALL_RET register. This is the default if not
1810+
* defined above. If an architecture cannot set the return value
1811+
* (for example when the syscall and return value register is
1812+
* shared), report it with TH_LOG() in an arch-specific definition
1813+
* of SYSCALL_RET_SET() above, and leave SYSCALL_RET undefined.
1814+
*/
1815+
#if !defined(SYSCALL_RET) && !defined(SYSCALL_RET_SET)
1816+
# error "One of SYSCALL_RET or SYSCALL_RET_SET is needed for this arch"
1817+
#endif
1818+
#ifndef SYSCALL_RET_SET
1819+
# define SYSCALL_RET_SET(_regs, _val) \
1820+
do { \
1821+
SYSCALL_RET(_regs) = (_val); \
1822+
} while (0)
1823+
#endif
18071824

18081825
/* When the syscall return can't be changed, stub out the tests for it. */
1809-
#ifdef SYSCALL_NUM_RET_SHARE_REG
1826+
#ifndef SYSCALL_RET
18101827
# define EXPECT_SYSCALL_RETURN(val, action) EXPECT_EQ(-1, action)
18111828
#else
18121829
# define EXPECT_SYSCALL_RETURN(val, action) \
@@ -1870,11 +1887,7 @@ void change_syscall(struct __test_metadata *_metadata,
18701887

18711888
/* If syscall is skipped, change return value. */
18721889
if (syscall == -1)
1873-
#ifdef SYSCALL_NUM_RET_SHARE_REG
1874-
TH_LOG("Can't modify syscall return on this architecture");
1875-
#else
1876-
SYSCALL_RET(regs) = result;
1877-
#endif
1890+
SYSCALL_RET_SET(regs, result);
18781891

18791892
/* Flush any register changes made. */
18801893
if (memcmp(&orig, &regs, sizeof(orig)) != 0)

0 commit comments

Comments
 (0)