summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Moore <pmoore@redhat.com>2014-08-20 16:42:38 -0400
committerPaul Moore <pmoore@redhat.com>2014-08-21 14:52:53 -0400
commit1123a31f7ab7dcc6e77f5b125aef9c605b379150 (patch)
tree8522fe8c05790b9763534adceb98bbce805afaa1
parent97a1710da19e6365a826953e629bd5410cadc9d3 (diff)
downloadlibseccomp-1123a31f7ab7dcc6e77f5b125aef9c605b379150.tar.gz
system: add initial support for the new seccomp() syscall
The new seccomp() syscall makes an appearance in Linux 3.17. Signed-off-by: Paul Moore <pmoore@redhat.com>
-rw-r--r--configure.ac6
-rw-r--r--src/Makefile.am2
-rw-r--r--src/api.c20
-rw-r--r--src/system.c71
-rw-r--r--src/system.h30
5 files changed, 103 insertions, 26 deletions
diff --git a/configure.ac b/configure.ac
index be2ffd5..8cdf4e5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -76,6 +76,12 @@ AC_SUBST([VERSION_MINOR])
AC_SUBST([VERSION_MICRO])
dnl ####
+dnl function checks
+dnl ####
+dnl # NOTE: keep this disabled until we can test on a released 3.17 kernel
+dnl AC_CHECK_FUNCS(seccomp)
+
+dnl ####
dnl cython checks
dnl ####
AC_CHECK_PROG(have_cython, cython, "yes", "no")
diff --git a/src/Makefile.am b/src/Makefile.am
index 271a562..2d1db37 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -32,7 +32,7 @@ SOURCES_ARCH = \
arch-mips64n32.h arch-mips64n32.c arch-mips64n32-syscalls.c
SOURCES_GEN = \
- api.c system.h \
+ api.c system.h system.c \
db.h db.c \
hash.h hash.c \
gen_pfc.h gen_pfc.c gen_bpf.h gen_bpf.c
diff --git a/src/api.c b/src/api.c
index 0c29e29..4c9cebe 100644
--- a/src/api.c
+++ b/src/api.c
@@ -27,7 +27,6 @@
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
-#include <sys/prctl.h>
#include <seccomp.h>
@@ -225,30 +224,13 @@ API int seccomp_arch_remove(scmp_filter_ctx ctx, uint32_t arch_token)
/* NOTE - function header comment in include/seccomp.h */
API int seccomp_load(const scmp_filter_ctx ctx)
{
- int rc;
struct db_filter_col *col;
- struct bpf_program *program;
if (_ctx_valid(ctx))
return -EINVAL;
col = (struct db_filter_col *)ctx;
- program = gen_bpf_generate((struct db_filter_col *)ctx);
- if (program == NULL)
- return -ENOMEM;
- /* attempt to set NO_NEW_PRIVS */
- if (col->attr.nnp_enable) {
- rc = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
- if (rc < 0)
- return -errno;
- }
- /* load the filter into the kernel */
- rc = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, program);
- gen_bpf_release(program);
- if (rc < 0)
- return -errno;
-
- return 0;
+ return sys_filter_load(col);
}
/* NOTE - function header comment in include/seccomp.h */
diff --git a/src/system.c b/src/system.c
new file mode 100644
index 0000000..fcbaec9
--- /dev/null
+++ b/src/system.c
@@ -0,0 +1,71 @@
+/**
+ * Seccomp System Interfaces
+ *
+ * Copyright (c) 2014 Red Hat <pmoore@redhat.com>
+ * Author: Paul Moore <pmoore@redhat.com>
+ */
+
+/*
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses>.
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/prctl.h>
+
+#include <seccomp.h>
+
+#include "db.h"
+#include "gen_bpf.h"
+#include "system.h"
+
+/**
+ * Loads the filter into the kernel
+ * @param col the filter collection
+ *
+ * This function loads the given seccomp filter context into the kernel. If
+ * the filter was loaded correctly, the kernel will be enforcing the filter
+ * when this function returns. Returns zero on success, negative values on
+ * error.
+ *
+ */
+int sys_filter_load(const struct db_filter_col *col)
+{
+ int rc;
+ struct bpf_program *program = NULL;
+
+ program = gen_bpf_generate(col);
+ if (program == NULL)
+ return -ENOMEM;
+
+ /* attempt to set NO_NEW_PRIVS */
+ if (col->attr.nnp_enable) {
+ rc = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+ if (rc < 0)
+ goto filter_load_out;
+ }
+
+ /* load the filter into the kernel */
+#ifdef HAVE_SECCOMP
+ rc = seccomp(SECCOMP_SET_MODE_FILTER, flags, program);
+#else
+ rc = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, program);
+#endif /* HAVE_SECCOMP */
+
+filter_load_out:
+ /* cleanup and return */
+ gen_bpf_release(program);
+ if (rc < 0)
+ return -errno;
+ return 0;
+}
diff --git a/src/system.h b/src/system.h
index 11303cf..21e3224 100644
--- a/src/system.h
+++ b/src/system.h
@@ -1,5 +1,5 @@
/**
- * Seccomp System Information
+ * Seccomp System Interfaces
*
* Copyright (c) 2012 Red Hat <pmoore@redhat.com>
* Author: Paul Moore <pmoore@redhat.com>
@@ -27,6 +27,8 @@
#include "configure.h"
+struct db_filter_col;
+
#ifdef HAVE_LINUX_SECCOMP_H
/* system header file */
@@ -76,17 +78,33 @@ struct seccomp_data {
__u64 args[6];
};
-#endif /* CONF_SYSINC_SECCOMP */
+#endif /* HAVE_LINUX_SECCOMP_H */
/* rename some of the socket filter types to make more sense */
typedef struct sock_filter bpf_instr_raw;
+/* no new privs defintions */
#ifndef PR_SET_NO_NEW_PRIVS
-#define PR_SET_NO_NEW_PRIVS 38
-#endif /* PR_SET_NO_NEW_PRIVS */
+#define PR_SET_NO_NEW_PRIVS 38
+#endif
#ifndef PR_GET_NO_NEW_PRIVS
-#define PR_GET_NO_NEW_PRIVS 39
-#endif /* PR_GET_NO_NEW_PRIVS */
+#define PR_GET_NO_NEW_PRIVS 39
+#endif
+
+/* operations for the seccomp() syscall */
+#ifndef SECCOMP_MODE_STRICT
+#define SECCOMP_SET_MODE_STRICT 0
+#endif
+#ifndef SECCOMP_SET_MODE_FILTER
+#define SECCOMP_SET_MODE_FILTER 1
+#endif
+
+/* flags for the seccomp() syscall */
+#ifndef SECCOMP_FILTER_FLAG_TSYNC
+#define SECCOMP_FILTER_FLAG_TSYNC 1
+#endif
+
+int sys_filter_load(const struct db_filter_col *col);
#endif