Skip to content

Commit

Permalink
tests: change test 53 to use syscall names rather than numbers
Browse files Browse the repository at this point in the history
Previously test 53, sim-binary_tree, used syscall numbers to build
a large binary tree.  This is problematic on architectures that
have sparsely populated syscall numbers.

This commit modifies the test to use syscall names to build up a
realistic binary tree that should work on all architectures.

Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
  • Loading branch information
drakenclimber authored and pcmoore committed Mar 10, 2020
1 parent 00afcff commit 070c784
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 366 deletions.
110 changes: 80 additions & 30 deletions tests/53-sim-binary_tree.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Seccomp Library test program
*
* Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018-2020 Oracle and/or its affiliates.
* Author: Tom Hromatka <tom.hromatka@oracle.com>
*/

Expand Down Expand Up @@ -29,9 +29,61 @@

#include "util.h"

#define MAX_SYSCALL (330)
#define ARG_COUNT_MAX 2

#include <stdio.h>
struct syscall_errno {
int syscall;
int error;
int arg_cnt;
/* To make the test more interesting, arguments are added to several
* syscalls. To keep the test simple, the arguments always use
* SCMP_CMP_EQ.
*/
int args[ARG_COUNT_MAX];
};

struct syscall_errno table[] = {
{ SCMP_SYS(read), 0, 0, { 0, 0 } },
{ SCMP_SYS(write), 1, 0, { 0, 0 } },
{ SCMP_SYS(open), 2, 0, { 0, 0 } },
{ SCMP_SYS(close), 3, 2, { 100, 101 } },
{ SCMP_SYS(stat), 4, 0, { 0, 0 } },
{ SCMP_SYS(fstat), 5, 0, { 0, 0 } },
{ SCMP_SYS(lstat), 6, 0, { 0, 0 } },
{ SCMP_SYS(poll), 7, 1, { 102, 0 } },
{ SCMP_SYS(lseek), 8, 2, { 103, 104 } },
{ SCMP_SYS(mmap), 9, 0, { 0, 0 } },
{ SCMP_SYS(mprotect), 10, 0, { 0, 0 } },
{ SCMP_SYS(munmap), 11, 0, { 0, 0 } },
{ SCMP_SYS(brk), 12, 0, { 0, 0 } },
{ SCMP_SYS(rt_sigaction), 13, 0, { 0, 0 } },
{ SCMP_SYS(rt_sigprocmask), 14, 0, { 0, 0 } },
{ SCMP_SYS(rt_sigreturn), 15, 0, { 0, 0 } },
{ SCMP_SYS(ioctl), 16, 0, { 0, 0 } },
{ SCMP_SYS(pread64), 17, 1, { 105, 0 } },
{ SCMP_SYS(pwrite64), 18, 0, { 0, 0 } },
{ SCMP_SYS(readv), 19, 0, { 0, 0 } },
{ SCMP_SYS(writev), 20, 0, { 0, 0 } },
{ SCMP_SYS(access), 21, 0, { 0, 0 } },
{ SCMP_SYS(pipe), 22, 0, { 0, 0 } },
{ SCMP_SYS(select), 23, 2, { 106, 107 } },
{ SCMP_SYS(sched_yield), 24, 0, { 0, 0 } },
{ SCMP_SYS(mremap), 25, 2, { 108, 109 } },
{ SCMP_SYS(msync), 26, 0, { 0, 0 } },
{ SCMP_SYS(mincore), 27, 0, { 0, 0 } },
{ SCMP_SYS(madvise), 28, 0, { 0, 0 } },
{ SCMP_SYS(shmget), 29, 0, { 0, 0 } },
{ SCMP_SYS(shmat), 30, 1, { 110, 0 } },
{ SCMP_SYS(shmctl), 31, 1, { 111, 0 } },
{ SCMP_SYS(dup), 32, 1, { 112, 0 } },
{ SCMP_SYS(dup2), 33, 0, { 0, 0 } },
{ SCMP_SYS(pause), 34, 0, { 0, 0 } },
{ SCMP_SYS(nanosleep), 35, 0, { 0, 0 } },
{ SCMP_SYS(getitimer), 36, 0, { 0, 0 } },
{ SCMP_SYS(alarm), 37, 0, { 0, 0 } },
};

const int table_size = sizeof(table) / sizeof(table[0]);

int main(int argc, char *argv[])
{
Expand All @@ -49,38 +101,36 @@ int main(int argc, char *argv[])
goto out;
}

rc = seccomp_arch_remove(ctx, SCMP_ARCH_NATIVE);
if (rc < 0)
goto out;
rc = seccomp_arch_add(ctx, SCMP_ARCH_X86_64);
if (rc < 0)
goto out;
rc = seccomp_arch_add(ctx, SCMP_ARCH_X86);
if (rc < 0)
goto out;
rc = seccomp_attr_set(ctx, SCMP_FLTATR_CTL_OPTIMIZE, 2);
if (rc < 0)
goto out;

