aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Sesek <rsesek@google.com>2015-11-02 15:28:49 -0500
committerShuah Khan <shuahkh@osg.samsung.com>2015-11-02 16:41:02 -0500
commitfd88d16c58c2ad689a68d6790c789e7d5be3fc5b (patch)
treec5428d64cb4c8942cac53694828bf261f9b76f08
parent256d0afb11d6e878e8c793e4a6e3bbfb81f9aae8 (diff)
selftests/seccomp: Be more precise with syscall arguments.
Certain syscall emulation layers strictly check that the number of arguments match what the syscall handler expects. The KILL_one_arg_one and KILL_one_arg_six tests passed more parameters than expected to various syscalls, causing failures in this emulation mode. Instead, test using syscalls that take the appropriate number of arguments. Signed-off-by: Robert Sesek <rsesek@google.com> Signed-off-by: Kees Cook <keescook@chromium.org> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
-rw-r--r--tools/testing/selftests/seccomp/seccomp_bpf.c46
1 files changed, 35 insertions, 11 deletions
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
index e7bc5d3533da..e38cc54942db 100644
--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
+++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
@@ -29,6 +29,9 @@
29#include <linux/elf.h> 29#include <linux/elf.h>
30#include <sys/uio.h> 30#include <sys/uio.h>
31#include <sys/utsname.h> 31#include <sys/utsname.h>
32#include <sys/fcntl.h>
33#include <sys/mman.h>
34#include <sys/times.h>
32 35
33#define _GNU_SOURCE 36#define _GNU_SOURCE
34#include <unistd.h> 37#include <unistd.h>
@@ -429,14 +432,16 @@ TEST_SIGNAL(KILL_one, SIGSYS)
429 432
430TEST_SIGNAL(KILL_one_arg_one, SIGSYS) 433TEST_SIGNAL(KILL_one_arg_one, SIGSYS)
431{ 434{
435 void *fatal_address;
432 struct sock_filter filter[] = { 436 struct sock_filter filter[] = {
433 BPF_STMT(BPF_LD|BPF_W|BPF_ABS, 437 BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
434 offsetof(struct seccomp_data, nr)), 438 offsetof(struct seccomp_data, nr)),
435 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0), 439 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_times, 1, 0),
436 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW), 440 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
437 /* Only both with lower 32-bit for now. */ 441 /* Only both with lower 32-bit for now. */
438 BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_arg(0)), 442 BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_arg(0)),
439 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 0x0C0FFEE, 0, 1), 443 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K,
444 (unsigned long)&fatal_address, 0, 1),
440 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL), 445 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),
441 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW), 446 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
442 }; 447 };
@@ -446,7 +451,8 @@ TEST_SIGNAL(KILL_one_arg_one, SIGSYS)
446 }; 451 };
447 long ret; 452 long ret;
448 pid_t parent = getppid(); 453 pid_t parent = getppid();
449 pid_t pid = getpid(); 454 struct tms timebuf;
455 clock_t clock = times(&timebuf);
450 456
451 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); 457 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
452 ASSERT_EQ(0, ret); 458 ASSERT_EQ(0, ret);
@@ -455,17 +461,22 @@ TEST_SIGNAL(KILL_one_arg_one, SIGSYS)
455 ASSERT_EQ(0, ret); 461 ASSERT_EQ(0, ret);
456 462
457 EXPECT_EQ(parent, syscall(__NR_getppid)); 463 EXPECT_EQ(parent, syscall(__NR_getppid));
458 EXPECT_EQ(pid, syscall(__NR_getpid)); 464 EXPECT_LE(clock, syscall(__NR_times, &timebuf));
459 /* getpid() should never return. */ 465 /* times() should never return. */
460 EXPECT_EQ(0, syscall(__NR_getpid, 0x0C0FFEE)); 466 EXPECT_EQ(0, syscall(__NR_times, &fatal_address));
461} 467}
462 468
463TEST_SIGNAL(KILL_one_arg_six, SIGSYS) 469TEST_SIGNAL(KILL_one_arg_six, SIGSYS)
464{ 470{
471#ifndef __NR_mmap2
472 int sysno = __NR_mmap;
473#else
474 int sysno = __NR_mmap2;
475#endif
465 struct sock_filter filter[] = { 476 struct sock_filter filter[] = {
466 BPF_STMT(BPF_LD|BPF_W|BPF_ABS, 477 BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
467 offsetof(struct seccomp_data, nr)), 478 offsetof(struct seccomp_data, nr)),
468 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0), 479 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, sysno, 1, 0),
469 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW), 480 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
470 /* Only both with lower 32-bit for now. */ 481 /* Only both with lower 32-bit for now. */
471 BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_arg(5)), 482 BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_arg(5)),
@@ -479,7 +490,8 @@ TEST_SIGNAL(KILL_one_arg_six, SIGSYS)
479 }; 490 };
480 long ret; 491 long ret;
481 pid_t parent = getppid(); 492 pid_t parent = getppid();
482 pid_t pid = getpid(); 493 int fd;
494 void *map1, *map2;
483 495
484 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); 496 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
485 ASSERT_EQ(0, ret); 497 ASSERT_EQ(0, ret);
@@ -487,10 +499,22 @@ TEST_SIGNAL(KILL_one_arg_six, SIGSYS)
487 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog); 499 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
488 ASSERT_EQ(0, ret); 500 ASSERT_EQ(0, ret);
489 501
502 fd = open("/dev/zero", O_RDONLY);
503 ASSERT_NE(-1, fd);
504
490 EXPECT_EQ(parent, syscall(__NR_getppid)); 505 EXPECT_EQ(parent, syscall(__NR_getppid));
491 EXPECT_EQ(pid, syscall(__NR_getpid)); 506 map1 = (void *)syscall(sysno,
492 /* getpid() should never return. */ 507 NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, fd, PAGE_SIZE);
493 EXPECT_EQ(0, syscall(__NR_getpid, 1, 2, 3, 4, 5, 0x0C0FFEE)); 508 EXPECT_NE(MAP_FAILED, map1);
509 /* mmap2() should never return. */
510 map2 = (void *)syscall(sysno,
511 NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, fd, 0x0C0FFEE);
512 EXPECT_EQ(MAP_FAILED, map2);
513
514 /* The test failed, so clean up the resources. */
515 munmap(map1, PAGE_SIZE);
516 munmap(map2, PAGE_SIZE);
517 close(fd);
494} 518}
495 519
496/* TODO(wad) add 64-bit versus 32-bit arg tests. */ 520/* TODO(wad) add 64-bit versus 32-bit arg tests. */