diff options
author | Damien Miller <djm@mindrot.org> | 2019-08-23 10:08:48 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2019-08-23 10:10:03 +1000 |
commit | f6906f9bf12c968debec3671bbf19926ff8a235b (patch) | |
tree | 0e540b08f4bc1246a1ee910224767aa67acc3a19 /sandbox-seccomp-filter.c | |
parent | e3b6c966b79c3ea5d51b923c3bbdc41e13b96ea0 (diff) |
allow mprotect(2) with PROT_(READ|WRITE|NONE) only
Used by some hardened heap allocators. Requested by Yegor
Timoshenko in https://github.com/openssh/openssh-portable/pull/142
Diffstat (limited to 'sandbox-seccomp-filter.c')
-rw-r--r-- | sandbox-seccomp-filter.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c index 56eb9317f..7b44755cb 100644 --- a/sandbox-seccomp-filter.c +++ b/sandbox-seccomp-filter.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <sys/types.h> | 42 | #include <sys/types.h> |
43 | #include <sys/resource.h> | 43 | #include <sys/resource.h> |
44 | #include <sys/prctl.h> | 44 | #include <sys/prctl.h> |
45 | #include <sys/mman.h> | ||
45 | 46 | ||
46 | #include <linux/net.h> | 47 | #include <linux/net.h> |
47 | #include <linux/audit.h> | 48 | #include <linux/audit.h> |
@@ -95,12 +96,12 @@ | |||
95 | BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW) | 96 | BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW) |
96 | #define SC_ALLOW_ARG(_nr, _arg_nr, _arg_val) \ | 97 | #define SC_ALLOW_ARG(_nr, _arg_nr, _arg_val) \ |
97 | BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_nr), 0, 6), \ | 98 | BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_nr), 0, 6), \ |
98 | /* load and test first syscall argument, low word */ \ | 99 | /* load and test syscall argument, low word */ \ |
99 | BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ | 100 | BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ |
100 | offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_LO_OFFSET), \ | 101 | offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_LO_OFFSET), \ |
101 | BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \ | 102 | BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \ |
102 | ((_arg_val) & 0xFFFFFFFF), 0, 3), \ | 103 | ((_arg_val) & 0xFFFFFFFF), 0, 3), \ |
103 | /* load and test first syscall argument, high word */ \ | 104 | /* load and test syscall argument, high word */ \ |
104 | BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ | 105 | BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ |
105 | offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_HI_OFFSET), \ | 106 | offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_HI_OFFSET), \ |
106 | BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \ | 107 | BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \ |
@@ -109,6 +110,24 @@ | |||
109 | /* reload syscall number; all rules expect it in accumulator */ \ | 110 | /* reload syscall number; all rules expect it in accumulator */ \ |
110 | BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ | 111 | BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ |
111 | offsetof(struct seccomp_data, nr)) | 112 | offsetof(struct seccomp_data, nr)) |
113 | /* Allow if syscall argument contains only values in mask */ | ||
114 | #define SC_ALLOW_ARG_MASK(_nr, _arg_nr, _arg_mask) \ | ||
115 | BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_nr), 0, 8), \ | ||
116 | /* load, mask and test syscall argument, low word */ \ | ||
117 | BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ | ||
118 | offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_LO_OFFSET), \ | ||
119 | BPF_STMT(BPF_ALU+BPF_AND+BPF_K, ~((_arg_mask) & 0xFFFFFFFF)), \ | ||
120 | BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 4), \ | ||
121 | /* load, mask and test syscall argument, high word */ \ | ||
122 | BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ | ||
123 | offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_HI_OFFSET), \ | ||
124 | BPF_STMT(BPF_ALU+BPF_AND+BPF_K, \ | ||
125 | ~(((uint32_t)((uint64_t)(_arg_mask) >> 32)) & 0xFFFFFFFF)), \ | ||
126 | BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 1), \ | ||
127 | BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW), \ | ||
128 | /* reload syscall number; all rules expect it in accumulator */ \ | ||
129 | BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ | ||
130 | offsetof(struct seccomp_data, nr)) | ||
112 | 131 | ||
113 | /* Syscall filtering set for preauth. */ | 132 | /* Syscall filtering set for preauth. */ |
114 | static const struct sock_filter preauth_insns[] = { | 133 | static const struct sock_filter preauth_insns[] = { |
@@ -202,6 +221,9 @@ static const struct sock_filter preauth_insns[] = { | |||
202 | #ifdef __NR_mmap2 | 221 | #ifdef __NR_mmap2 |
203 | SC_ALLOW(__NR_mmap2), | 222 | SC_ALLOW(__NR_mmap2), |
204 | #endif | 223 | #endif |
224 | #ifdef __NR_mprotect | ||
225 | SC_ALLOW_ARG_MASK(__NR_mprotect, 2, PROT_READ|PROT_WRITE|PROT_NONE), | ||
226 | #endif | ||
205 | #ifdef __NR_mremap | 227 | #ifdef __NR_mremap |
206 | SC_ALLOW(__NR_mremap), | 228 | SC_ALLOW(__NR_mremap), |
207 | #endif | 229 | #endif |