/* NOTE: this test is entirely fabricated and should not be
* replicated in the real world.
*
* The MAX_SYSCALL number (330) was chosen to force seccomp to
* build an unbalanced binary tree - and it happens to be less
* than the current syscall max. The syscall numbers are
* hardcoded to simplify the test. A few syscalls have
* argument chains to further complicate the filter.
*/
for (i = 0; i < table_size; i++) {
switch (table[i].arg_cnt) {
case 2:
rc = seccomp_rule_add(ctx,
SCMP_ACT_ERRNO(table[i].error),
table[i].syscall, 2,
SCMP_A0(SCMP_CMP_EQ,
table[i].args[0]),
SCMP_A1(SCMP_CMP_EQ,
table[i].args[1]));
break;
case 1:
rc = seccomp_rule_add(ctx,
SCMP_ACT_ERRNO(table[i].error),
table[i].syscall, 1,
SCMP_A0(SCMP_CMP_EQ,
table[i].args[0]));
break;
case 0:
default:
rc = seccomp_rule_add(ctx,
SCMP_ACT_ERRNO(table[i].error),
table[i].syscall, 0);
break;
}

for (i = 0; i < MAX_SYSCALL; i++) {
/* arbitrarily make the filter more complex by filtering
* on arguments for a few syscalls
*/
if (i == 10 || i == 53 || i == 61 || i == 255)
rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(i), i, 1,
SCMP_A0(SCMP_CMP_EQ, i));
else
rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(i), i, 0);
if (rc < 0)
goto out;
}
Expand Down
55 changes: 51 additions & 4 deletions tests/53-sim-binary_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,47 @@

from seccomp import *

table = [
{"syscall": "read", "error": 0, "arg_cnt": 0 },
{"syscall": "write", "error": 1, "arg_cnt": 0 },
{"syscall": "open", "error": 2, "arg_cnt": 0 },
{"syscall": "close", "error": 3, "arg_cnt": 2, "arg1": 100, "arg2": 101 },
{"syscall": "stat", "error": 4, "arg_cnt": 0 },
{"syscall": "fstat", "error": 5, "arg_cnt": 0 },
{"syscall": "lstat", "error": 6, "arg_cnt": 0 },
{"syscall": "poll", "error": 7, "arg_cnt": 1, "arg1": 102 },
{"syscall": "lseek", "error": 8, "arg_cnt": 2, "arg1": 103, "arg2": 104 },
{"syscall": "mmap", "error": 9, "arg_cnt": 0 },
{"syscall": "mprotect", "error": 10, "arg_cnt": 0 },
{"syscall": "munmap", "error": 11, "arg_cnt": 0 },
{"syscall": "brk", "error": 12, "arg_cnt": 0 },
{"syscall": "rt_sigaction", "error": 13, "arg_cnt": 0 },
{"syscall": "rt_sigprocmask", "error": 14, "arg_cnt": 0 },
{"syscall": "rt_sigreturn", "error": 15, "arg_cnt": 0 },
{"syscall": "ioctl", "error": 16, "arg_cnt": 0 },
{"syscall": "pread64", "error": 17, "arg_cnt": 1, "arg1": 105 },
{"syscall": "pwrite64", "error": 18, "arg_cnt": 0 },
{"syscall": "readv", "error": 19, "arg_cnt": 0 },
{"syscall": "writev", "error": 20, "arg_cnt": 0 },
{"syscall": "access", "error": 21, "arg_cnt": 0 },
{"syscall": "pipe", "error": 22, "arg_cnt": 0 },
{"syscall": "select", "error": 23, "arg_cnt": 2, "arg1": 106, "arg2": 107 },
{"syscall": "sched_yield", "error": 24, "arg_cnt": 0 },
{"syscall": "mremap", "error": 25, "arg_cnt": 2, "arg1": 108, "arg2": 109 },
{"syscall": "msync", "error": 26, "arg_cnt": 0 },
{"syscall": "mincore", "error": 27, "arg_cnt": 0 },
{"syscall": "madvise", "error": 28, "arg_cnt": 0 },
{"syscall": "shmget", "error": 29, "arg_cnt": 0 },
{"syscall": "shmat", "error": 30, "arg_cnt": 1, "arg1": 110 },
{"syscall": "shmctl", "error": 31, "arg_cnt": 1, "arg1": 111 },
{"syscall": "dup", "error": 32, "arg_cnt": 1, "arg1": 112 },
{"syscall": "dup2", "error": 33, "arg_cnt": 0 },
{"syscall": "pause", "error": 34, "arg_cnt": 0 },
{"syscall": "nanosleep", "error": 35, "arg_cnt": 0 },
{"syscall": "getitimer", "error": 36, "arg_cnt": 0 },
{"syscall": "alarm", "error": 37, "arg_cnt": 0 },
]

def test(args):
f = SyscallFilter(ALLOW)

Expand All @@ -36,11 +77,17 @@ def test(args):
f.add_arch(Arch("x86"))
f.set_attr(Attr.CTL_OPTIMIZE, 2)

for i in range(330):
if (i == 10 or i == 53 or i == 61 or i == 255):
f.add_rule(ERRNO(i), i, Arg(0, EQ, i))
for entry in table:
print(entry)
if entry["arg_cnt"] == 2:
f.add_rule(ERRNO(entry["error"]), entry["syscall"],
Arg(0, EQ, entry["arg1"]),
Arg(1, EQ, entry["arg2"]))
elif entry["arg_cnt"] == 1:
f.add_rule(ERRNO(entry["error"]), entry["syscall"],
Arg(0, EQ, entry["arg1"]))
else:
f.add_rule(ERRNO(i), i)
f.add_rule(ERRNO(entry["error"]), entry["syscall"])

return f

Expand Down
Loading

0 comments on commit 070c784

Please sign in to comment.