aboutgitcodelistschat:MatrixIRC
path: root/cooker
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2023-06-07 23:02:23 +0200
committerStefano Brivio <sbrivio@redhat.com>2023-06-07 23:06:32 +0200
commitc38fccbc867019d6c063be1c1d8137edfe52f8de (patch)
treeb3c1b398b4eb40e862263ee084b1dbb7463c1ada /cooker
parent1c1a9da7a4f9c4c1990192e14763ebf423d812a9 (diff)
downloadseitan-c38fccbc867019d6c063be1c1d8137edfe52f8de.tar
seitan-c38fccbc867019d6c063be1c1d8137edfe52f8de.tar.gz
seitan-c38fccbc867019d6c063be1c1d8137edfe52f8de.tar.bz2
seitan-c38fccbc867019d6c063be1c1d8137edfe52f8de.tar.lz
seitan-c38fccbc867019d6c063be1c1d8137edfe52f8de.tar.xz
seitan-c38fccbc867019d6c063be1c1d8137edfe52f8de.tar.zst
seitan-c38fccbc867019d6c063be1c1d8137edfe52f8de.zip
mknod/mknodat values, initial support for MASK flag, OP_BITWISE
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'cooker')
-rw-r--r--cooker/call.c41
-rw-r--r--cooker/calls/fs.c63
-rw-r--r--cooker/cooker.h1
-rw-r--r--cooker/emit.c56
-rw-r--r--cooker/emit.h9
-rw-r--r--cooker/match.c44
6 files changed, 154 insertions, 60 deletions
diff --git a/cooker/call.c b/cooker/call.c
index 7aef157..7ae3d48 100644
--- a/cooker/call.c
+++ b/cooker/call.c
@@ -113,10 +113,14 @@ static union value parse_field(struct gluten_ctx *g, struct arg *args,
if (tag_offset.type == OFFSET_NULL)
die(" tag not found");
- if (base_offset->type == OFFSET_NULL)
+ if (base_offset->type == OFFSET_NULL) {
*base_offset = tag_offset;
- else
+ } else if (f->flags & MASK || add) {
+ emit_bitwise(g, f->type, BITWISE_OR, offset,
+ offset, tag_offset);
+ } else {
emit_copy_field(g, f, offset, tag_offset);
+ }
}
if (json_object_get_count(tmp2) > count)
@@ -252,9 +256,10 @@ bool arg_needs_temp(struct field *f, int pos, JSON_Value *jvalue,
case INT:
case LONG:
case U32:
+ return false;
case GNU_DEV_MAJOR:
case GNU_DEV_MINOR:
- return false;
+ return true;
case SELECT:
f_inner = f->desc.d_select->field;
if (arg_needs_temp(f_inner, pos, jvalue, top_level_tag, level))
@@ -300,7 +305,7 @@ bool arg_needs_temp(struct field *f, int pos, JSON_Value *jvalue,
}
static struct gluten_offset parse_arg(struct gluten_ctx *g, struct arg *args,
- struct arg *a,
+ struct arg *a, bool multi_field,
struct gluten_offset offset,
JSON_Value *jvalue)
{
@@ -314,10 +319,15 @@ static struct gluten_offset parse_arg(struct gluten_ctx *g, struct arg *args,
return offset;
}
- if (arg_needs_temp(&a->f, a->pos, jvalue, &top_level_tag, 0))
- offset = gluten_rw_alloc(g, a->f.size);
- else if (a->f.size && !top_level_tag)
+ if (arg_needs_temp(&a->f, a->pos, jvalue, &top_level_tag, 0) ||
+ multi_field) {
+ if (a->f.size)
+ offset = gluten_rw_alloc(g, a->f.size);
+ else
+ offset = gluten_rw_alloc_type(g, a->f.type);
+ } else if ((a->f.size && !top_level_tag)) {
offset = gluten_ro_alloc(g, a->f.size);
+ }
parse_field(g, args, &offset, a->pos, &a->f, jvalue, false, false);
return offset;
@@ -336,6 +346,8 @@ static void parse_call(struct gluten_ctx *g, struct ns_spec *ns, long nr,
struct {
bool needs_fd;
bool has_fd;
+ bool found;
+ bool multi_field;
} arg_check[6] = { 0 };
int arg_max_pos = -1;
unsigned count = 0;
@@ -349,6 +361,10 @@ static void parse_call(struct gluten_ctx *g, struct ns_spec *ns, long nr,
a = g->selected_arg[a->pos];
}
+ if (arg_check[a->pos].found)
+ arg_check[a->pos].multi_field = true;
+ arg_check[a->pos].found = true;
+
if (a->f.type == FDPATH)
arg_check[a->pos].needs_fd = true;
@@ -362,10 +378,13 @@ static void parse_call(struct gluten_ctx *g, struct ns_spec *ns, long nr,
/* TODO: Factor this out into a function in... parse.c? */
for (a = args; a->f.name; a++) {
JSON_Value *jvalue;
+ bool multi_field;
if (a->f.type == SELECTED)
a = g->selected_arg[a->pos];
+ multi_field = arg_check[a->pos].multi_field;
+
/* Not common with parse_match(), though */
if ((jvalue = json_object_get_value(obj, a->f.name))) {
if (arg_check[a->pos].has_fd)
@@ -373,15 +392,15 @@ static void parse_call(struct gluten_ctx *g, struct ns_spec *ns, long nr,
else if (arg_check[a->pos].needs_fd)
arg_check[a->pos].has_fd = true;
- offset[a->pos] = parse_arg(g, args, a, offset[a->pos],
- jvalue);
+ offset[a->pos] = parse_arg(g, args, a, multi_field,
+ offset[a->pos], jvalue);
count++;
} else if (arg_check[a->pos].needs_fd &&
arg_check[a->pos].has_fd) {
;
} else if (a->f.flags & SIZE) {
- offset[a->pos] = parse_arg(g, args, a, offset[a->pos],
- jvalue);
+ offset[a->pos] = parse_arg(g, args, a, multi_field,
+ offset[a->pos], jvalue);
} else {
die(" No specification for argument %s", a->f.name);
}
diff --git a/cooker/calls/fs.c b/cooker/calls/fs.c
index cfc0091..469dd88 100644
--- a/cooker/calls/fs.c
+++ b/cooker/calls/fs.c
@@ -58,13 +58,44 @@ swapoff
#include <asm-generic/unistd.h>
#include <sys/syscall.h>
-#include <fcntl.h>
+#define _GNU_SOURCE
#include <sys/stat.h>
+#include <fcntl.h>
#include <linux/limits.h>
#include "../cooker.h"
#include "../calls.h"
+static struct num modes[] = {
+ { "S_ISUID", S_ISUID },
+ { "S_ISGID", S_ISGID },
+ { "S_IRWXU", S_IRWXU },
+ { "S_IRUSR", S_IRUSR },
+ { "S_IWUSR", S_IWUSR },
+ { "S_IXUSR", S_IXUSR },
+ { "S_IRWXG", S_IRWXG },
+ { "S_IRGRP", S_IRGRP },
+ { "S_IWGRP", S_IWGRP },
+ { "S_IXGRP", S_IXGRP },
+ { "S_IRWXO", S_IRWXO },
+ { "S_IROTH", S_IROTH },
+ { "S_IWOTH", S_IWOTH },
+ { "S_IXOTH", S_IXOTH },
+ { "S_ISVTX", S_ISVTX },
+ { 0 },
+};
+
+static struct num types[] = {
+ { "S_IFSOCK", S_IFSOCK },
+ { "S_IFLNK", S_IFLNK },
+ { "S_IFREG", S_IFREG },
+ { "S_IFBLK", S_IFBLK },
+ { "S_IFDIR", S_IFDIR },
+ { "S_IFCHR", S_IFCHR },
+ { "S_IFIFO", S_IFIFO },
+ { 0 },
+};
+
static struct arg mknod_args[] = {
{ 0,
{
@@ -75,9 +106,16 @@ static struct arg mknod_args[] = {
},
{ 1,
{
- "mode", U32 /* TODO */, 0,
+ "mode", INT, FLAGS | MASK,
0, 0,
- { 0 /* TODO */ },
+ { .d_num = modes },
+ }
+ },
+ { 1,
+ {
+ "type", INT, FLAGS | MASK,
+ 0, 0,
+ { .d_num = types },
}
},
{ 2,
@@ -98,13 +136,7 @@ static struct arg mknod_args[] = {
};
static struct arg mknodat_args[] = {
- { 0,
- {
- "dirfd", UNDEF, 0,
- 0, 1 /* TODO: PATH_MAX */,
- { 0 }
- }
- },
+ /* No dirfd: we only support absolute paths at the moment */
{ 1,
{
"path", STRING, 0,
@@ -114,9 +146,16 @@ static struct arg mknodat_args[] = {
},
{ 2,
{
- "mode", UNDEF /* TODO */, FLAGS,
+ "mode", INT, FLAGS | MASK,
+ 0, 0,
+ { .d_num = modes },
+ }
+ },
+ { 2,
+ {
+ "type", INT, FLAGS | MASK,
0, 0,
- { 0 /* TODO */ },
+ { .d_num = types },
}
},
{ 3,
diff --git a/cooker/cooker.h b/cooker/cooker.h
index b26ea2d..24d8f7f 100644
--- a/cooker/cooker.h
+++ b/cooker/cooker.h
@@ -18,6 +18,7 @@
#include <sys/types.h>
#include <arpa/inet.h>
+#include <common.h>
#include <util.h>
#define TAGS_MAX 256
diff --git a/cooker/emit.c b/cooker/emit.c
index 506a561..107b2ce 100644
--- a/cooker/emit.c
+++ b/cooker/emit.c
@@ -198,40 +198,49 @@ void emit_resolvefd(struct gluten_ctx *g, struct gluten_offset fd,
}
/**
- * emit_mask(): Emit OP_MASK instruction: mask and store
+ * emit_bitwise(): Emit OP_BITWISE instruction: bitwise operation and store
* @g: gluten context
* @type: Type of operands
- * @src: gluten pointer to source operand
- * @mask: gluten pointer to mask
+ * @op_type: Type of bitwise operation
+ * @dst: gluten pointer to destination operand, can be OFFSET_NULL
+ * @x: gluten pointer to first source operand
+ * @y: gluten pointer to second source operand
*
- * Return: offset to destination operand, allocated here
+ * Return: offset to destination operand, allocated here if not given
*/
-struct gluten_offset emit_mask(struct gluten_ctx *g, enum type type,
- struct gluten_offset src,
- struct gluten_offset mask)
+struct gluten_offset emit_bitwise(struct gluten_ctx *g, enum type type,
+ enum bitwise_type op_type,
+ struct gluten_offset dst,
+ struct gluten_offset x,
+ struct gluten_offset y)
{
struct op *op = (struct op *)gluten_ptr(&g->g, g->ip);
- struct op_mask *op_mask = &op->op.mask;
+ struct op_bitwise *op_bitwise = &op->op.bitwise;
struct gluten_offset o;
- struct mask_desc *desc;
+ struct bitwise_desc *desc;
- op->type = OP_MASK;
+ op->type = OP_BITWISE;
- o = gluten_ro_alloc(g, sizeof(struct mask_desc));
- desc = (struct mask_desc *)gluten_ptr(&g->g, o);
+ o = gluten_ro_alloc(g, sizeof(struct bitwise_desc));
+ desc = (struct bitwise_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;
+ desc->type = op_type;
+ if (dst.type == OFFSET_NULL)
+ desc->dst = gluten_rw_alloc(g, desc->size);
+ else
+ desc->dst = dst;
+ desc->x = x;
+ desc->y = y;
- op_mask->desc = o;
+ op_bitwise->desc = o;
- debug(" %i: OP_MASK: %s: #%lu (size: %lu) := %s: #%lu & %s: #%lu",
+ debug(" %i: OP_BITWISE: %s: #%lu (size: %lu) := %s: #%lu %s %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);
+ gluten_offset_name[desc->dst.type], desc->dst.offset, desc->size,
+ gluten_offset_name[desc->x.type], desc->x.offset,
+ bitwise_type_str[op_type],
+ gluten_offset_name[desc->y.type], desc->y.offset);
if (++g->ip.offset > INST_MAX)
die("Too many instructions");
@@ -537,5 +546,10 @@ 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));
+}
+
+void link_matches(struct gluten_ctx *g)
+{
+ debug(" Linking matches...");
+ gluten_link(g, JUMP_NEXT_ACTION, (struct op *)gluten_ptr(&g->g, g->lr));
}
diff --git a/cooker/emit.h b/cooker/emit.h
index 81f947e..978c9e0 100644
--- a/cooker/emit.h
+++ b/cooker/emit.h
@@ -13,10 +13,12 @@ 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);
struct gluten_offset emit_seccomp_data(int index);
+struct gluten_offset emit_bitwise(struct gluten_ctx *g, enum type type,
+ enum bitwise_type op_type,
+ struct gluten_offset dst,
+ struct gluten_offset x,
+ struct gluten_offset y);
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);
@@ -43,5 +45,6 @@ struct gluten_offset emit_data_or(struct gluten_ctx *g,
enum type type, union value *value);
void link_block(struct gluten_ctx *g);
void link_match(struct gluten_ctx *g);
+void link_matches(struct gluten_ctx *g);
#endif /* EMIT_H */
diff --git a/cooker/match.c b/cooker/match.c
index 3c7650c..d32bf0a 100644
--- a/cooker/match.c
+++ b/cooker/match.c
@@ -78,7 +78,7 @@ static union value parse_field(struct gluten_ctx *g,
enum op_cmp_type cmp, enum jump_type jump,
int index, struct field *f, JSON_Value *jvalue)
{
- struct gluten_offset const_offset, mask_offset, data_offset, seccomp_offset;
+ struct gluten_offset const_offset, mask_offset, seccomp_offset;
union value v = { .v_num = 0 };
struct field *f_inner;
const char *tag_name;
@@ -90,6 +90,32 @@ static union value parse_field(struct gluten_ctx *g,
if (f->name)
debug(" parsing field name %s", f->name);
+ /* Some types need pre-tagging preparation */
+ switch (f->type) {
+ 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);
+ offset = emit_bitwise(g, U64, BITWISE_AND, NULL_OFFSET,
+ offset, mask_offset);
+ 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);
+ offset = emit_bitwise(g, U64, BITWISE_AND, NULL_OFFSET,
+ offset, mask_offset);
+ break;
+ default:
+ break;
+ }
+
if (json_value_get_type(jvalue) == JSONObject &&
(tmp = json_value_get_object(jvalue)) &&
(tag_name = json_object_get_string(tmp, "tag"))) {
@@ -153,30 +179,20 @@ static union value parse_field(struct gluten_ctx *g,
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);
+ emit_cmp_field(g, cmp, f, 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);
+ emit_cmp_field(g, cmp, f, offset, const_offset, jump);
break;
case SELECT:
f_inner = f->desc.d_select->field;
@@ -329,4 +345,6 @@ void handle_matches(struct gluten_ctx *g, JSON_Value *value)
link_match(g);
}
+
+ link_matches(g);
}