diff options
author | Mickaël Salaün <mic@digikod.net> | 2015-12-29 15:35:45 -0500 |
---|---|---|
committer | Richard Weinberger <richard@nod.at> | 2016-01-10 15:49:49 -0500 |
commit | 4a0b88070406323487bad730d8945f482151a145 (patch) | |
tree | d4d35cb43c578bab371a1b12e109373b972b348c | |
parent | e04c989eb785af61d2895d76d38c09166296f9c5 (diff) |
selftests/seccomp: Remove the need for HAVE_ARCH_TRACEHOOK
Some architectures do not implement PTRACE_GETREGSET nor
PTRACE_SETREGSET (required by HAVE_ARCH_TRACEHOOK) but only implement
PTRACE_GETREGS and PTRACE_SETREGS (e.g. User-mode Linux).
This improve seccomp selftest portability for architectures without
HAVE_ARCH_TRACEHOOK support by defining a new trigger HAVE_GETREGS. For
now, this is only enabled for i386 and x86_64 architectures. This is
required to be able to run this tests on User-mode Linux.
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: Kees Cook <keescook@chromium.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Will Drewry <wad@chromium.org>
Cc: Shuah Khan <shuahkh@osg.samsung.com>
Cc: Meredydd Luff <meredydd@senatehouse.org>
Cc: David Drysdale <drysdale@google.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
Acked-by: Kees Cook <keescook@chromium.org>
-rw-r--r-- | tools/testing/selftests/seccomp/seccomp_bpf.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index 882fe83a3554..b9453b838162 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c | |||
@@ -1246,11 +1246,24 @@ TEST_F(TRACE_poke, getpid_runs_normally) | |||
1246 | # error "Do not know how to find your architecture's registers and syscalls" | 1246 | # error "Do not know how to find your architecture's registers and syscalls" |
1247 | #endif | 1247 | #endif |
1248 | 1248 | ||
1249 | /* Use PTRACE_GETREGS and PTRACE_SETREGS when available. This is useful for | ||
1250 | * architectures without HAVE_ARCH_TRACEHOOK (e.g. User-mode Linux). | ||
1251 | */ | ||
1252 | #if defined(__x86_64__) || defined(__i386__) | ||
1253 | #define HAVE_GETREGS | ||
1254 | #endif | ||
1255 | |||
1249 | /* Architecture-specific syscall fetching routine. */ | 1256 | /* Architecture-specific syscall fetching routine. */ |
1250 | int get_syscall(struct __test_metadata *_metadata, pid_t tracee) | 1257 | int get_syscall(struct __test_metadata *_metadata, pid_t tracee) |
1251 | { | 1258 | { |
1252 | struct iovec iov; | ||
1253 | ARCH_REGS regs; | 1259 | ARCH_REGS regs; |
1260 | #ifdef HAVE_GETREGS | ||
1261 | EXPECT_EQ(0, ptrace(PTRACE_GETREGS, tracee, 0, ®s)) { | ||
1262 | TH_LOG("PTRACE_GETREGS failed"); | ||
1263 | return -1; | ||
1264 | } | ||
1265 | #else | ||
1266 | struct iovec iov; | ||
1254 | 1267 | ||
1255 | iov.iov_base = ®s; | 1268 | iov.iov_base = ®s; |
1256 | iov.iov_len = sizeof(regs); | 1269 | iov.iov_len = sizeof(regs); |
@@ -1258,6 +1271,7 @@ int get_syscall(struct __test_metadata *_metadata, pid_t tracee) | |||
1258 | TH_LOG("PTRACE_GETREGSET failed"); | 1271 | TH_LOG("PTRACE_GETREGSET failed"); |
1259 | return -1; | 1272 | return -1; |
1260 | } | 1273 | } |
1274 | #endif | ||
1261 | 1275 | ||
1262 | return regs.SYSCALL_NUM; | 1276 | return regs.SYSCALL_NUM; |
1263 | } | 1277 | } |
@@ -1266,13 +1280,16 @@ int get_syscall(struct __test_metadata *_metadata, pid_t tracee) | |||
1266 | void change_syscall(struct __test_metadata *_metadata, | 1280 | void change_syscall(struct __test_metadata *_metadata, |
1267 | pid_t tracee, int syscall) | 1281 | pid_t tracee, int syscall) |
1268 | { | 1282 | { |
1269 | struct iovec iov; | ||
1270 | int ret; | 1283 | int ret; |
1271 | ARCH_REGS regs; | 1284 | ARCH_REGS regs; |
1272 | 1285 | #ifdef HAVE_GETREGS | |
1286 | ret = ptrace(PTRACE_GETREGS, tracee, 0, ®s); | ||
1287 | #else | ||
1288 | struct iovec iov; | ||
1273 | iov.iov_base = ®s; | 1289 | iov.iov_base = ®s; |
1274 | iov.iov_len = sizeof(regs); | 1290 | iov.iov_len = sizeof(regs); |
1275 | ret = ptrace(PTRACE_GETREGSET, tracee, NT_PRSTATUS, &iov); | 1291 | ret = ptrace(PTRACE_GETREGSET, tracee, NT_PRSTATUS, &iov); |
1292 | #endif | ||
1276 | EXPECT_EQ(0, ret); | 1293 | EXPECT_EQ(0, ret); |
1277 | 1294 | ||
1278 | #if defined(__x86_64__) || defined(__i386__) || defined(__powerpc__) || \ | 1295 | #if defined(__x86_64__) || defined(__i386__) || defined(__powerpc__) || \ |
@@ -1312,9 +1329,13 @@ void change_syscall(struct __test_metadata *_metadata, | |||
1312 | if (syscall == -1) | 1329 | if (syscall == -1) |
1313 | regs.SYSCALL_RET = 1; | 1330 | regs.SYSCALL_RET = 1; |
1314 | 1331 | ||
1332 | #ifdef HAVE_GETREGS | ||
1333 | ret = ptrace(PTRACE_SETREGS, tracee, 0, ®s); | ||
1334 | #else | ||
1315 | iov.iov_base = ®s; | 1335 | iov.iov_base = ®s; |
1316 | iov.iov_len = sizeof(regs); | 1336 | iov.iov_len = sizeof(regs); |
1317 | ret = ptrace(PTRACE_SETREGSET, tracee, NT_PRSTATUS, &iov); | 1337 | ret = ptrace(PTRACE_SETREGSET, tracee, NT_PRSTATUS, &iov); |
1338 | #endif | ||
1318 | EXPECT_EQ(0, ret); | 1339 | EXPECT_EQ(0, ret); |
1319 | } | 1340 | } |
1320 | 1341 | ||