diff options
author | Paul Moore <paul@paul-moore.com> | 2017-02-23 12:25:02 -0500 |
---|---|---|
committer | Paul Moore <paul@paul-moore.com> | 2017-02-23 12:25:02 -0500 |
commit | 10dd41eac56d08a27afe355e51675050feb13e18 (patch) | |
tree | 5754eff740d9d4ef277e43dab95ade483156f364 | |
parent | 50ed5c1e6eeb01a96448cb58cb8481e4150d3383 (diff) | |
download | libseccomp-10dd41eac56d08a27afe355e51675050feb13e18.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>
(imported from commit dc879990774b5fe0b5d3362ae592e8a5bb615fbb)
-rw-r--r-- | doc/man/man3/seccomp_attr_set.3 | 12 | ||||
-rw-r--r-- | doc/man/man3/seccomp_rule_add.3 | 11 | ||||
-rw-r--r-- | include/seccomp.h.in | 1 | ||||
-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 |
9 files changed, 53 insertions, 18 deletions
diff --git a/doc/man/man3/seccomp_attr_set.3 b/doc/man/man3/seccomp_attr_set.3 index 806b223..4658ed3 100644 --- a/doc/man/man3/seccomp_attr_set.3 +++ b/doc/man/man3/seccomp_attr_set.3 @@ -76,6 +76,15 @@ greater; attempting to enable this flag on earlier kernels will result in an error being returned. Defaults to off ( .I value == 0). +.TP +.B SCMP_FLTATR_ATL_TSKIP +A flag to specify if libseccomp should allow filter rules to be created for +the -1 syscall. The -1 syscall value can be used by tracer programs to skip +specific syscall invocations, see +.BR seccomp (2) +for more information. Defaults to off ( +.I value +== 0). .\" ////////////////////////////////////////////////////////////////////////// .SH RETURN VALUE .\" ////////////////////////////////////////////////////////////////////////// @@ -129,4 +138,5 @@ Paul Moore <paul@paul-moore.com> .\" ////////////////////////////////////////////////////////////////////////// .BR seccomp_init (3), .BR seccomp_reset (3), -.BR seccomp_load (3) +.BR seccomp_load (3), +.BR seccomp (2) diff --git a/doc/man/man3/seccomp_rule_add.3 b/doc/man/man3/seccomp_rule_add.3 index 8cac4df..70d7eaf 100644 --- a/doc/man/man3/seccomp_rule_add.3 +++ b/doc/man/man3/seccomp_rule_add.3 @@ -90,6 +90,14 @@ is highly recommended to use the .BR SCMP_SYS () macro instead. See the EXAMPLES section below. .P +Starting with Linux v4.8, there may be a need to create a rule with a syscall +value of -1 to allow tracing programs to skip a syscall invocation; in order +to create a rule with a -1 syscall value it is necessary to first set the +.B SCMP_FLTATR_API_TSKIP +attribute. See +.BR seccomp_attr_set (3) +for more information. +.P The filter context .I ctx is the value returned by the call to @@ -292,4 +300,5 @@ Paul Moore <paul@paul-moore.com> .\" ////////////////////////////////////////////////////////////////////////// .BR seccomp_syscall_resolve_name_rewrite (3), .BR seccomp_syscall_priority (3), -.BR seccomp_load (3) +.BR seccomp_load (3), +.BR seccomp_attr_set (3) diff --git a/include/seccomp.h.in b/include/seccomp.h.in index 70f1e20..f90407a 100644 --- a/include/seccomp.h.in +++ b/include/seccomp.h.in @@ -63,6 +63,7 @@ enum scmp_filter_attr { SCMP_FLTATR_ACT_BADARCH = 2, /**< bad architecture action */ SCMP_FLTATR_CTL_NNP = 3, /**< set NO_NEW_PRIVS on filter load */ SCMP_FLTATR_CTL_TSYNC = 4, /**< sync threads on filter load */ + SCMP_FLTATR_API_TSKIP = 5, /**< allow rules with a -1 syscall */ _SCMP_FLTATR_MAX, }; @@ -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; @@ -311,7 +314,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); @@ -331,7 +334,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); @@ -380,7 +383,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); @@ -317,6 +317,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) @@ -347,10 +351,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) { @@ -391,10 +395,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) @@ -411,9 +411,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; } @@ -570,6 +570,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; @@ -794,6 +795,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; @@ -841,6 +845,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; @@ -1534,9 +1541,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 15c94f8..235b859 100644 --- a/src/python/libseccomp.pxd +++ b/src/python/libseccomp.pxd @@ -54,6 +54,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 c87bc3f..076322c 100644 --- a/src/python/seccomp.pyx +++ b/src/python/seccomp.pyx @@ -246,6 +246,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. |