summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Moore <pmoore@redhat.com>2013-01-30 15:33:39 -0500
committerPaul Moore <pmoore@redhat.com>2013-03-26 18:15:10 -0400
commitbb6075384f8cf3286d3109222a2d022ac730ef6a (patch)
treecb026e5c5ba8d8ff2e0c6c7a79e701bdc37d2d0d
parent7d04a6cf698b2ac9e2fd2a80d1ffb356dfe5d370 (diff)
downloadlibseccomp-bb6075384f8cf3286d3109222a2d022ac730ef6a.tar.gz
bpf: support multiple architectures sharing the same BPF arch token
This is necessary for x32 support. Signed-off-by: Paul Moore <pmoore@redhat.com>
-rw-r--r--src/gen_bpf.c42
1 files changed, 38 insertions, 4 deletions
diff --git a/src/gen_bpf.c b/src/gen_bpf.c
index b1287e5..52d4a42 100644
--- a/src/gen_bpf.c
+++ b/src/gen_bpf.c
@@ -1065,15 +1065,17 @@ static struct bpf_blk *_gen_bpf_syscall(struct bpf_state *state,
* Generate the BPF instruction blocks for a given filter/architecture
* @param state the BPF state
* @param db the filter DB
+ * @param db_secondary the secondary DB
*
- * Generate the BPF instruction block for the given filter DB/architecture and
- * return a pointer to the block on succes, NULL on failure. The resulting
+ * Generate the BPF instruction block for the given filter DB(s)/architecture(s)
+ * and return a pointer to the block on succes, NULL on failure. The resulting
* block assumes that the architecture token has already been loaded into the
* BPF accumulator.
*
*/
static struct bpf_blk *_gen_bpf_arch(struct bpf_state *state,
- const struct db_filter *db)
+ const struct db_filter *db,
+ const struct db_filter *db_secondary)
{
int rc;
unsigned int blk_cnt = 0;
@@ -1114,6 +1116,38 @@ static struct bpf_blk *_gen_bpf_arch(struct bpf_state *state,
s_head->pri_nxt = NULL;
}
}
+ if (db_secondary != NULL) {
+ db_list_foreach(s_iter, db_secondary->syscalls) {
+ if (s_head != NULL) {
+ s_iter_b = s_head;
+ while ((s_iter_b->pri_nxt != NULL) &&
+ (s_iter->priority <= s_iter_b->priority))
+ s_iter_b = s_iter_b->pri_nxt;
+
+ if (s_iter->priority > s_iter_b->priority) {
+ s_iter->pri_prv = s_iter_b->pri_prv;
+ s_iter->pri_nxt = s_iter_b;
+ if (s_iter_b == s_head) {
+ s_head->pri_prv = s_iter;
+ s_head = s_iter;
+ } else {
+ s_iter->pri_prv->pri_nxt=s_iter;
+ s_iter->pri_nxt->pri_prv=s_iter;
+ }
+ } else {
+ s_iter->pri_prv = s_tail;
+ s_iter->pri_nxt = NULL;
+ s_iter->pri_prv->pri_nxt = s_iter;
+ s_tail = s_iter;
+ }
+ } else {
+ s_head = s_iter;
+ s_tail = s_iter;
+ s_head->pri_prv = NULL;
+ s_head->pri_nxt = NULL;
+ }
+ }
+ }
/* create the syscall filters and add them to block list group */
for (s_iter = s_tail; s_iter != NULL; s_iter = s_iter->pri_prv) {
@@ -1417,7 +1451,7 @@ static int _gen_bpf_build_bpf(struct bpf_state *state,
/* generate the per-architecture filters */
for (iter = 0; iter < col->filter_cnt; iter++) {
- b_new = _gen_bpf_arch(state, col->filters[iter]);
+ b_new = _gen_bpf_arch(state, col->filters[iter], NULL);
if (b_new == NULL)
return -ENOMEM;
b_new->prev = b_tail;