diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/api.c | 28 | ||||
-rw-r--r-- | src/db.c | 60 | ||||
-rw-r--r-- | src/db.h | 8 | ||||
-rw-r--r-- | src/python/libseccomp.pxd | 2 | ||||
-rw-r--r-- | src/python/seccomp.pyx | 12 | ||||
-rw-r--r-- | src/system.c | 4 |
6 files changed, 101 insertions, 13 deletions
@@ -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)); +} @@ -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; +} @@ -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) |