summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Weißschuh <thomas@t-8ch.de>2023-05-05 00:38:11 +0200
committerThomas Weißschuh <thomas@t-8ch.de>2023-05-16 22:44:50 +0200
commit5e248716e6ac7c08f24d5cc0856a13a94395faca (patch)
tree57d87edc132b75ee53c14ea37455096b0388cf8c
parent7f104027e2a0929e71fa1307dcfe94f5217799a5 (diff)
downloadutil-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.c24
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 = {