- for (i = 0, n = 0; i < syscall_max(); i++)
- if (syscall_filter[i >> 4] & (1 << (i & 31))) {
- struct sock_filter item[] = {
- BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, INDEX_TO_SYSCALL(i), 0, 1),
- BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
- };
+ if (c->syscall_archs) {
+
+ SET_FOREACH(id, c->syscall_archs, i) {
+ r = seccomp_arch_add(seccomp, PTR_TO_UINT32(id) - 1);
+ if (r == -EEXIST)
+ continue;
+ if (r < 0)
+ goto finish;
+ }
+
+ } else {
+ r = seccomp_add_secondary_archs(seccomp);
+ if (r < 0)
+ goto finish;
+ }
+
+ action = c->syscall_whitelist ? SCMP_ACT_ALLOW : negative_action;
+ SET_FOREACH(id, c->syscall_filter, i) {
+ r = seccomp_rule_add(seccomp, action, PTR_TO_INT(id) - 1, 0);
+ if (r < 0)
+ goto finish;
+ }
+
+ r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_NNP, 0);
+ if (r < 0)
+ goto finish;
+
+ r = seccomp_load(seccomp);
+
+finish:
+ seccomp_release(seccomp);
+ return r;
+}
+
+static int apply_address_families(ExecContext *c) {
+ scmp_filter_ctx *seccomp;
+ Iterator i;
+ int r;
+
+ assert(c);
+
+ seccomp = seccomp_init(SCMP_ACT_ALLOW);
+ if (!seccomp)
+ return -ENOMEM;
+
+ r = seccomp_add_secondary_archs(seccomp);
+ if (r < 0)
+ goto finish;
+
+ if (c->address_families_whitelist) {
+ int af, first = 0, last = 0;
+ void *afp;
+
+ /* If this is a whitelist, we first block the address
+ * families that are out of range and then everything
+ * that is not in the set. First, we find the lowest
+ * and highest address family in the set. */
+
+ SET_FOREACH(afp, c->address_families, i) {
+ af = PTR_TO_INT(afp);
+
+ if (af <= 0 || af >= af_max())
+ continue;
+
+ if (first == 0 || af < first)
+ first = af;
+
+ if (last == 0 || af > last)
+ last = af;
+ }