summaryrefslogtreecommitdiff
path: root/sandbox-seccomp-filter.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2017-03-14 12:24:47 +1100
committerDamien Miller <djm@mindrot.org>2017-03-14 12:41:53 +1100
commit9e96b41682aed793fadbea5ccd472f862179fb02 (patch)
tree8f28c1e60284176348973ff19101785772e18bb8 /sandbox-seccomp-filter.c
parent8ff3fc3f2f7c13e8968717bc2b895ee32c441275 (diff)
Fix weakness in seccomp-bpf sandbox arg inspection
Syscall arguments are passed via an array of 64-bit values in struct seccomp_data, but we were only inspecting the bottom 32 bits and not even those correctly for BE systems. Fortunately, the only case argument inspection was used was in the socketcall filtering so using this for sandbox escape seems impossible. ok dtucker
Diffstat (limited to 'sandbox-seccomp-filter.c')
-rw-r--r--sandbox-seccomp-filter.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c
index 2e1ed2c52..af5525abb 100644
--- a/sandbox-seccomp-filter.c
+++ b/sandbox-seccomp-filter.c
@@ -73,6 +73,16 @@
73# define SECCOMP_FILTER_FAIL SECCOMP_RET_TRAP 73# define SECCOMP_FILTER_FAIL SECCOMP_RET_TRAP
74#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ 74#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */
75 75
76#if __BYTE_ORDER == __LITTLE_ENDIAN
77# define ARG_LO_OFFSET 0
78# define ARG_HI_OFFSET sizeof(uint32_t)
79#elif __BYTE_ORDER == __BIG_ENDIAN
80# define ARG_LO_OFFSET sizeof(uint32_t)
81# define ARG_HI_OFFSET 0
82#else
83#error "Unknown endianness"
84#endif
85
76/* Simple helpers to avoid manual errors (but larger BPF programs). */ 86/* Simple helpers to avoid manual errors (but larger BPF programs). */
77#define SC_DENY(_nr, _errno) \ 87#define SC_DENY(_nr, _errno) \
78 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \ 88 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \
@@ -81,11 +91,17 @@
81 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \ 91 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \
82 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW) 92 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
83#define SC_ALLOW_ARG(_nr, _arg_nr, _arg_val) \ 93#define SC_ALLOW_ARG(_nr, _arg_nr, _arg_val) \
84 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 4), \ 94 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 6), \
85 /* load first syscall argument */ \ 95 /* load and test first syscall argument, low word */ \
96 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
97 offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_LO_OFFSET), \
98 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \
99 ((_arg_val) & 0xFFFFFFFF), 0, 3), \
100 /* load and test first syscall argument, high word */ \
86 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ 101 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
87 offsetof(struct seccomp_data, args[(_arg_nr)])), \ 102 offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_HI_OFFSET), \
88 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_arg_val), 0, 1), \ 103 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \
104 (((uint32_t)((uint64_t)(_arg_val) >> 32)) & 0xFFFFFFFF), 0, 1), \
89 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW), \ 105 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW), \
90 /* reload syscall number; all rules expect it in accumulator */ \ 106 /* reload syscall number; all rules expect it in accumulator */ \
91 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ 107 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \