aboutgitcodelistschat:MatrixIRC
diff options
context:
space:
mode:
-rw-r--r--common/gluten.h23
-rw-r--r--cooker/call.c4
-rw-r--r--cooker/calls/fs.c48
-rw-r--r--cooker/cooker.h8
-rw-r--r--cooker/emit.c87
-rw-r--r--cooker/emit.h3
-rw-r--r--cooker/example.hjson2
-rw-r--r--cooker/gluten.c5
-rw-r--r--cooker/gluten.h1
-rw-r--r--cooker/match.c73
-rw-r--r--eater/eater.c5
-rw-r--r--operations.c76
12 files changed, 293 insertions, 42 deletions
diff --git a/common/gluten.h b/common/gluten.h
index 53782db..edb447c 100644
--- a/common/gluten.h
+++ b/common/gluten.h
@@ -68,6 +68,7 @@ enum op_type {
OP_FD,
OP_RETURN,
OP_LOAD,
+ OP_MASK,
OP_CMP,
OP_RESOLVEDFD,
};
@@ -193,14 +194,29 @@ enum op_cmp_type {
CMP_LE,
};
-struct op_cmp {
+struct cmp_desc {
+ enum op_cmp_type cmp;
+ size_t size;
struct gluten_offset x;
struct gluten_offset y;
- size_t size;
- enum op_cmp_type cmp;
struct gluten_offset jmp;
};
+struct op_cmp {
+ struct gluten_offset desc; /* struct cmp_desc */
+};
+
+struct mask_desc {
+ size_t size;
+ struct gluten_offset dst;
+ struct gluten_offset src;
+ struct gluten_offset mask;
+};
+
+struct op_mask {
+ struct gluten_offset desc; /* struct mask_desc */
+};
+
struct op_resolvedfd {
struct gluten_offset fd;
struct gluten_offset path;
@@ -223,6 +239,7 @@ struct op {
struct op_return ret;
struct op_fd fd;
struct op_load load;
+ struct op_mask mask;
struct op_cmp cmp;
struct op_resolvedfd resfd;
struct op_copy copy;
diff --git a/cooker/call.c b/cooker/call.c
index 1c29db8..289a0cb 100644
--- a/cooker/call.c
+++ b/cooker/call.c
@@ -143,6 +143,8 @@ static union value parse_field(struct gluten_ctx *g, struct arg *args,
case INT:
case LONG:
case U32:
+ case GNU_DEV_MAJOR:
+ case GNU_DEV_MINOR:
if (f->flags == SIZE) {
v.v_num = value_get_size(g, f->desc.d_size);
} else if (f->flags == FLAGS) {
@@ -250,6 +252,8 @@ bool arg_needs_temp(struct field *f, int pos, JSON_Value *jvalue,
case INT:
case LONG:
case U32:
+ case GNU_DEV_MAJOR:
+ case GNU_DEV_MINOR:
return false;
case SELECT:
f_inner = f->desc.d_select->field;
diff --git a/cooker/calls/fs.c b/cooker/calls/fs.c
index 013dacf..cfc0091 100644
--- a/cooker/calls/fs.c
+++ b/cooker/calls/fs.c
@@ -69,27 +69,66 @@ static struct arg mknod_args[] = {
{ 0,
{
"path", STRING, 0,
- 0, 1 /* TODO: PATH_MAX */,
+ 0, PATH_MAX,
{ 0 }
}
},
{ 1,
{
- "mode", UNDEF /* TODO */, FLAGS,
+ "mode", U32 /* TODO */, 0,
0, 0,
{ 0 /* TODO */ },
}
},
{ 2,
{
- "major", UNDEF /* TODO */, 0,
+ "major", GNU_DEV_MAJOR, 0,
0, 0,
{ 0 },
}
},
{ 2,
{
- "minor", UNDEF /* TODO */, 0,
+ "minor", GNU_DEV_MINOR, 0,
+ 0, 0,
+ { 0 },
+ }
+ },
+ { 0 }
+};
+
+static struct arg mknodat_args[] = {
+ { 0,
+ {
+ "dirfd", UNDEF, 0,
+ 0, 1 /* TODO: PATH_MAX */,
+ { 0 }
+ }
+ },
+ { 1,
+ {
+ "path", STRING, 0,
+ 0, PATH_MAX,
+ { 0 }
+ }
+ },
+ { 2,
+ {
+ "mode", UNDEF /* TODO */, FLAGS,
+ 0, 0,
+ { 0 /* TODO */ },
+ }
+ },
+ { 3,
+ {
+ "major", GNU_DEV_MAJOR, 0,
+ 0, 0,
+ { 0 },
+ }
+ },
+ { 3,
+ {
+ "minor", GNU_DEV_MINOR, 0,
0, 0,
{ 0 },
}
@@ -99,5 +138,6 @@ static struct arg mknod_args[] = {
struct call syscalls_fs[] = {
{ __NR_mknod, "mknod", mknod_args },
+ { __NR_mknodat, "mknodat", mknodat_args },
{ 0 },
};
diff --git a/cooker/cooker.h b/cooker/cooker.h
index 7a14221..b26ea2d 100644
--- a/cooker/cooker.h
+++ b/cooker/cooker.h
@@ -14,6 +14,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/sysmacros.h>
#include <sys/types.h>
#include <arpa/inet.h>
@@ -82,6 +83,9 @@ enum type {
IPV4,
IPV6,
+ GNU_DEV_MAJOR,
+ GNU_DEV_MINOR,
+
FDPATH,
TYPE_END,
@@ -108,7 +112,9 @@ enum flags {
#define TYPE_IS_COMPOUND(t) \
((t) == STRUCT || (t) == SELECT)
#define TYPE_IS_NUM(t) \
- ((t) == INT || (t) == U32 || (t) == U64 || (t) == LONG || (t) == USHORT)
+ ((t) == USHORT || (t) == INT || (t) == U32 || \
+ (t) == U64 || (t) == LONG || \
+ (t) == GNU_DEV_MAJOR || (t) == GNU_DEV_MINOR)
/**
* struct num - A numeric value and its label
diff --git a/cooker/emit.c b/cooker/emit.c
index 4be5d35..d0928e3 100644
--- a/cooker/emit.c
+++ b/cooker/emit.c
@@ -18,9 +18,10 @@ static const char *type_str[] = {
"UNDEF", "NONE",
"USHORT", "INT", "U32", "U64", "LONG",
"STRING",
- "STRUCT", "SELECT",
+ "STRUCT", "SELECT", "SELECTED",
"PID",
"PORT", "IPV4", "IPV6",
+ "GNU_DEV_MAJOR", "GNU_DEV_MINOR",
"FDPATH",
NULL
};
@@ -163,6 +164,48 @@ void emit_load(struct gluten_ctx *g, struct gluten_offset dst,
}
/**
+ * emit_mask(): Emit OP_MASK instruction: mask and store
+ * @g: gluten context
+ * @type: Type of operands
+ * @src: gluten pointer to source operand
+ * @mask: gluten pointer to mask
+ *
+ * Return: offset to destination operand, allocated here
+ */
+struct gluten_offset emit_mask(struct gluten_ctx *g, enum type type,
+ struct gluten_offset src,
+ struct gluten_offset mask)
+{
+ struct op *op = (struct op *)gluten_ptr(&g->g, g->ip);
+ struct op_mask *op_mask = &op->op.mask;
+ struct gluten_offset o;
+ struct mask_desc *desc;
+
+ op->type = OP_MASK;
+
+ o = gluten_ro_alloc(g, sizeof(struct mask_desc));
+ desc = (struct mask_desc *)gluten_ptr(&g->g, o);
+
+ desc->size = gluten_size[type];
+ desc->dst = gluten_rw_alloc(g, desc->size);
+ desc->src = src;
+ desc->mask = mask;
+
+ op_mask->desc = o;
+
+ debug(" %i: OP_MASK: %s: #%lu (size: %lu) := %s: #%lu & %s: #%lu",
+ g->ip.offset,
+ gluten_offset_name[desc->dst.type], desc->dst.offset, desc->size,
+ gluten_offset_name[desc->src.type], desc->src.offset,
+ gluten_offset_name[desc->mask.type], desc->mask.offset);
+
+ if (++g->ip.offset > INST_MAX)
+ die("Too many instructions");
+
+ return desc->dst;
+}
+
+/**
* emit_cmp(): Emit OP_CMP instruction: compare data from two offsets
* @g: gluten context
* @cmp_type: Type of comparison
@@ -177,15 +220,22 @@ void emit_cmp(struct gluten_ctx *g, enum op_cmp_type cmp_type,
{
struct op *op = (struct op *)gluten_ptr(&g->g, g->ip);
struct op_cmp *cmp = &op->op.cmp;
+ struct gluten_offset o;
+ struct cmp_desc *desc;
op->type = OP_CMP;
- cmp->x = x;
- cmp->y = y;
- cmp->size = size;
- cmp->cmp = cmp_type;
- cmp->jmp.type = OFFSET_INSTRUCTION;
- cmp->jmp.offset = jmp;
+ o = gluten_ro_alloc(g, sizeof(struct cmp_desc));
+ desc = (struct cmp_desc *)gluten_ptr(&g->g, o);
+
+ desc->x = x;
+ desc->y = y;
+ desc->size = size;
+ desc->cmp = cmp_type;
+ desc->jmp.type = OFFSET_INSTRUCTION;
+ desc->jmp.offset = jmp;
+
+ cmp->desc = o;
debug(" %i: OP_CMP: if %s: #%lu %s (size: %lu) %s: #%lu, jump to %s",
g->ip.offset,
@@ -333,6 +383,7 @@ static struct gluten_offset emit_data_do(struct gluten_ctx *g,
switch (type) {
case USHORT:
case INT:
+ case U32:
if (add) {
*(int *)p |= value->v_int;
debug(" C#%i |= (%s) %i",
@@ -357,6 +408,18 @@ static struct gluten_offset emit_data_do(struct gluten_ctx *g,
}
break;
+ case GNU_DEV_MAJOR:
+ *(unsigned long long int *)p |= makedev(value->v_num, 0);
+ debug(" C#%i |= (%s) %llu",
+ ret.offset, type_str[type], value->v_num);
+
+ break;
+ case GNU_DEV_MINOR:
+ *(unsigned long long int *)p |= makedev(0, value->v_num);
+ debug(" C#%i |= (%s) %llu",
+ ret.offset, type_str[type], value->v_num);
+
+ break;
case STRING:
strncpy(p, value->v_str, str_len);
debug(" C#%i: (%s:%i) %s", g->cp.offset, type_str[type],
@@ -400,6 +463,7 @@ static void gluten_link(struct gluten_ctx *g, enum jump_type type,
struct op *start)
{
struct gluten_offset *jmp;
+ struct cmp_desc *desc;
struct op *op;
for (op = (struct op *)start; op->type; op++) {
@@ -408,7 +472,9 @@ static void gluten_link(struct gluten_ctx *g, enum jump_type type,
jmp = &op->op.nr.no_match;
break;
case OP_CMP:
- jmp = &op->op.cmp.jmp;
+ desc = (struct cmp_desc *)gluten_ptr(&g->g,
+ op->op.cmp.desc);
+ jmp = &desc->jmp;
break;
default:
continue;
@@ -416,6 +482,10 @@ static void gluten_link(struct gluten_ctx *g, enum jump_type type,
if (jmp->offset == type) {
jmp->offset = g->ip.offset;
+
+ if (jmp->offset >= INST_MAX)
+ die("jump after end of instruction area");
+
debug(" linked jump of instruction #%i to #%i",
op - (struct op *)g->g.inst, g->ip.offset);
}
@@ -432,4 +502,5 @@ void link_match(struct gluten_ctx *g)
{
debug(" Linking match...");
gluten_link(g, JUMP_NEXT_MATCH, (struct op *)gluten_ptr(&g->g, g->mr));
+ gluten_link(g, JUMP_NEXT_ACTION, (struct op *)gluten_ptr(&g->g, g->mr));
}
diff --git a/cooker/emit.h b/cooker/emit.h
index 70ffd72..9ec64e0 100644
--- a/cooker/emit.h
+++ b/cooker/emit.h
@@ -13,6 +13,9 @@ void emit_call(struct gluten_ctx *g, struct ns_spec *ns, long nr,
struct gluten_offset offset[6], struct gluten_offset ret_offset);
void emit_load(struct gluten_ctx *g, struct gluten_offset dst,
int index, size_t len);
+struct gluten_offset emit_mask(struct gluten_ctx *g, enum type type,
+ struct gluten_offset src,
+ struct gluten_offset mask);
void emit_cmp(struct gluten_ctx *g, enum op_cmp_type cmp,
struct gluten_offset x, struct gluten_offset y, size_t size,
enum jump_type jmp);
diff --git a/cooker/example.hjson b/cooker/example.hjson
index b161449..9e08163 100644
--- a/cooker/example.hjson
+++ b/cooker/example.hjson
@@ -32,7 +32,7 @@
},
{
"match": [ /* Giuseppe's example */
- { "mknod": { "path": { "tag": "path" }, "mode": "c", "major": 1, "minor": { "in": [ 3, 5, 7, 8, 9 ], "tag": "minor" } } }
+ { "mknodat": { "path": { "tag": "path" }, "mode": "c", "major": 1, "minor": { "value": { "in": [ 3, 5, 7, 8, 9 ] }, "tag": "minor" } } }
],
"call": {
"mknod": { "path": { "tag": { "get": "path" } }, "mode": "c", "major": 1, "minor": { "tag": { "get": "minor" } } },
diff --git a/cooker/gluten.c b/cooker/gluten.c
index cb9ecfb..4d3aea5 100644
--- a/cooker/gluten.c
+++ b/cooker/gluten.c
@@ -24,9 +24,12 @@ size_t gluten_size[TYPE_COUNT] = {
[IPV4] = sizeof(struct in_addr),
[IPV6] = sizeof(struct in6_addr),
+ [GNU_DEV_MAJOR] = sizeof(unsigned long long int),
+ [GNU_DEV_MINOR] = sizeof(unsigned long long int),
};
-const char *jump_name[JUMP_COUNT] = { "next block", "next match", "end" };
+const char *jump_name[JUMP_COUNT] = { "next block", "next match", "next action",
+ "end" };
/**
* gluten_rw_alloc() - Allocate in temporary (seitan read-write) data area
diff --git a/cooker/gluten.h b/cooker/gluten.h
index 9474700..e0ea54d 100644
--- a/cooker/gluten.h
+++ b/cooker/gluten.h
@@ -45,6 +45,7 @@ struct gluten_ctx {
enum jump_type {
JUMP_NEXT_BLOCK,
JUMP_NEXT_MATCH,
+ JUMP_NEXT_ACTION,
JUMP_END,
JUMP_COUNT,
};
diff --git a/cooker/match.c b/cooker/match.c
index c53a456..e9aed16 100644
--- a/cooker/match.c
+++ b/cooker/match.c
@@ -75,13 +75,15 @@ static struct gluten_offset arg_load(struct gluten_ctx *g, struct arg *a)
*/
static union value parse_field(struct gluten_ctx *g,
struct gluten_offset offset,
+ enum op_cmp_type cmp, enum jump_type jump,
int index, struct field *f, JSON_Value *jvalue)
{
- struct gluten_offset const_offset;
+ struct gluten_offset const_offset, mask_offset, data_offset;
union value v = { .v_num = 0 };
struct field *f_inner;
const char *tag_name;
JSON_Object *tmp;
+ JSON_Array *set;
JSON_Value *sel;
if (f->name)
@@ -96,6 +98,30 @@ static union value parse_field(struct gluten_ctx *g,
jvalue = json_object_get_value(tmp, "value");
}
+ if (json_value_get_type(jvalue) == JSONObject &&
+ (tmp = json_value_get_object(jvalue)) &&
+ (set = json_object_get_array(tmp, "in"))) {
+ unsigned i, count = json_array_get_count(set);
+
+ if (cmp != CMP_NE || jump != JUMP_NEXT_BLOCK)
+ die("unsupported nested set");
+
+ for (i = 0; i < count; i++) {
+ if (i == count - 1) {
+ cmp = CMP_NE;
+ jump = JUMP_NEXT_BLOCK;
+ } else {
+ cmp = CMP_EQ;
+ jump = JUMP_NEXT_ACTION;
+ }
+
+ jvalue = json_array_get_value(set, i);
+ parse_field(g, offset, cmp, jump, index, f, jvalue);
+ }
+
+ return v; /* No SELECT based on sets... of course */
+ }
+
/* Nothing to match on: just store as reference */
if (!jvalue)
return v;
@@ -115,11 +141,41 @@ static union value parse_field(struct gluten_ctx *g,
/* calculate mask first */
;
}
-
+ /* Falls through */
v.v_num = value_get_num(f->desc.d_num, jvalue);
const_offset = emit_data(g, f->type, 0, &v);
- emit_cmp(g, CMP_NE, offset, const_offset, gluten_size[f->type],
- JUMP_NEXT_BLOCK);
+ emit_cmp(g, cmp, offset, const_offset, gluten_size[f->type],
+ jump);
+ break;
+ case GNU_DEV_MAJOR:
+ /*
+xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
+______________________ _____________
+ */
+ v.v_num = ((long long)0xfff << 44) | (0xfff << 8);
+ mask_offset = emit_data(g, U64, 0, &v);
+
+ v.v_num = value_get_num(f->desc.d_num, jvalue);
+ v.v_num = (v.v_num & 0xfff) << 8 | (v.v_num & ~0xfff) << 32;
+ const_offset = emit_data(g, U64, 0, &v);
+
+ data_offset = emit_mask(g, U64, offset, mask_offset);
+ emit_cmp_field(g, cmp, f, data_offset, const_offset, jump);
+ break;
+ case GNU_DEV_MINOR:
+ /*
+xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
+ ____________________________ ________
+ */
+ v.v_num = 0xff | ((long long)0xffffff << 12);
+ mask_offset = emit_data(g, U64, 0, &v);
+
+ v.v_num = value_get_num(f->desc.d_num, jvalue);
+ v.v_num = (v.v_num & 0xff) | (v.v_num & ~0xfff) << 12;
+ const_offset = emit_data(g, U64, 0, &v);
+
+ data_offset = emit_mask(g, U64, offset, mask_offset);
+ emit_cmp_field(g, cmp, f, data_offset, const_offset, jump);
break;
case SELECT:
f_inner = f->desc.d_select->field;
@@ -131,11 +187,11 @@ static union value parse_field(struct gluten_ctx *g,
sel = jvalue;
}
- v = parse_field(g, offset, index, f_inner, sel);
+ v = parse_field(g, offset, cmp, jump, index, f_inner, sel);
f = select_field(g, index, f->desc.d_select, v);
if (f)
- parse_field(g, offset, index, f, jvalue);
+ parse_field(g, offset, cmp, jump, index, f, jvalue);
break;
case STRING:
v.v_str = json_value_get_string(jvalue);
@@ -155,7 +211,8 @@ static union value parse_field(struct gluten_ctx *g,
if (!field_value)
continue;
- parse_field(g, offset, index, f_inner, field_value);
+ parse_field(g, offset, cmp, jump, index, f_inner,
+ field_value);
}
break;
default:
@@ -179,7 +236,7 @@ static void parse_arg(struct gluten_ctx *g, JSON_Value *jvalue, struct arg *a)
offset = arg_load(g, a);
- parse_field(g, offset, a->pos, &a->f, jvalue);
+ parse_field(g, offset, CMP_NE, JUMP_NEXT_BLOCK, a->pos, &a->f, jvalue);
}
/**
diff --git a/eater/eater.c b/eater/eater.c
index 567bffa..af1df5f 100644
--- a/eater/eater.c
+++ b/eater/eater.c
@@ -98,18 +98,19 @@ int main(int argc, char **argv)
n = read(fd, filter, sizeof(filter));
close(fd);
- install_filter(filter, (unsigned short)(n / sizeof(filter[0])));
+ fd = install_filter(filter, (unsigned short)(n / sizeof(filter[0])));
+
/*
* close-on-exec flag is set for the file descriptor by seccomp.
* We want to preserve the fd on the exec in this way we are able
* to easly find the notifier fd if seitan restarts.
*/
- fd = find_fd_seccomp_notifier("/proc/self/fd");
flags = fcntl(fd, F_GETFD);
if (fcntl(fd, F_SETFD, flags & !FD_CLOEXEC) < 0) {
perror("fcntl");
exit(EXIT_FAILURE);
}
+
act.sa_handler = signal_handler;
sigaction(SIGCONT, &act, NULL);
pause();
diff --git a/operations.c b/operations.c
index ba9820b..78206bd 100644
--- a/operations.c
+++ b/operations.c
@@ -349,31 +349,77 @@ int op_fd(const struct seccomp_notif *req, int notifier,
return 0;
}
+int op_mask(const struct seccomp_notif *req, int notifier, struct gluten *g,
+ struct op_mask *op)
+{
+ const struct mask_desc *desc = gluten_ptr(&req->data, g, op->desc);
+ const unsigned char *src, *mask;
+ unsigned char *dst;
+ unsigned i;
+
+ (void)notifier;
+
+ if (!desc)
+ return -1;
+
+ dst = gluten_write_ptr( g, desc->dst);
+ src = gluten_ptr(&req->data, g, desc->src);
+ mask = gluten_ptr(&req->data, g, desc->mask);
+
+/*
+ if (!dst || !src || !mask ||
+ !check_gluten_limits(desc->dst, desc->size) ||
+ !check_gluten_limits(desc->src, desc->size) ||
+ !check_gluten_limits(desc->mask, desc->size))
+ return -1;
+*/
+ debug(" op_mask: dst=(%s %d) src=(%s %d) mask=(%s %d) size=%d",
+ gluten_offset_name[desc->dst.type], desc->dst.offset,
+ gluten_offset_name[desc->src.type], desc->src.offset,
+ gluten_offset_name[desc->mask.type], desc->mask.offset,
+ desc->size);
+
+ for (i = 0; i < desc->size; i++)
+ dst[i] = src[i] & mask[i];
+
+ return 0;
+}
+
int op_cmp(const struct seccomp_notif *req, int notifier, struct gluten *g,
struct op_cmp *op)
{
- const void *px = gluten_ptr(&req->data, g, op->x);
- const void *py = gluten_ptr(&req->data, g, op->y);
- enum op_cmp_type cmp = op->cmp;
+ const struct cmp_desc *desc = gluten_ptr(&req->data, g, op->desc);
+ enum op_cmp_type cmp;
+ const void *px, *py;
int res;
(void)notifier;
- if (px == NULL || py == NULL || !check_gluten_limits(op->x, op->size) ||
- !check_gluten_limits(op->y, op->size))
+ if (!desc)
+ return -1;
+
+ px = gluten_ptr(&req->data, g, desc->x);
+ py = gluten_ptr(&req->data, g, desc->y);
+ cmp = desc->cmp;
+
+ if (!px || !py ||
+ !check_gluten_limits(desc->x, desc->size) ||
+ !check_gluten_limits(desc->y, desc->size))
return -1;
debug(" op_cmp: operands x=(%s %d) y=(%s %d) size=%d",
- gluten_offset_name[op->x.type], op->x.offset,
- gluten_offset_name[op->y.type], op->y.offset, op->size);
- res = memcmp(px, py, op->size);
- if ((res == 0 && (cmp == CMP_EQ || cmp == CMP_LE || cmp == CMP_GE)) ||
- (res < 0 && (cmp == CMP_LT || cmp == CMP_LE)) ||
- (res > 0 && (cmp == CMP_GT || cmp == CMP_GE)) ||
+ gluten_offset_name[desc->x.type], desc->x.offset,
+ gluten_offset_name[desc->y.type], desc->y.offset, desc->size);
+
+ res = memcmp(px, py, desc->size);
+
+ if ((res == 0 && (cmp == CMP_EQ || cmp == CMP_LE || cmp == CMP_GE)) ||
+ (res < 0 && (cmp == CMP_LT || cmp == CMP_LE)) ||
+ (res > 0 && (cmp == CMP_GT || cmp == CMP_GE)) ||
(res != 0 && (cmp == CMP_NE))) {
- debug(" op_cmp: successful comparison jump to %d",
- op->jmp.offset);
- return op->jmp.offset;
+ debug(" op_cmp: successful comparison, jump to %d",
+ desc->jmp.offset);
+ return desc->jmp.offset;
}
debug(" op_cmp: comparison is false");
@@ -435,6 +481,7 @@ int eval(struct gluten *g, const struct seccomp_notif *req,
struct op *op = (struct op *)g->inst;
while (op->type != OP_END) {
+ debug("at instruction %i", op - (struct op *)g->inst);
switch (op->type) {
HANDLE_OP(OP_CALL, op_call, call, g);
HANDLE_OP(OP_BLOCK, op_block, block, g);
@@ -442,6 +489,7 @@ int eval(struct gluten *g, const struct seccomp_notif *req,
HANDLE_OP(OP_CONT, op_continue, NO_FIELD, g);
HANDLE_OP(OP_FD, op_fd, fd, g);
HANDLE_OP(OP_LOAD, op_load, load, g);
+ HANDLE_OP(OP_MASK, op_mask, mask, g);
HANDLE_OP(OP_CMP, op_cmp, cmp, g);
HANDLE_OP(OP_RESOLVEDFD, op_resolve_fd, resfd, g);
HANDLE_OP(OP_NR, op_nr, nr, g);