summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/api.c28
-rw-r--r--src/db.c60
-rw-r--r--src/db.h8
-rw-r--r--src/python/libseccomp.pxd2
-rw-r--r--src/python/seccomp.pyx12
-rw-r--r--src/system.c4
6 files changed, 101 insertions, 13 deletions
diff --git a/src/api.c b/src/api.c
index 423a1c5..9c2f64a 100644
--- a/src/api.c
+++ b/src/api.c
@@ -2,6 +2,7 @@
* Seccomp Library API
*
* Copyright (c) 2012,2013 Red Hat <pmoore@redhat.com>
+ * Copyright (c) 2022 Microsoft Corporation <paulmoore@microsoft.com>
* Author: Paul Moore <paul@paul-moore.com>
*/
@@ -723,11 +724,11 @@ API int seccomp_export_bpf(const scmp_filter_ctx ctx, int fd)
return _rc_filter(-EINVAL);
col = (struct db_filter_col *)ctx;
- rc = gen_bpf_generate(col, &program);
+ rc = db_col_precompute(col);
if (rc < 0)
return _rc_filter(rc);
+ program = col->prgm_bpf;
rc = write(fd, program->blks, BPF_PGM_SIZE(program));
- gen_bpf_release(program);
if (rc < 0)
return _rc_filter_sys(col, -errno);
@@ -739,7 +740,6 @@ API int seccomp_export_bpf_mem(const scmp_filter_ctx ctx, void *buf,
size_t *len)
{
int rc;
- size_t buf_len;
struct db_filter_col *col;
struct bpf_program *program;
@@ -747,21 +747,31 @@ API int seccomp_export_bpf_mem(const scmp_filter_ctx ctx, void *buf,
return _rc_filter(-EINVAL);
col = (struct db_filter_col *)ctx;
- rc = gen_bpf_generate(col, &program);
+ rc = db_col_precompute(col);
if (rc < 0)
return _rc_filter(rc);
- buf_len = *len;
- *len = BPF_PGM_SIZE(program);
+ program = col->prgm_bpf;
- rc = 0;
if (buf) {
/* If we have a big enough buffer, write the program. */
- if (*len > buf_len)
+ if (BPF_PGM_SIZE(program) > *len)
rc = _rc_filter(-ERANGE);
else
memcpy(buf, program->blks, *len);
}
- gen_bpf_release(program);
+ *len = BPF_PGM_SIZE(program);
return rc;
}
+
+/* NOTE - function header comment in include/seccomp.h */
+API int seccomp_precompute(const scmp_filter_ctx ctx)
+{
+ struct db_filter_col *col;
+
+ if (_ctx_valid(ctx))
+ return _rc_filter(-EINVAL);
+ col = (struct db_filter_col *)ctx;
+
+ return _rc_filter(db_col_precompute(col));
+}
diff --git a/src/db.c b/src/db.c
index 3d9585a..6d81874 100644
--- a/src/db.c
+++ b/src/db.c
@@ -3,6 +3,7 @@
*
* Copyright (c) 2012,2016,2018 Red Hat <pmoore@redhat.com>
* Copyright (c) 2019 Cisco Systems, Inc. <pmoore2@cisco.com>
+ * Copyright (c) 2022 Microsoft Corporation <paulmoore@microsoft.com>
* Author: Paul Moore <paul@paul-moore.com>
*/
@@ -1098,6 +1099,9 @@ int db_col_reset(struct db_filter_col *col, uint32_t def_action)
free(snap);
}
+ /* reset the precomputed programs */
+ db_col_precompute_reset(col);
+
return 0;
}
@@ -1162,6 +1166,9 @@ void db_col_release(struct db_filter_col *col)
free(col->filters);
col->filters = NULL;
+ /* free any precompute */
+ db_col_precompute_reset(col);
+
/* free the collection */
free(col);
}
@@ -1250,6 +1257,9 @@ int db_col_merge(struct db_filter_col *col_dst, struct db_filter_col *col_src)
col_dst->filter_cnt++;
}
+ /* reset the precompute */
+ db_col_precompute_reset(col_dst);
+
/* free the source */
col_src->filter_cnt = 0;
db_col_release(col_src);
@@ -1373,6 +1383,7 @@ int db_col_attr_set(struct db_filter_col *col,
col->attr.act_badarch = value;
else
return -EINVAL;
+ db_col_precompute_reset(col);
break;
case SCMP_FLTATR_CTL_NNP:
col->attr.nnp_enable = (value ? 1 : 0);
@@ -1394,6 +1405,7 @@ int db_col_attr_set(struct db_filter_col *col,
break;
case SCMP_FLTATR_API_TSKIP:
col->attr.api_tskip = (value ? 1 : 0);
+ db_col_precompute_reset(col);
break;
case SCMP_FLTATR_CTL_LOG:
rc = sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_LOG);
@@ -1427,6 +1439,7 @@ int db_col_attr_set(struct db_filter_col *col,
rc = -EOPNOTSUPP;
break;
}
+ db_col_precompute_reset(col);
break;
case SCMP_FLTATR_API_SYSRAWRC:
col->attr.api_sysrawrc = (value ? 1 : 0);
@@ -1460,6 +1473,8 @@ int db_col_db_new(struct db_filter_col *col, const struct arch_def *arch)
rc = db_col_db_add(col, db);
if (rc < 0)
_db_release(db);
+ else
+ db_col_precompute_reset(col);
return rc;
}
@@ -1540,6 +1555,8 @@ int db_col_db_remove(struct db_filter_col *col, uint32_t arch_token)
col->endian = 0;
}
+ db_col_precompute_reset(col);
+
return 0;
}
@@ -2233,6 +2250,9 @@ priority_failure:
rc = rc_tmp;
}
+ if (rc == 0)
+ db_col_precompute_reset(col);
+
return rc;
}
@@ -2377,8 +2397,11 @@ add_arch_fail:
add_return:
/* update the misc state */
- if (rc == 0 && action == SCMP_ACT_NOTIFY)
- col->notify_used = true;
+ if (rc == 0) {
+ if (action == SCMP_ACT_NOTIFY)
+ col->notify_used = true;
+ db_col_precompute_reset(col);
+ }
if (chain != NULL)
free(chain);
return rc;
@@ -2501,6 +2524,9 @@ void db_col_transaction_abort(struct db_filter_col *col)
for (iter = 0; iter < filter_cnt; iter++)
_db_release(filters[iter]);
free(filters);
+
+ /* free any precompute */
+ db_col_precompute_reset(col);
}
/**
@@ -2618,3 +2644,33 @@ shadow_err:
_db_snap_release(snap);
return;
}
+
+/**
+ * Precompute the seccomp filters
+ * @param col the filter collection
+ *
+ * This function precomputes the seccomp filters before they are needed,
+ * returns zero on success, negative values on error.
+ *
+ */
+int db_col_precompute(struct db_filter_col *col)
+{
+ if (!col->prgm_bpf)
+ return gen_bpf_generate(col, &col->prgm_bpf);
+ return 0;
+}
+
+/**
+ * Free any precomputed filter programs
+ * @param col the filter collection
+ *
+ * This function releases any precomputed filter programs.
+ */
+void db_col_precompute_reset(struct db_filter_col *col)
+{
+ if (!col->prgm_bpf)
+ return;
+
+ gen_bpf_release(col->prgm_bpf);
+ col->prgm_bpf = NULL;
+}
diff --git a/src/db.h b/src/db.h
index 765c607..9a41427 100644
--- a/src/db.h
+++ b/src/db.h
@@ -2,6 +2,7 @@
* Enhanced Seccomp Filter DB
*
* Copyright (c) 2012,2016 Red Hat <pmoore@redhat.com>
+ * Copyright (c) 2022 Microsoft Corporation <paulmoore@microsoft.com>
* Author: Paul Moore <paul@paul-moore.com>
*/
@@ -28,6 +29,7 @@
#include <seccomp.h>
#include "arch.h"
+#include "gen_bpf.h"
/* XXX - need to provide doxygen comments for the types here */
@@ -162,6 +164,9 @@ struct db_filter_col {
/* userspace notification */
bool notify_used;
+
+ /* precomputed programs */
+ struct bpf_program *prgm_bpf;
};
/**
@@ -212,6 +217,9 @@ int db_col_transaction_start(struct db_filter_col *col);
void db_col_transaction_abort(struct db_filter_col *col);
void db_col_transaction_commit(struct db_filter_col *col);
+int db_col_precompute(struct db_filter_col *col);
+void db_col_precompute_reset(struct db_filter_col *col);
+
int db_rule_add(struct db_filter *db, const struct db_api_rule_list *rule);
#endif
diff --git a/src/python/libseccomp.pxd b/src/python/libseccomp.pxd
index 6175c8a..9589cfe 100644
--- a/src/python/libseccomp.pxd
+++ b/src/python/libseccomp.pxd
@@ -170,5 +170,7 @@ cdef extern from "seccomp.h":
int seccomp_export_bpf_mem(const scmp_filter_ctx ctx, void *buf,
size_t *len)
+ int seccomp_precompute(const scmp_filter_ctx ctx)
+
# kate: syntax python;
# kate: indent-mode python; space-indent on; indent-width 4; mixedindent off;
diff --git a/src/python/seccomp.pyx b/src/python/seccomp.pyx
index 3551aac..1f58517 100644
--- a/src/python/seccomp.pyx
+++ b/src/python/seccomp.pyx
@@ -1069,5 +1069,17 @@ cdef class SyscallFilter:
raise RuntimeError(str.format("Library error (errno = {0})", rc))
return program
+ def precompute(self):
+ """ Precompute the seccomp filter.
+
+ Description:
+ Precompute the seccomp filter and store it internally for future use,
+ speeding up filter loads and other functions which require the
+ generated filter.
+ """
+ rc = libseccomp.seccomp_precompute(self._ctx)
+ if rc != 0:
+ raise RuntimeError(str.format("Library error (errno = {0})", rc))
+
# kate: syntax python;
# kate: indent-mode python; space-indent on; indent-width 4; mixedindent off;
diff --git a/src/system.c b/src/system.c
index ae445bf..94e0405 100644
--- a/src/system.c
+++ b/src/system.c
@@ -360,9 +360,10 @@ int sys_filter_load(struct db_filter_col *col, bool rawrc)
bool listener_req;
struct bpf_program *prgm = NULL;
- rc = gen_bpf_generate(col, &prgm);
+ rc = db_col_precompute(col);
if (rc < 0)
return rc;
+ prgm = col->prgm_bpf;
/* attempt to set NO_NEW_PRIVS */
if (col->attr.nnp_enable) {
@@ -417,7 +418,6 @@ int sys_filter_load(struct db_filter_col *col, bool rawrc)
filter_load_out:
/* cleanup and return */
- gen_bpf_release(prgm);
if (rc == -ESRCH)
return -ESRCH;
if (rc < 0)