diff options
author | Thomas Weißschuh <thomas@t-8ch.de> | 2023-05-05 00:38:11 +0200 |
---|---|---|
committer | Thomas Weißschuh <thomas@t-8ch.de> | 2023-05-16 22:44:50 +0200 |
commit | 5e248716e6ac7c08f24d5cc0856a13a94395faca (patch) | |
tree | 57d87edc132b75ee53c14ea37455096b0388cf8c | |
parent | 7f104027e2a0929e71fa1307dcfe94f5217799a5 (diff) | |
download | util-linux-5e248716e6ac7c08f24d5cc0856a13a94395faca.tar.gz |
enosys: remove long jumps from BPF
BPF encodes the jump distance in a uint8_t. To avoid overflows of this
value reorganize the generated bytecode to work without long jumps.
Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
-rw-r--r-- | misc-utils/enosys.c | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/misc-utils/enosys.c b/misc-utils/enosys.c index 83e1847ff..79f57b255 100644 --- a/misc-utils/enosys.c +++ b/misc-utils/enosys.c @@ -139,7 +139,7 @@ int main(int argc, char **argv) if (optind >= argc) errtryhelp(EXIT_FAILURE); -#define N_FILTERS (ARRAY_SIZE(syscalls) + 6) +#define N_FILTERS (ARRAY_SIZE(syscalls) * 2 + 5) struct sock_filter filter[N_FILTERS] = { [0] = BPF_STMT(BPF_LD | BPF_W | BPF_ABS, syscall_arch), @@ -147,19 +147,21 @@ int main(int argc, char **argv) [2] = BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_TRAP), [3] = BPF_STMT(BPF_LD | BPF_W | BPF_ABS, syscall_nr), - [N_FILTERS - 2] = BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), - [N_FILTERS - 1] = BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | ENOSYS), + [N_FILTERS - 1] = BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), }; + static_assert(ARRAY_SIZE(filter) <= BPF_MAXINSNS, "bpf filter too big"); for (i = 0; i < ARRAY_SIZE(syscalls); i++) { - if (blocked_syscalls[i]) { - filter[i + 4] = (struct sock_filter) BPF_JUMP( - BPF_JMP | BPF_JEQ | BPF_K, - syscalls[i].number, - N_FILTERS - 3 - i, 0); - } else { - filter[i + 4] = UL_BPF_NOP; - } + struct sock_filter *f = &filter[4 + i * 2]; + + *f = (struct sock_filter) BPF_JUMP( + BPF_JMP | BPF_JEQ | BPF_K, + syscalls[i].number, + 0, 1); + *(f + 1) = blocked_syscalls[i] + ? (struct sock_filter) BPF_STMT( + BPF_RET | BPF_K, SECCOMP_RET_ERRNO | ENOSYS) + : UL_BPF_NOP; } struct sock_fprog prog = { |