aboutgitcodelistschat:MatrixIRC
diff options
context:
space:
mode:
-rw-r--r--common/gluten.h15
-rw-r--r--cooker/call.c1
-rw-r--r--cooker/emit.c41
-rw-r--r--cooker/emit.h3
-rw-r--r--cooker/match.c13
-rw-r--r--demo/ioctl.hjson8
-rw-r--r--operations.c23
-rw-r--r--operations.h2
8 files changed, 88 insertions, 18 deletions
diff --git a/common/gluten.h b/common/gluten.h
index edb447c..a50687f 100644
--- a/common/gluten.h
+++ b/common/gluten.h
@@ -217,11 +217,14 @@ struct op_mask {
struct gluten_offset desc; /* struct mask_desc */
};
-struct op_resolvedfd {
- struct gluten_offset fd;
- struct gluten_offset path;
- size_t path_size;
- unsigned int jmp;
+struct resolvefd_desc {
+ struct gluten_offset fd;
+ struct gluten_offset path;
+ size_t path_max;
+};
+
+struct op_resolvefd {
+ struct gluten_offset desc;
};
struct op_copy {
@@ -241,7 +244,7 @@ struct op {
struct op_load load;
struct op_mask mask;
struct op_cmp cmp;
- struct op_resolvedfd resfd;
+ struct op_resolvefd resfd;
struct op_copy copy;
} op;
};
diff --git a/cooker/call.c b/cooker/call.c
index 289a0cb..7aef157 100644
--- a/cooker/call.c
+++ b/cooker/call.c
@@ -275,6 +275,7 @@ bool arg_needs_temp(struct field *f, int pos, JSON_Value *jvalue,
return arg_needs_temp(f, pos, jvalue, NULL, level + 1);
return false;
+ case FDPATH:
case STRING:
return false;
case STRUCT:
diff --git a/cooker/emit.c b/cooker/emit.c
index d0928e3..7b1b14d 100644
--- a/cooker/emit.c
+++ b/cooker/emit.c
@@ -164,6 +164,40 @@ void emit_load(struct gluten_ctx *g, struct gluten_offset dst,
}
/**
+ * emit_resolved() - Emit OP_RESOLVEFD instruction: resolve file descriptor with path
+ * @g: gluten context
+ * @fd: offset of the file descriptor value
+ * @path: offset of the path
+ * @path_size: size of the path
+ */
+void emit_resolvefd(struct gluten_ctx *g, struct gluten_offset fd,
+ struct gluten_offset path, size_t path_size)
+{
+ struct op *op = (struct op *)gluten_ptr(&g->g, g->ip);
+ struct op_resolvefd *resfd = &op->op.resfd;
+ struct gluten_offset o;
+ struct resolvefd_desc *desc;
+
+ op->type = OP_RESOLVEDFD;
+ o = gluten_ro_alloc(g, sizeof(struct resolvefd_desc));
+ desc = (struct resolvefd_desc *)gluten_ptr(&g->g, o);
+
+ desc->fd = fd;
+ desc->path = path;
+ desc->path_max = path_size;
+
+ resfd->desc = o;
+
+ debug(" %i: OP_RESOLVEDFD:", g->ip.offset);
+ debug(" \tfd: %s offset=%d", gluten_offset_name[fd.type], fd.offset);
+ debug(" \tpath: %s offset=%d size=%d", gluten_offset_name[path.type],
+ path.offset, path_size);
+
+ if (++g->ip.offset > INST_MAX)
+ die("Too many instructions");
+}
+
+/**
* emit_mask(): Emit OP_MASK instruction: mask and store
* @g: gluten context
* @type: Type of operands
@@ -422,7 +456,7 @@ static struct gluten_offset emit_data_do(struct gluten_ctx *g,
break;
case STRING:
strncpy(p, value->v_str, str_len);
- debug(" C#%i: (%s:%i) %s", g->cp.offset, type_str[type],
+ debug(" C#%i: (%s:%i) %s", ret.offset, type_str[type],
str_len, value->v_str);
break;
@@ -459,6 +493,11 @@ struct gluten_offset emit_data_or(struct gluten_ctx *g,
true);
}
+struct gluten_offset emit_seccomp_data(int index) {
+ struct gluten_offset o = { OFFSET_SECCOMP_DATA, index };
+ return o;
+}
+
static void gluten_link(struct gluten_ctx *g, enum jump_type type,
struct op *start)
{
diff --git a/cooker/emit.h b/cooker/emit.h
index 9ec64e0..18618ee 100644
--- a/cooker/emit.h
+++ b/cooker/emit.h
@@ -16,6 +16,7 @@ void emit_load(struct gluten_ctx *g, struct gluten_offset dst,
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);
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);
@@ -29,6 +30,8 @@ void emit_copy(struct gluten_ctx *g,
struct gluten_offset dst, struct gluten_offset src, size_t size);
void emit_copy_field(struct gluten_ctx *g, struct field *field,
struct gluten_offset dst, struct gluten_offset src);
+void emit_resolvefd(struct gluten_ctx *g, struct gluten_offset fd,
+ struct gluten_offset path, size_t path_size);
void emit_end(struct gluten_ctx *g);
struct gluten_offset emit_data(struct gluten_ctx *g, enum type type,
size_t str_len, union value *value);
diff --git a/cooker/match.c b/cooker/match.c
index e9aed16..3c7650c 100644
--- a/cooker/match.c
+++ b/cooker/match.c
@@ -78,13 +78,14 @@ 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;
+ struct gluten_offset const_offset, mask_offset, data_offset, seccomp_offset;
union value v = { .v_num = 0 };
struct field *f_inner;
const char *tag_name;
JSON_Object *tmp;
JSON_Array *set;
JSON_Value *sel;
+ size_t size;
if (f->name)
debug(" parsing field name %s", f->name);
@@ -202,6 +203,16 @@ xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
emit_cmp(g, CMP_NE, offset, const_offset, strlen(v.v_str) + 1,
JUMP_NEXT_BLOCK);
break;
+ case FDPATH:
+ v.v_str = json_value_get_string(jvalue);
+ size = strlen(v.v_str) + 1;
+ offset = gluten_rw_alloc(g, size);
+ const_offset = emit_data(g, STRING, size, &v);
+ seccomp_offset = emit_seccomp_data(index);
+ emit_resolvefd(g, seccomp_offset, offset, size);
+ emit_cmp(g, CMP_NE, offset, const_offset, size,
+ JUMP_NEXT_BLOCK);
+ break;
case STRUCT:
for (f_inner = f->desc.d_struct; f_inner->name; f_inner++) {
JSON_Value *field_value;
diff --git a/demo/ioctl.hjson b/demo/ioctl.hjson
new file mode 100644
index 0000000..53b59f5
--- /dev/null
+++ b/demo/ioctl.hjson
@@ -0,0 +1,8 @@
+[
+ {
+ "match": [
+ { "ioctl": { "path": "/dev/net/tun", "request": "TUNSETIFF" } }
+ ],
+ "return": 0
+ }
+]
diff --git a/operations.c b/operations.c
index 78206bd..50fdcfb 100644
--- a/operations.c
+++ b/operations.c
@@ -427,24 +427,29 @@ int op_cmp(const struct seccomp_notif *req, int notifier, struct gluten *g,
}
int op_resolve_fd(const struct seccomp_notif *req, int notifier,
- struct gluten *g, struct op_resolvedfd *op)
+ struct gluten *g, struct op_resolvefd *op)
{
- char fdpath[PATH_MAX], buf[PATH_MAX], path[PATH_MAX];
+ const struct resolvefd_desc *desc = gluten_ptr(&req->data, g, op->desc);
+ char fdpath[PATH_MAX], buf[PATH_MAX];
ssize_t nbytes;
int fd;
(void)notifier;
- if (gluten_read(NULL, g, &path, op->path, sizeof(op->path_size)) == -1)
- return -1;
- if (gluten_read(&req->data, g, &fd, op->fd, sizeof(fd)) == -1)
+ debug(" op_resolvefd: fd=(%s %d) path=(%s %d) path_max=%d",
+ gluten_offset_name[desc->fd.type], desc->fd.offset,
+ gluten_offset_name[desc->path.type], desc->path.offset,
+ desc->path_max);
+
+ if (gluten_read(&req->data, g, &fd, desc->fd, sizeof(fd)) == -1)
return -1;
snprintf(fdpath, PATH_MAX, "/proc/%d/fd/%d", req->pid, fd);
- if ((nbytes = readlink(fdpath, buf, op->path_size)) < 0)
- ret_err(-1, "error reading %s", fdpath);
- if (strcmp(path, buf) == 0)
- return op->jmp;
+ if ((nbytes = readlink(fdpath, buf, desc->path_max)) < 0)
+ ret_err(-1, "error reading %s", buf);
+
+ debug(" op_resolvefd: fd %d -> path: %s", fd, buf);
+ gluten_write(g, desc->path, &buf, desc->path_max);
return 0;
}
diff --git a/operations.h b/operations.h
index f543d7a..2f26fc6 100644
--- a/operations.h
+++ b/operations.h
@@ -53,7 +53,7 @@ int op_continue(const struct seccomp_notif *req, int notifier, struct gluten *g,
int op_cmp(const struct seccomp_notif *req, int notifier, struct gluten *g,
struct op_cmp *op);
int op_resolve_fd(const struct seccomp_notif *req, int notifier,
- struct gluten *g, struct op_resolvedfd *op);
+ struct gluten *g, struct op_resolvefd *op);
int op_load(const struct seccomp_notif *req, int notifier, struct gluten *g,
struct op_load *load);
int op_copy(const struct seccomp_notif *req, int notifier, struct gluten *g,