From 82b77505f9420f11d614c2ae0f74153ca4ee3cb5 Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Tue, 2 May 2023 09:48:50 +0200 Subject: cooker updates spilling all over the place Only tangentially related: - make seitan C99 again, so that I can build cooker without warnings - make Makefiles make use of the usual conventions about assigning directory paths in variables, drop numbers.h as requirement for cooker and make it convenient to run stand-alone Makefiles - fix up nr_syscalls.sh to be POSIX, otherwise it will give syntax errors on my system - define a single, common way to refer to offsets in gluten, and functions to use those offsets in a safe way. Immediates are gone: cooker will write any bit of "data" to the read-only section - call const what has to be const - define on-disk layout for gluten - add OP_NR (to check syscall numbers), rename OP_COPY_ARGS to OP_LOAD (it loads _selected_ stuff from arguments) As for cooker itself: - drop ARG_ and arg_ prefixes from struct names, and similar - add/rework functions to build OP_NR, OP_LOAD, OP_CMP, and to write constant data to gluten - add parsing for "compound" arguments, but that's not completely hooked into evaluation for numeric arguments yet Signed-off-by: Stefano Brivio --- common/gluten.h | 157 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 127 insertions(+), 30 deletions(-) (limited to 'common/gluten.h') diff --git a/common/gluten.h b/common/gluten.h index eb965d9..61270d8 100644 --- a/common/gluten.h +++ b/common/gluten.h @@ -1,10 +1,49 @@ -#ifndef GLUTEN_H -#define GLUTEN_H +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright 2023 Red Hat GmbH + * Authors: Alice Frosi + * Stefano Brivio + */ + +#ifndef COMMON_GLUTEN_H +#define COMMON_GLUTEN_H +#include #include #include +#include + +#include "util.h" -#define MAX_FD_INJECTED 10 +extern struct seccomp_data anonymous_seccomp_data; + +#define HEADER_SIZE 4096 +#define INST_SIZE 4096 +#define RO_DATA_SIZE 4096 +#define DATA_SIZE 4096 + +#define INST_MAX 16 +#define OFFSET_MAX MAX(MAX(MAX(DATA_SIZE, RO_DATA_SIZE), \ + INST_MAX), \ + ARRAY_SIZE(anonymous_seccomp_data.args)) + +enum gluten_offset_type { + OFFSET_RO_DATA = 0, + OFFSET_DATA = 1, + OFFSET_SECCOMP_DATA = 2, + OFFSET_INSTRUCTION = 3, + OFFSET_TYPE_MAX = OFFSET_INSTRUCTION, +}; + +struct gluten_offset { +#ifdef __GNUC__ + enum gluten_offset_type type:BITS_PER_NUM(OFFSET_TYPE_MAX); +#else + uint16_t type:BITS_PER_NUM(OFFSET_TYPE_MAX); +#endif + uint16_t offset:BITS_PER_NUM(OFFSET_MAX); +}; + +BUILD_BUG_ON(BITS_PER_NUM(OFFSET_TYPE_MAX) + BITS_PER_NUM(OFFSET_MAX) > 16) enum ns_spec_type { NS_NONE, @@ -18,7 +57,7 @@ struct ns_spec { union { pid_t pid; char *path; - }; + } id; }; /* @@ -50,7 +89,7 @@ enum op_type { OP_INJECT, OP_INJECT_A, OP_RETURN, - OP_COPY_ARGS, + OP_LOAD, OP_END, OP_CMP, OP_RESOLVEDFD, @@ -61,12 +100,17 @@ enum value_type { REFERENCE, }; +struct op_nr { + long nr; + struct gluten_offset no_match; +}; + struct op_call { long nr; bool has_ret; void *args[6]; struct op_context context; - uint16_t ret_off; + struct gluten_offset ret; }; struct op_block { @@ -78,24 +122,12 @@ struct op_continue { }; struct op_return { - enum value_type type; - union { - int64_t value; - uint16_t value_off; - }; -}; - -struct fd_type { - enum value_type type; - union { - uint32_t fd; - uint16_t fd_off; - }; + struct gluten_offset val; }; struct op_inject { - struct fd_type newfd; - struct fd_type oldfd; + struct gluten_offset new_fd; + struct gluten_offset old_fd; }; struct copy_arg { @@ -104,8 +136,10 @@ struct copy_arg { size_t size; }; -struct op_copy_args { - struct copy_arg args[6]; +struct op_load { + struct gluten_offset src; + struct gluten_offset dst; + size_t size; }; enum op_cmp_type { @@ -118,8 +152,8 @@ enum op_cmp_type { }; struct op_cmp { - uint16_t s1_off; - uint16_t s2_off; + struct gluten_offset x; + struct gluten_offset y; size_t size; enum op_cmp_type cmp; unsigned int jmp; @@ -135,14 +169,77 @@ struct op_resolvedfd { struct op { enum op_type type; union { + struct op_nr nr; struct op_call call; struct op_block block; struct op_continue cont; struct op_return ret; - struct op_inject inj; - struct op_copy_args copy; + struct op_inject inject; + struct op_load load; struct op_cmp cmp; struct op_resolvedfd resfd; - }; -}; -#endif /* GLUTEN_H */ + } op; +}; + +#ifdef COOKER +# define GLUTEN_CONST +#else +# define GLUTEN_CONST const +#endif + +struct gluten { + GLUTEN_CONST char header[HEADER_SIZE]; + + GLUTEN_CONST char inst[INST_SIZE]; + + GLUTEN_CONST char ro_data[RO_DATA_SIZE]; + + char data[DATA_SIZE]; +} __attribute__((packed)); + +BUILD_BUG_ON(INST_SIZE < INST_MAX * sizeof(struct op)) + +#ifdef COOKER +static inline void *gluten_ptr(struct gluten *g, const struct gluten_offset x) +#else +static inline void *gluten_write_ptr(struct gluten *g, + const struct gluten_offset x) +#endif +{ + /* TODO: Boundary checks */ + + switch (x.type) { + case OFFSET_DATA: + return (char *)g->data + x.offset; +#ifdef COOKER + case OFFSET_RO_DATA: + return (char *)g->ro_data + x.offset; + case OFFSET_INSTRUCTION: + return (struct op *)(g->inst) + x.offset; +#endif + default: + return NULL; + } +} + +#ifndef COOKER +static inline const void *gluten_ptr(const struct seccomp_data *s, + struct gluten *g, + const struct gluten_offset x) +{ + switch (x.type) { + case OFFSET_DATA: + return g->data + x.offset; + case OFFSET_RO_DATA: + return g->ro_data + x.offset; + case OFFSET_SECCOMP_DATA: + return (const uint64_t *)s->args + x.offset; + case OFFSET_INSTRUCTION: + return (const struct op *)(g->inst) + x.offset; + default: + return NULL; + } +} +#endif + +#endif /* COMMON_GLUTEN_H */ -- cgit v1.2.3