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 +++++++++++++++++++++++++++++++++++++++++++++----------- common/util.h | 97 ++++++++++++++++++++++++++++++++++ 2 files changed, 224 insertions(+), 30 deletions(-) (limited to 'common') 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 */ diff --git a/common/util.h b/common/util.h index 84dc3db..102b55b 100644 --- a/common/util.h +++ b/common/util.h @@ -6,8 +6,22 @@ #ifndef UTIL_H #define UTIL_H +#include +#include + #define BIT(n) (1UL << (n)) +#ifndef MIN +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#endif +#ifndef MAX +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) +#endif + +#define ARRAY_SIZE(a) ((int)(sizeof(a) / sizeof((a)[0]))) + +#define BUILD_BUG_ON(x) extern int __y[1 - 2 * !!(x)]; + void err(const char *format, ...); void info(const char *format, ...); void debug(const char *format, ...); @@ -19,4 +33,87 @@ void debug(const char *format, ...); exit(EXIT_FAILURE); \ } while (0) +/** + * From the Linux kernel, include/linux/log2.h: + * + * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * const_ilog2 - log base 2 of 32-bit or a 64-bit constant unsigned value + * @n: parameter + * + * Use this where sparse expects a true constant expression, e.g. for array + * indices. + */ +#define const_ilog2(n) \ +( \ + __builtin_constant_p(n) ? ( \ + (n) < 2 ? 0 : \ + (n) & (1ULL << 63) ? 63 : \ + (n) & (1ULL << 62) ? 62 : \ + (n) & (1ULL << 61) ? 61 : \ + (n) & (1ULL << 60) ? 60 : \ + (n) & (1ULL << 59) ? 59 : \ + (n) & (1ULL << 58) ? 58 : \ + (n) & (1ULL << 57) ? 57 : \ + (n) & (1ULL << 56) ? 56 : \ + (n) & (1ULL << 55) ? 55 : \ + (n) & (1ULL << 54) ? 54 : \ + (n) & (1ULL << 53) ? 53 : \ + (n) & (1ULL << 52) ? 52 : \ + (n) & (1ULL << 51) ? 51 : \ + (n) & (1ULL << 50) ? 50 : \ + (n) & (1ULL << 49) ? 49 : \ + (n) & (1ULL << 48) ? 48 : \ + (n) & (1ULL << 47) ? 47 : \ + (n) & (1ULL << 46) ? 46 : \ + (n) & (1ULL << 45) ? 45 : \ + (n) & (1ULL << 44) ? 44 : \ + (n) & (1ULL << 43) ? 43 : \ + (n) & (1ULL << 42) ? 42 : \ + (n) & (1ULL << 41) ? 41 : \ + (n) & (1ULL << 40) ? 40 : \ + (n) & (1ULL << 39) ? 39 : \ + (n) & (1ULL << 38) ? 38 : \ + (n) & (1ULL << 37) ? 37 : \ + (n) & (1ULL << 36) ? 36 : \ + (n) & (1ULL << 35) ? 35 : \ + (n) & (1ULL << 34) ? 34 : \ + (n) & (1ULL << 33) ? 33 : \ + (n) & (1ULL << 32) ? 32 : \ + (n) & (1ULL << 31) ? 31 : \ + (n) & (1ULL << 30) ? 30 : \ + (n) & (1ULL << 29) ? 29 : \ + (n) & (1ULL << 28) ? 28 : \ + (n) & (1ULL << 27) ? 27 : \ + (n) & (1ULL << 26) ? 26 : \ + (n) & (1ULL << 25) ? 25 : \ + (n) & (1ULL << 24) ? 24 : \ + (n) & (1ULL << 23) ? 23 : \ + (n) & (1ULL << 22) ? 22 : \ + (n) & (1ULL << 21) ? 21 : \ + (n) & (1ULL << 20) ? 20 : \ + (n) & (1ULL << 19) ? 19 : \ + (n) & (1ULL << 18) ? 18 : \ + (n) & (1ULL << 17) ? 17 : \ + (n) & (1ULL << 16) ? 16 : \ + (n) & (1ULL << 15) ? 15 : \ + (n) & (1ULL << 14) ? 14 : \ + (n) & (1ULL << 13) ? 13 : \ + (n) & (1ULL << 12) ? 12 : \ + (n) & (1ULL << 11) ? 11 : \ + (n) & (1ULL << 10) ? 10 : \ + (n) & (1ULL << 9) ? 9 : \ + (n) & (1ULL << 8) ? 8 : \ + (n) & (1ULL << 7) ? 7 : \ + (n) & (1ULL << 6) ? 6 : \ + (n) & (1ULL << 5) ? 5 : \ + (n) & (1ULL << 4) ? 4 : \ + (n) & (1ULL << 3) ? 3 : \ + (n) & (1ULL << 2) ? 2 : \ + 1) : \ + -1) + +#define BITS_PER_NUM(n) (const_ilog2(n) + 1) + #endif /* UTIL_H */ -- cgit v1.2.3