summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Moore <pmoore@redhat.com>2015-08-29 20:05:19 -0400
committerPaul Moore <pmoore@redhat.com>2015-08-29 20:05:19 -0400
commit0d287caf43792239b107ee3215b32b8bc901f9c3 (patch)
treef9c3249888ef712b11334203860adaec1265ef60
parent99bf257b614ed648bd139732fa9411acf833d8a6 (diff)
downloadlibseccomp-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.c4
-rw-r--r--src/system.h3
-rw-r--r--tests/11-basic-basic_errors.c10
-rwxr-xr-xtests/11-basic-basic_errors.py6
4 files changed, 22 insertions, 1 deletions
diff --git a/src/db.c b/src/db.c
index 37b334a..92ae958 100644
--- a/src/db.c
+++ b/src/db.c
@@ -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;