diff options
author | Paul Moore <pmoore@redhat.com> | 2015-08-29 20:05:19 -0400 |
---|---|---|
committer | Paul Moore <pmoore@redhat.com> | 2015-08-29 20:05:19 -0400 |
commit | 0d287caf43792239b107ee3215b32b8bc901f9c3 (patch) | |
tree | f9c3249888ef712b11334203860adaec1265ef60 | |
parent | 99bf257b614ed648bd139732fa9411acf833d8a6 (diff) | |
download | libseccomp-0d287caf43792239b107ee3215b32b8bc901f9c3.tar.gz |
api: limit errno values to MAX_ERRNO
It turns out that userspace behaves oddly when given an errno value
greater than MAX_ERRNO, so much so that the kernel seccomp mechanism
has started blocking filters with bad errno values. Let's try to
catch the problem at rule addition time to make things easier to
spot and fix.
Signed-off-by: Paul Moore <pmoore@redhat.com>
-rw-r--r-- | src/db.c | 4 | ||||
-rw-r--r-- | src/system.h | 3 | ||||
-rw-r--r-- | tests/11-basic-basic_errors.c | 10 | ||||
-rwxr-xr-x | tests/11-basic-basic_errors.py | 6 |
4 files changed, 22 insertions, 1 deletions
@@ -30,6 +30,7 @@ #include "arch.h" #include "db.h" +#include "system.h" /* state values */ #define _DB_STA_VALID 0xA1B2C3D4 @@ -358,7 +359,8 @@ int db_action_valid(uint32_t action) return 0; else if (action == SCMP_ACT_TRAP) return 0; - else if (action == SCMP_ACT_ERRNO(action & 0x0000ffff)) + else if ((action == SCMP_ACT_ERRNO(action & 0x0000ffff)) && + ((action & 0x0000ffff) < MAX_ERRNO)) return 0; else if (action == SCMP_ACT_TRACE(action & 0x0000ffff)) return 0; diff --git a/src/system.h b/src/system.h index a0536d4..4660679 100644 --- a/src/system.h +++ b/src/system.h @@ -27,6 +27,9 @@ #include "configure.h" +/* NOTE: this was taken from the Linux Kernel sources */ +#define MAX_ERRNO 4095 + struct db_filter_col; #ifdef HAVE_LINUX_SECCOMP_H diff --git a/tests/11-basic-basic_errors.c b/tests/11-basic-basic_errors.c index f2559d5..f615584 100644 --- a/tests/11-basic-basic_errors.c +++ b/tests/11-basic-basic_errors.c @@ -130,6 +130,16 @@ int main(int argc, char *argv[]) seccomp_release(ctx); ctx = NULL; + /* errno values beyond MAX_ERRNO */ + ctx = seccomp_init(SCMP_ACT_ALLOW); + if (ctx == NULL) + return -1; + rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(0xffff), 0, 0); + if (rc != -EINVAL) + return -1; + seccomp_release(ctx); + ctx = NULL; + /* seccomp_export_pfc errors */ rc = seccomp_export_pfc(ctx, STDOUT_FILENO); if (rc != -EINVAL) diff --git a/tests/11-basic-basic_errors.py b/tests/11-basic-basic_errors.py index 10e5d7d..915c241 100755 --- a/tests/11-basic-basic_errors.py +++ b/tests/11-basic-basic_errors.py @@ -81,6 +81,12 @@ def test(): except RuntimeError: pass + f = SyscallFilter(ALLOW) + try: + f.add_rule(ERRNO(0xffff), "read") + except RuntimeError: + pass + test() # kate: syntax python; |