summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Moore <paul@paul-moore.com>2017-02-23 12:25:02 -0500
committerPaul Moore <paul@paul-moore.com>2017-02-23 12:25:02 -0500
commit10dd41eac56d08a27afe355e51675050feb13e18 (patch)
tree5754eff740d9d4ef277e43dab95ade483156f364
parent50ed5c1e6eeb01a96448cb58cb8481e4150d3383 (diff)
downloadlibseccomp-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.312
-rw-r--r--doc/man/man3/seccomp_rule_add.311
-rw-r--r--include/seccomp.h.in1
-rw-r--r--src/api.c11
-rw-r--r--src/arch.c18
-rw-r--r--src/db.c14
-rw-r--r--src/db.h2
-rw-r--r--src/python/libseccomp.pxd1
-rw-r--r--src/python/seccomp.pyx1
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,
};
diff --git a/src/api.c b/src/api.c
index 7d5b1ec..6dfee15 100644
--- a/src/api.c
+++ b/src/api.c
@@ -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);
diff --git a/src/arch.c b/src/arch.c
index f6c093c..e05a7f2 100644
--- a/src/arch.c
+++ b/src/arch.c
@@ -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;
}
diff --git a/src/db.c b/src/db.c
index 37f013c..8960fcd 100644
--- a/src/db.c
+++ b/src/db.c
@@ -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
diff --git a/src/db.h b/src/db.h
index 687e777..c4ad549 100644
--- a/src/db.h
+++ b/src/db.h
@@ -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.