diff options
author | Paul Moore <paul@paul-moore.com> | 2017-02-15 19:10:35 -0500 |
---|---|---|
committer | Paul Moore <paul@paul-moore.com> | 2017-02-21 17:30:47 -0500 |
commit | dc879990774b5fe0b5d3362ae592e8a5bb615fbb (patch) | |
tree | 126b545a209cf8b4abf92f50dd4cb6b0f0f0325e /src | |
parent | a66f000de92c7ced17ae6615837dabafd803ae42 (diff) | |
download | libseccomp-dc879990774b5fe0b5d3362ae592e8a5bb615fbb.tar.gz |
all: treat syscall -1 as a valid syscall
Process tracers use a -1 syscall value to indicate that a syscall
should be skipped. This turns out to be quite an undertaking as
we need to workaround __NR_SCMP_ERROR (which also has a value of
-1). Pay special attention to the new attribute,
SCMP_FLTATR_API_TSKIP, and the documentation additions.
More information in the GitHub issue:
* https://github.com/seccomp/libseccomp/issues/80
Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/api.c | 11 | ||||
-rw-r--r-- | src/arch.c | 18 | ||||
-rw-r--r-- | src/db.c | 14 | ||||
-rw-r--r-- | src/db.h | 2 | ||||
-rw-r--r-- | src/python/libseccomp.pxd | 1 | ||||
-rw-r--r-- | src/python/seccomp.pyx | 1 |
6 files changed, 31 insertions, 16 deletions
@@ -65,8 +65,11 @@ static int _ctx_valid(const scmp_filter_ctx *ctx) * syscall appears valid, negative values on failure. * */ -static int _syscall_valid(int syscall) +static int _syscall_valid(const struct db_filter_col *col, int syscall) { + /* syscall -1 is used by tracers to skip the syscall */ + if (col->attr.api_tskip && syscall == -1) + return 0; if (syscall <= -1 && syscall >= -99) return -EINVAL; return 0; @@ -309,7 +312,7 @@ API int seccomp_syscall_priority(scmp_filter_ctx ctx, { struct db_filter_col *col = (struct db_filter_col *)ctx; - if (db_col_valid(col) || _syscall_valid(syscall)) + if (db_col_valid(col) || _syscall_valid(col, syscall)) return -EINVAL; return db_col_syscall_priority(col, syscall, priority); @@ -329,7 +332,7 @@ API int seccomp_rule_add_array(scmp_filter_ctx ctx, if (arg_cnt > 0 && arg_array == NULL) return -EINVAL; - if (db_col_valid(col) || _syscall_valid(syscall)) + if (db_col_valid(col) || _syscall_valid(col, syscall)) return -EINVAL; rc = db_action_valid(action); @@ -378,7 +381,7 @@ API int seccomp_rule_add_exact_array(scmp_filter_ctx ctx, if (arg_cnt > 0 && arg_array == NULL) return -EINVAL; - if (db_col_valid(col) || _syscall_valid(syscall)) + if (db_col_valid(col) || _syscall_valid(col, syscall)) return -EINVAL; rc = db_action_valid(action); @@ -330,6 +330,10 @@ int arch_syscall_translate(const struct arch_def *arch, int *syscall) int sc_num; const char *sc_name; + /* special handling for syscall -1 */ + if (*syscall == -1) + return 0; + if (arch->token != arch_def_native->token) { sc_name = arch_syscall_resolve_num(arch_def_native, *syscall); if (sc_name == NULL) @@ -360,10 +364,10 @@ int arch_syscall_rewrite(const struct arch_def *arch, int *syscall) { int sys = *syscall; - if (sys >= 0) { + if (sys >= -1) { /* we shouldn't be here - no rewrite needed */ return 0; - } else if (sys < 0 && sys > -100) { + } else if (sys < -1 && sys > -100) { /* reserved values */ return -EINVAL; } else if (sys <= -100 && sys > -10000) { @@ -404,10 +408,6 @@ int arch_filter_rule_add(struct db_filter_col *col, struct db_filter *db, int rc; struct db_api_rule_list *rule, *rule_tail; - /* ensure we aren't using any reserved syscall values */ - if (syscall < 0 && syscall > -100) - return -EINVAL; - /* translate the syscall */ rc = arch_syscall_translate(db->arch, &syscall); if (rc < 0) @@ -424,9 +424,9 @@ int arch_filter_rule_add(struct db_filter_col *col, struct db_filter *db, rule->next = NULL; /* add the new rule to the existing filter */ - if (db->arch->rule_add == NULL) { - /* negative syscalls require a db->arch->rule_add() function */ - if (syscall < 0 && strict) { + if (syscall == -1 || db->arch->rule_add == NULL) { + /* syscalls < -1 require a db->arch->rule_add() function */ + if (syscall < -1 && strict) { rc = -EDOM; goto rule_add_failure; } @@ -567,6 +567,7 @@ int db_col_reset(struct db_filter_col *col, uint32_t def_action) col->attr.act_badarch = SCMP_ACT_KILL; col->attr.nnp_enable = 1; col->attr.tsync_enable = 0; + col->attr.api_tskip = 0; /* set the state */ col->state = _DB_STA_VALID; @@ -788,6 +789,9 @@ int db_col_attr_get(const struct db_filter_col *col, case SCMP_FLTATR_CTL_TSYNC: *value = col->attr.tsync_enable; break; + case SCMP_FLTATR_API_TSKIP: + *value = col->attr.api_tskip; + break; default: rc = -EEXIST; break; @@ -835,6 +839,9 @@ int db_col_attr_set(struct db_filter_col *col, /* unsupported */ rc = -EOPNOTSUPP; break; + case SCMP_FLTATR_API_TSKIP: + col->attr.api_tskip = (value ? 1 : 0); + break; default: rc = -EEXIST; break; @@ -1523,9 +1530,10 @@ int db_col_syscall_priority(struct db_filter_col *col, if (rc_tmp < 0) goto priority_failure; - /* if this is a pseudo syscall (syscall < 0) then we need to - * rewrite the syscall for some arch specific reason */ - if (sc_tmp < 0) { + /* if this is a pseudo syscall then we need to rewrite the + * syscall for some arch specific reason, don't forget the + * special handling for syscall -1 */ + if (sc_tmp < -1) { /* we set this as a strict op - we don't really care * since priorities are a "best effort" thing - as we * want to catch the -EDOM error and bail on this @@ -137,6 +137,8 @@ struct db_filter_attr { uint32_t nnp_enable; /* SECCOMP_FILTER_FLAG_TSYNC related attributes */ uint32_t tsync_enable; + /* allow rules with a -1 syscall value */ + uint32_t api_tskip; }; struct db_filter { diff --git a/src/python/libseccomp.pxd b/src/python/libseccomp.pxd index 500da15..d58a417 100644 --- a/src/python/libseccomp.pxd +++ b/src/python/libseccomp.pxd @@ -56,6 +56,7 @@ cdef extern from "seccomp.h": SCMP_FLTATR_ACT_BADARCH SCMP_FLTATR_CTL_NNP SCMP_FLTATR_CTL_TSYNC + SCMP_FLTATR_API_TSKIP cdef enum scmp_compare: SCMP_CMP_NE diff --git a/src/python/seccomp.pyx b/src/python/seccomp.pyx index 3986f7d..275019a 100644 --- a/src/python/seccomp.pyx +++ b/src/python/seccomp.pyx @@ -273,6 +273,7 @@ cdef class Attr: ACT_BADARCH = libseccomp.SCMP_FLTATR_ACT_BADARCH CTL_NNP = libseccomp.SCMP_FLTATR_CTL_NNP CTL_TSYNC = libseccomp.SCMP_FLTATR_CTL_TSYNC + API_TSKIP = libseccomp.SCMP_FLTATR_API_TSKIP cdef class Arg: """ Python object representing a SyscallFilter syscall argument. |