Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Side by Side Diff: sandbox/linux/bpf_dsl/bpf_dsl_unittest.cc

Issue 944823002: Revert of bpf_dsl: Change bpf_dsl_unittests into actual standalone unit tests (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | sandbox/linux/bpf_dsl/seccomp_macros.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "sandbox/linux/bpf_dsl/bpf_dsl.h" 5 #include "sandbox/linux/bpf_dsl/bpf_dsl.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <netinet/in.h> 9 #include <netinet/in.h>
10 #include <sys/socket.h> 10 #include <sys/socket.h>
11 #include <sys/syscall.h> 11 #include <sys/syscall.h>
12 #include <sys/utsname.h> 12 #include <sys/utsname.h>
13 #include <unistd.h> 13 #include <unistd.h>
14 14
15 #include "base/files/scoped_file.h" 15 #include "base/files/scoped_file.h"
16 #include "base/macros.h" 16 #include "base/macros.h"
17 #include "build/build_config.h" 17 #include "build/build_config.h"
18 #include "sandbox/linux/bpf_dsl/bpf_dsl_impl.h" 18 #include "sandbox/linux/bpf_dsl/bpf_dsl_impl.h"
19 #include "sandbox/linux/bpf_dsl/codegen.h"
20 #include "sandbox/linux/bpf_dsl/policy.h" 19 #include "sandbox/linux/bpf_dsl/policy.h"
21 #include "sandbox/linux/bpf_dsl/policy_compiler.h" 20 #include "sandbox/linux/seccomp-bpf/bpf_tests.h"
22 #include "sandbox/linux/bpf_dsl/seccomp_macros.h"
23 #include "sandbox/linux/bpf_dsl/trap_registry.h"
24 #include "sandbox/linux/seccomp-bpf/errorcode.h" 21 #include "sandbox/linux/seccomp-bpf/errorcode.h"
25 #include "sandbox/linux/seccomp-bpf/verifier.h" 22 #include "sandbox/linux/seccomp-bpf/syscall.h"
26 #include "testing/gtest/include/gtest/gtest.h" 23 #include "testing/gtest/include/gtest/gtest.h"
27 24
28 #define CASES SANDBOX_BPF_DSL_CASES 25 #define CASES SANDBOX_BPF_DSL_CASES
29 26
27 // Helper macro to assert that invoking system call |sys| directly via
28 // Syscall::Call with arguments |...| returns |res|.
29 // Errors can be asserted by specifying a value like "-EINVAL".
30 #define ASSERT_SYSCALL_RESULT(res, sys, ...) \
31 BPF_ASSERT_EQ(res, Stubs::sys(__VA_ARGS__))
32
30 namespace sandbox { 33 namespace sandbox {
31 namespace bpf_dsl { 34 namespace bpf_dsl {
32 namespace { 35 namespace {
33 36
34 // Helper function to construct fake arch_seccomp_data objects. 37 // Type safe stubs for tested system calls.
35 struct arch_seccomp_data FakeSyscall(int nr, 38 class Stubs {
36 uint64_t p0 = 0,
37 uint64_t p1 = 0,
38 uint64_t p2 = 0,
39 uint64_t p3 = 0,
40 uint64_t p4 = 0,
41 uint64_t p5 = 0) {
42 // Made up program counter for syscall address.
43 const uint64_t kFakePC = 0x543210;
44
45 struct arch_seccomp_data data = {
46 nr,
47 SECCOMP_ARCH,
48 kFakePC,
49 {
50 p0, p1, p2, p3, p4, p5,
51 },
52 };
53
54 return data;
55 }
56
57 class FakeTrapRegistry : public TrapRegistry {
58 public: 39 public:
59 FakeTrapRegistry() : next_id_(1) {} 40 static int getpgid(pid_t pid) { return Syscall::Call(__NR_getpgid, pid); }
60 virtual ~FakeTrapRegistry() {} 41 static int setuid(uid_t uid) { return Syscall::Call(__NR_setuid, uid); }
61 42 static int setgid(gid_t gid) { return Syscall::Call(__NR_setgid, gid); }
62 uint16_t Add(TrapFnc fnc, const void* aux, bool safe) override { 43 static int setpgid(pid_t pid, pid_t pgid) {
63 EXPECT_NE(0U, next_id_); 44 return Syscall::Call(__NR_setpgid, pid, pgid);
64 return next_id_++;
65 } 45 }
66 46
67 bool EnableUnsafeTraps() override { 47 static int fcntl(int fd, int cmd, unsigned long arg = 0) {
68 ADD_FAILURE() << "Unimplemented"; 48 return Syscall::Call(__NR_fcntl, fd, cmd, arg);
69 return false;
70 } 49 }
71 50
72 private: 51 static int uname(struct utsname* buf) {
73 uint16_t next_id_; 52 return Syscall::Call(__NR_uname, buf);
74
75 DISALLOW_COPY_AND_ASSIGN(FakeTrapRegistry);
76 };
77
78 class PolicyEmulator {
79 public:
80 explicit PolicyEmulator(const Policy* policy) : program_(), traps_() {
81 program_ = *PolicyCompiler(policy, &traps_).Compile();
82 }
83 ~PolicyEmulator() {}
84
85 uint32_t Emulate(const struct arch_seccomp_data& data) const {
86 const char* err = nullptr;
87 uint32_t res = Verifier::EvaluateBPF(program_, data, &err);
88 if (err) {
89 ADD_FAILURE() << err;
90 return 0;
91 }
92 return res;
93 } 53 }
94 54
95 void ExpectAllow(const struct arch_seccomp_data& data) const { 55 static int setresuid(uid_t ruid, uid_t euid, uid_t suid) {
96 EXPECT_EQ(SECCOMP_RET_ALLOW, Emulate(data)); 56 return Syscall::Call(__NR_setresuid, ruid, euid, suid);
97 } 57 }
98 58
99 void ExpectErrno(uint16_t err, const struct arch_seccomp_data& data) const { 59 #if !defined(ARCH_CPU_X86)
100 EXPECT_EQ(SECCOMP_RET_ERRNO | err, Emulate(data)); 60 static int socketpair(int domain, int type, int protocol, int sv[2]) {
61 return Syscall::Call(__NR_socketpair, domain, type, protocol, sv);
101 } 62 }
102 63 #endif
103 private:
104 CodeGen::Program program_;
105 FakeTrapRegistry traps_;
106
107 DISALLOW_COPY_AND_ASSIGN(PolicyEmulator);
108 }; 64 };
109 65
110 class BasicPolicy : public Policy { 66 class BasicPolicy : public Policy {
111 public: 67 public:
112 BasicPolicy() {} 68 BasicPolicy() {}
113 ~BasicPolicy() override {} 69 ~BasicPolicy() override {}
114 ResultExpr EvaluateSyscall(int sysno) const override { 70 ResultExpr EvaluateSyscall(int sysno) const override {
115 if (sysno == __NR_getpgid) { 71 if (sysno == __NR_getpgid) {
116 const Arg<pid_t> pid(0); 72 const Arg<pid_t> pid(0);
117 return If(pid == 0, Error(EPERM)).Else(Error(EINVAL)); 73 return If(pid == 0, Error(EPERM)).Else(Error(EINVAL));
118 } 74 }
119 if (sysno == __NR_setuid) { 75 if (sysno == __NR_setuid) {
120 const Arg<uid_t> uid(0); 76 const Arg<uid_t> uid(0);
121 return If(uid != 42, Error(ESRCH)).Else(Error(ENOMEM)); 77 return If(uid != 42, Error(ESRCH)).Else(Error(ENOMEM));
122 } 78 }
123 return Allow(); 79 return Allow();
124 } 80 }
125 81
126 private: 82 private:
127 DISALLOW_COPY_AND_ASSIGN(BasicPolicy); 83 DISALLOW_COPY_AND_ASSIGN(BasicPolicy);
128 }; 84 };
129 85
130 TEST(BPFDSL, Basic) { 86 BPF_TEST_C(BPFDSL, Basic, BasicPolicy) {
131 BasicPolicy policy; 87 ASSERT_SYSCALL_RESULT(-EPERM, getpgid, 0);
132 PolicyEmulator emulator(&policy); 88 ASSERT_SYSCALL_RESULT(-EINVAL, getpgid, 1);
133 89
134 emulator.ExpectErrno(EPERM, FakeSyscall(__NR_getpgid, 0)); 90 ASSERT_SYSCALL_RESULT(-ENOMEM, setuid, 42);
135 emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_getpgid, 1)); 91 ASSERT_SYSCALL_RESULT(-ESRCH, setuid, 43);
136
137 emulator.ExpectErrno(ENOMEM, FakeSyscall(__NR_setuid, 42));
138 emulator.ExpectErrno(ESRCH, FakeSyscall(__NR_setuid, 43));
139 } 92 }
140 93
141 /* On IA-32, socketpair() is implemented via socketcall(). :-( */ 94 /* On IA-32, socketpair() is implemented via socketcall(). :-( */
142 #if !defined(ARCH_CPU_X86) 95 #if !defined(ARCH_CPU_X86)
143 class BooleanLogicPolicy : public Policy { 96 class BooleanLogicPolicy : public Policy {
144 public: 97 public:
145 BooleanLogicPolicy() {} 98 BooleanLogicPolicy() {}
146 ~BooleanLogicPolicy() override {} 99 ~BooleanLogicPolicy() override {}
147 ResultExpr EvaluateSyscall(int sysno) const override { 100 ResultExpr EvaluateSyscall(int sysno) const override {
148 if (sysno == __NR_socketpair) { 101 if (sysno == __NR_socketpair) {
149 const Arg<int> domain(0), type(1), protocol(2); 102 const Arg<int> domain(0), type(1), protocol(2);
150 return If(domain == AF_UNIX && 103 return If(domain == AF_UNIX &&
151 (type == SOCK_STREAM || type == SOCK_DGRAM) && 104 (type == SOCK_STREAM || type == SOCK_DGRAM) &&
152 protocol == 0, 105 protocol == 0,
153 Error(EPERM)).Else(Error(EINVAL)); 106 Error(EPERM)).Else(Error(EINVAL));
154 } 107 }
155 return Allow(); 108 return Allow();
156 } 109 }
157 110
158 private: 111 private:
159 DISALLOW_COPY_AND_ASSIGN(BooleanLogicPolicy); 112 DISALLOW_COPY_AND_ASSIGN(BooleanLogicPolicy);
160 }; 113 };
161 114
162 TEST(BPFDSL, BooleanLogic) { 115 BPF_TEST_C(BPFDSL, BooleanLogic, BooleanLogicPolicy) {
163 BooleanLogicPolicy policy; 116 int sv[2];
164 PolicyEmulator emulator(&policy);
165
166 const intptr_t kFakeSV = 0x12345;
167 117
168 // Acceptable combinations that should return EPERM. 118 // Acceptable combinations that should return EPERM.
169 emulator.ExpectErrno( 119 ASSERT_SYSCALL_RESULT(-EPERM, socketpair, AF_UNIX, SOCK_STREAM, 0, sv);
170 EPERM, FakeSyscall(__NR_socketpair, AF_UNIX, SOCK_STREAM, 0, kFakeSV)); 120 ASSERT_SYSCALL_RESULT(-EPERM, socketpair, AF_UNIX, SOCK_DGRAM, 0, sv);
171 emulator.ExpectErrno(
172 EPERM, FakeSyscall(__NR_socketpair, AF_UNIX, SOCK_DGRAM, 0, kFakeSV));
173 121
174 // Combinations that are invalid for only one reason; should return EINVAL. 122 // Combinations that are invalid for only one reason; should return EINVAL.
175 emulator.ExpectErrno( 123 ASSERT_SYSCALL_RESULT(-EINVAL, socketpair, AF_INET, SOCK_STREAM, 0, sv);
176 EINVAL, FakeSyscall(__NR_socketpair, AF_INET, SOCK_STREAM, 0, kFakeSV)); 124 ASSERT_SYSCALL_RESULT(-EINVAL, socketpair, AF_UNIX, SOCK_SEQPACKET, 0, sv);
177 emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_socketpair, AF_UNIX, 125 ASSERT_SYSCALL_RESULT(
178 SOCK_SEQPACKET, 0, kFakeSV)); 126 -EINVAL, socketpair, AF_UNIX, SOCK_STREAM, IPPROTO_TCP, sv);
179 emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_socketpair, AF_UNIX,
180 SOCK_STREAM, IPPROTO_TCP, kFakeSV));
181 127
182 // Completely unacceptable combination; should also return EINVAL. 128 // Completely unacceptable combination; should also return EINVAL.
183 emulator.ExpectErrno( 129 ASSERT_SYSCALL_RESULT(
184 EINVAL, FakeSyscall(__NR_socketpair, AF_INET, SOCK_SEQPACKET, IPPROTO_UDP, 130 -EINVAL, socketpair, AF_INET, SOCK_SEQPACKET, IPPROTO_UDP, sv);
185 kFakeSV));
186 } 131 }
187 #endif // !ARCH_CPU_X86 132 #endif // !ARCH_CPU_X86
188 133
189 class MoreBooleanLogicPolicy : public Policy { 134 class MoreBooleanLogicPolicy : public Policy {
190 public: 135 public:
191 MoreBooleanLogicPolicy() {} 136 MoreBooleanLogicPolicy() {}
192 ~MoreBooleanLogicPolicy() override {} 137 ~MoreBooleanLogicPolicy() override {}
193 ResultExpr EvaluateSyscall(int sysno) const override { 138 ResultExpr EvaluateSyscall(int sysno) const override {
194 if (sysno == __NR_setresuid) { 139 if (sysno == __NR_setresuid) {
195 const Arg<uid_t> ruid(0), euid(1), suid(2); 140 const Arg<uid_t> ruid(0), euid(1), suid(2);
196 return If(ruid == 0 || euid == 0 || suid == 0, Error(EPERM)) 141 return If(ruid == 0 || euid == 0 || suid == 0, Error(EPERM))
197 .ElseIf(ruid == 1 && euid == 1 && suid == 1, Error(EAGAIN)) 142 .ElseIf(ruid == 1 && euid == 1 && suid == 1, Error(EAGAIN))
198 .Else(Error(EINVAL)); 143 .Else(Error(EINVAL));
199 } 144 }
200 return Allow(); 145 return Allow();
201 } 146 }
202 147
203 private: 148 private:
204 DISALLOW_COPY_AND_ASSIGN(MoreBooleanLogicPolicy); 149 DISALLOW_COPY_AND_ASSIGN(MoreBooleanLogicPolicy);
205 }; 150 };
206 151
207 TEST(BPFDSL, MoreBooleanLogic) { 152 BPF_TEST_C(BPFDSL, MoreBooleanLogic, MoreBooleanLogicPolicy) {
208 MoreBooleanLogicPolicy policy;
209 PolicyEmulator emulator(&policy);
210
211 // Expect EPERM if any set to 0. 153 // Expect EPERM if any set to 0.
212 emulator.ExpectErrno(EPERM, FakeSyscall(__NR_setresuid, 0, 5, 5)); 154 ASSERT_SYSCALL_RESULT(-EPERM, setresuid, 0, 5, 5);
213 emulator.ExpectErrno(EPERM, FakeSyscall(__NR_setresuid, 5, 0, 5)); 155 ASSERT_SYSCALL_RESULT(-EPERM, setresuid, 5, 0, 5);
214 emulator.ExpectErrno(EPERM, FakeSyscall(__NR_setresuid, 5, 5, 0)); 156 ASSERT_SYSCALL_RESULT(-EPERM, setresuid, 5, 5, 0);
215 157
216 // Expect EAGAIN if all set to 1. 158 // Expect EAGAIN if all set to 1.
217 emulator.ExpectErrno(EAGAIN, FakeSyscall(__NR_setresuid, 1, 1, 1)); 159 ASSERT_SYSCALL_RESULT(-EAGAIN, setresuid, 1, 1, 1);
218 160
219 // Expect EINVAL for anything else. 161 // Expect EINVAL for anything else.
220 emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_setresuid, 5, 1, 1)); 162 ASSERT_SYSCALL_RESULT(-EINVAL, setresuid, 5, 1, 1);
221 emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_setresuid, 1, 5, 1)); 163 ASSERT_SYSCALL_RESULT(-EINVAL, setresuid, 1, 5, 1);
222 emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_setresuid, 1, 1, 5)); 164 ASSERT_SYSCALL_RESULT(-EINVAL, setresuid, 1, 1, 5);
223 emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_setresuid, 3, 4, 5)); 165 ASSERT_SYSCALL_RESULT(-EINVAL, setresuid, 3, 4, 5);
224 } 166 }
225 167
226 static const uintptr_t kDeadBeefAddr = 168 static const uintptr_t kDeadBeefAddr =
227 static_cast<uintptr_t>(0xdeadbeefdeadbeefULL); 169 static_cast<uintptr_t>(0xdeadbeefdeadbeefULL);
228 170
229 class ArgSizePolicy : public Policy { 171 class ArgSizePolicy : public Policy {
230 public: 172 public:
231 ArgSizePolicy() {} 173 ArgSizePolicy() {}
232 ~ArgSizePolicy() override {} 174 ~ArgSizePolicy() override {}
233 ResultExpr EvaluateSyscall(int sysno) const override { 175 ResultExpr EvaluateSyscall(int sysno) const override {
234 if (sysno == __NR_uname) { 176 if (sysno == __NR_uname) {
235 const Arg<uintptr_t> addr(0); 177 const Arg<uintptr_t> addr(0);
236 return If(addr == kDeadBeefAddr, Error(EPERM)).Else(Allow()); 178 return If(addr == kDeadBeefAddr, Error(EPERM)).Else(Allow());
237 } 179 }
238 return Allow(); 180 return Allow();
239 } 181 }
240 182
241 private: 183 private:
242 DISALLOW_COPY_AND_ASSIGN(ArgSizePolicy); 184 DISALLOW_COPY_AND_ASSIGN(ArgSizePolicy);
243 }; 185 };
244 186
245 TEST(BPFDSL, ArgSizeTest) { 187 BPF_TEST_C(BPFDSL, ArgSizeTest, ArgSizePolicy) {
246 ArgSizePolicy policy; 188 struct utsname buf;
247 PolicyEmulator emulator(&policy); 189 ASSERT_SYSCALL_RESULT(0, uname, &buf);
248 190 ASSERT_SYSCALL_RESULT(
249 emulator.ExpectAllow(FakeSyscall(__NR_uname, 0)); 191 -EPERM, uname, reinterpret_cast<struct utsname*>(kDeadBeefAddr));
250 emulator.ExpectErrno(EPERM, FakeSyscall(__NR_uname, kDeadBeefAddr));
251 } 192 }
252 193
253 #if 0
254 // TODO(mdempsky): This is really an integration test.
255
256 class TrappingPolicy : public Policy { 194 class TrappingPolicy : public Policy {
257 public: 195 public:
258 TrappingPolicy() {} 196 TrappingPolicy() {}
259 ~TrappingPolicy() override {} 197 ~TrappingPolicy() override {}
260 ResultExpr EvaluateSyscall(int sysno) const override { 198 ResultExpr EvaluateSyscall(int sysno) const override {
261 if (sysno == __NR_uname) { 199 if (sysno == __NR_uname) {
262 return Trap(UnameTrap, &count_); 200 return Trap(UnameTrap, &count_);
263 } 201 }
264 return Allow(); 202 return Allow();
265 } 203 }
266 204
267 private: 205 private:
268 static intptr_t count_; 206 static intptr_t count_;
269 207
270 static intptr_t UnameTrap(const struct arch_seccomp_data& data, void* aux) { 208 static intptr_t UnameTrap(const struct arch_seccomp_data& data, void* aux) {
271 BPF_ASSERT_EQ(&count_, aux); 209 BPF_ASSERT_EQ(&count_, aux);
272 return ++count_; 210 return ++count_;
273 } 211 }
274 212
275 DISALLOW_COPY_AND_ASSIGN(TrappingPolicy); 213 DISALLOW_COPY_AND_ASSIGN(TrappingPolicy);
276 }; 214 };
277 215
278 intptr_t TrappingPolicy::count_; 216 intptr_t TrappingPolicy::count_;
279 217
280 BPF_TEST_C(BPFDSL, TrapTest, TrappingPolicy) { 218 BPF_TEST_C(BPFDSL, TrapTest, TrappingPolicy) {
281 ASSERT_SYSCALL_RESULT(1, uname, NULL); 219 ASSERT_SYSCALL_RESULT(1, uname, NULL);
282 ASSERT_SYSCALL_RESULT(2, uname, NULL); 220 ASSERT_SYSCALL_RESULT(2, uname, NULL);
283 ASSERT_SYSCALL_RESULT(3, uname, NULL); 221 ASSERT_SYSCALL_RESULT(3, uname, NULL);
284 } 222 }
285 #endif
286 223
287 class MaskingPolicy : public Policy { 224 class MaskingPolicy : public Policy {
288 public: 225 public:
289 MaskingPolicy() {} 226 MaskingPolicy() {}
290 ~MaskingPolicy() override {} 227 ~MaskingPolicy() override {}
291 ResultExpr EvaluateSyscall(int sysno) const override { 228 ResultExpr EvaluateSyscall(int sysno) const override {
292 if (sysno == __NR_setuid) { 229 if (sysno == __NR_setuid) {
293 const Arg<uid_t> uid(0); 230 const Arg<uid_t> uid(0);
294 return If((uid & 0xf) == 0, Error(EINVAL)).Else(Error(EACCES)); 231 return If((uid & 0xf) == 0, Error(EINVAL)).Else(Error(EACCES));
295 } 232 }
296 if (sysno == __NR_setgid) { 233 if (sysno == __NR_setgid) {
297 const Arg<gid_t> gid(0); 234 const Arg<gid_t> gid(0);
298 return If((gid & 0xf0) == 0xf0, Error(EINVAL)).Else(Error(EACCES)); 235 return If((gid & 0xf0) == 0xf0, Error(EINVAL)).Else(Error(EACCES));
299 } 236 }
300 if (sysno == __NR_setpgid) { 237 if (sysno == __NR_setpgid) {
301 const Arg<pid_t> pid(0); 238 const Arg<pid_t> pid(0);
302 return If((pid & 0xa5) == 0xa0, Error(EINVAL)).Else(Error(EACCES)); 239 return If((pid & 0xa5) == 0xa0, Error(EINVAL)).Else(Error(EACCES));
303 } 240 }
304 return Allow(); 241 return Allow();
305 } 242 }
306 243
307 private: 244 private:
308 DISALLOW_COPY_AND_ASSIGN(MaskingPolicy); 245 DISALLOW_COPY_AND_ASSIGN(MaskingPolicy);
309 }; 246 };
310 247
311 TEST(BPFDSL, MaskTest) { 248 BPF_TEST_C(BPFDSL, MaskTest, MaskingPolicy) {
312 MaskingPolicy policy;
313 PolicyEmulator emulator(&policy);
314
315 for (uid_t uid = 0; uid < 0x100; ++uid) { 249 for (uid_t uid = 0; uid < 0x100; ++uid) {
316 const int expect_errno = (uid & 0xf) == 0 ? EINVAL : EACCES; 250 const int expect_errno = (uid & 0xf) == 0 ? EINVAL : EACCES;
317 emulator.ExpectErrno(expect_errno, FakeSyscall(__NR_setuid, uid)); 251 ASSERT_SYSCALL_RESULT(-expect_errno, setuid, uid);
318 } 252 }
319 253
320 for (gid_t gid = 0; gid < 0x100; ++gid) { 254 for (gid_t gid = 0; gid < 0x100; ++gid) {
321 const int expect_errno = (gid & 0xf0) == 0xf0 ? EINVAL : EACCES; 255 const int expect_errno = (gid & 0xf0) == 0xf0 ? EINVAL : EACCES;
322 emulator.ExpectErrno(expect_errno, FakeSyscall(__NR_setgid, gid)); 256 ASSERT_SYSCALL_RESULT(-expect_errno, setgid, gid);
323 } 257 }
324 258
325 for (pid_t pid = 0; pid < 0x100; ++pid) { 259 for (pid_t pid = 0; pid < 0x100; ++pid) {
326 const int expect_errno = (pid & 0xa5) == 0xa0 ? EINVAL : EACCES; 260 const int expect_errno = (pid & 0xa5) == 0xa0 ? EINVAL : EACCES;
327 emulator.ExpectErrno(expect_errno, FakeSyscall(__NR_setpgid, pid, 0)); 261 ASSERT_SYSCALL_RESULT(-expect_errno, setpgid, pid, 0);
328 } 262 }
329 } 263 }
330 264
331 class ElseIfPolicy : public Policy { 265 class ElseIfPolicy : public Policy {
332 public: 266 public:
333 ElseIfPolicy() {} 267 ElseIfPolicy() {}
334 ~ElseIfPolicy() override {} 268 ~ElseIfPolicy() override {}
335 ResultExpr EvaluateSyscall(int sysno) const override { 269 ResultExpr EvaluateSyscall(int sysno) const override {
336 if (sysno == __NR_setuid) { 270 if (sysno == __NR_setuid) {
337 const Arg<uid_t> uid(0); 271 const Arg<uid_t> uid(0);
338 return If((uid & 0xfff) == 0, Error(0)) 272 return If((uid & 0xfff) == 0, Error(0))
339 .ElseIf((uid & 0xff0) == 0, Error(EINVAL)) 273 .ElseIf((uid & 0xff0) == 0, Error(EINVAL))
340 .ElseIf((uid & 0xf00) == 0, Error(EEXIST)) 274 .ElseIf((uid & 0xf00) == 0, Error(EEXIST))
341 .Else(Error(EACCES)); 275 .Else(Error(EACCES));
342 } 276 }
343 return Allow(); 277 return Allow();
344 } 278 }
345 279
346 private: 280 private:
347 DISALLOW_COPY_AND_ASSIGN(ElseIfPolicy); 281 DISALLOW_COPY_AND_ASSIGN(ElseIfPolicy);
348 }; 282 };
349 283
350 TEST(BPFDSL, ElseIfTest) { 284 BPF_TEST_C(BPFDSL, ElseIfTest, ElseIfPolicy) {
351 ElseIfPolicy policy; 285 ASSERT_SYSCALL_RESULT(0, setuid, 0);
352 PolicyEmulator emulator(&policy);
353 286
354 emulator.ExpectErrno(0, FakeSyscall(__NR_setuid, 0)); 287 ASSERT_SYSCALL_RESULT(-EINVAL, setuid, 0x0001);
288 ASSERT_SYSCALL_RESULT(-EINVAL, setuid, 0x0002);
355 289
356 emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_setuid, 0x0001)); 290 ASSERT_SYSCALL_RESULT(-EEXIST, setuid, 0x0011);
357 emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_setuid, 0x0002)); 291 ASSERT_SYSCALL_RESULT(-EEXIST, setuid, 0x0022);
358 292
359 emulator.ExpectErrno(EEXIST, FakeSyscall(__NR_setuid, 0x0011)); 293 ASSERT_SYSCALL_RESULT(-EACCES, setuid, 0x0111);
360 emulator.ExpectErrno(EEXIST, FakeSyscall(__NR_setuid, 0x0022)); 294 ASSERT_SYSCALL_RESULT(-EACCES, setuid, 0x0222);
361
362 emulator.ExpectErrno(EACCES, FakeSyscall(__NR_setuid, 0x0111));
363 emulator.ExpectErrno(EACCES, FakeSyscall(__NR_setuid, 0x0222));
364 } 295 }
365 296
366 class SwitchPolicy : public Policy { 297 class SwitchPolicy : public Policy {
367 public: 298 public:
368 SwitchPolicy() {} 299 SwitchPolicy() {}
369 ~SwitchPolicy() override {} 300 ~SwitchPolicy() override {}
370 ResultExpr EvaluateSyscall(int sysno) const override { 301 ResultExpr EvaluateSyscall(int sysno) const override {
371 if (sysno == __NR_fcntl) { 302 if (sysno == __NR_fcntl) {
372 const Arg<int> cmd(1); 303 const Arg<int> cmd(1);
373 const Arg<unsigned long> long_arg(2); 304 const Arg<unsigned long> long_arg(2);
374 return Switch(cmd) 305 return Switch(cmd)
375 .CASES((F_GETFL, F_GETFD), Error(ENOENT)) 306 .CASES((F_GETFL, F_GETFD), Error(ENOENT))
376 .Case(F_SETFD, If(long_arg == O_CLOEXEC, Allow()).Else(Error(EINVAL))) 307 .Case(F_SETFD, If(long_arg == O_CLOEXEC, Allow()).Else(Error(EINVAL)))
377 .Case(F_SETFL, Error(EPERM)) 308 .Case(F_SETFL, Error(EPERM))
378 .Default(Error(EACCES)); 309 .Default(Error(EACCES));
379 } 310 }
380 return Allow(); 311 return Allow();
381 } 312 }
382 313
383 private: 314 private:
384 DISALLOW_COPY_AND_ASSIGN(SwitchPolicy); 315 DISALLOW_COPY_AND_ASSIGN(SwitchPolicy);
385 }; 316 };
386 317
387 TEST(BPFDSL, SwitchTest) { 318 BPF_TEST_C(BPFDSL, SwitchTest, SwitchPolicy) {
388 SwitchPolicy policy; 319 base::ScopedFD sock_fd(socket(AF_UNIX, SOCK_STREAM, 0));
389 PolicyEmulator emulator(&policy); 320 BPF_ASSERT(sock_fd.is_valid());
390 321
391 const int kFakeSockFD = 42; 322 ASSERT_SYSCALL_RESULT(-ENOENT, fcntl, sock_fd.get(), F_GETFD);
323 ASSERT_SYSCALL_RESULT(-ENOENT, fcntl, sock_fd.get(), F_GETFL);
392 324
393 emulator.ExpectErrno(ENOENT, FakeSyscall(__NR_fcntl, kFakeSockFD, F_GETFD)); 325 ASSERT_SYSCALL_RESULT(0, fcntl, sock_fd.get(), F_SETFD, O_CLOEXEC);
394 emulator.ExpectErrno(ENOENT, FakeSyscall(__NR_fcntl, kFakeSockFD, F_GETFL)); 326 ASSERT_SYSCALL_RESULT(-EINVAL, fcntl, sock_fd.get(), F_SETFD, 0);
395 327
396 emulator.ExpectAllow( 328 ASSERT_SYSCALL_RESULT(-EPERM, fcntl, sock_fd.get(), F_SETFL, O_RDONLY);
397 FakeSyscall(__NR_fcntl, kFakeSockFD, F_SETFD, O_CLOEXEC));
398 emulator.ExpectErrno(EINVAL,
399 FakeSyscall(__NR_fcntl, kFakeSockFD, F_SETFD, 0));
400 329
401 emulator.ExpectErrno(EPERM, 330 ASSERT_SYSCALL_RESULT(-EACCES, fcntl, sock_fd.get(), F_DUPFD, 0);
402 FakeSyscall(__NR_fcntl, kFakeSockFD, F_SETFL, O_RDONLY));
403
404 emulator.ExpectErrno(EACCES,
405 FakeSyscall(__NR_fcntl, kFakeSockFD, F_DUPFD, 0));
406 } 331 }
407 332
408 static intptr_t DummyTrap(const struct arch_seccomp_data& data, void* aux) { 333 static intptr_t DummyTrap(const struct arch_seccomp_data& data, void* aux) {
409 return 0; 334 return 0;
410 } 335 }
411 336
412 TEST(BPFDSL, IsAllowDeny) { 337 TEST(BPFDSL, IsAllowDeny) {
413 ResultExpr allow = Allow(); 338 ResultExpr allow = Allow();
414 EXPECT_TRUE(allow->IsAllow()); 339 EXPECT_TRUE(allow->IsAllow());
415 EXPECT_FALSE(allow->IsDeny()); 340 EXPECT_FALSE(allow->IsDeny());
(...skipping 27 matching lines...) Expand all
443 EXPECT_TRUE(unsafe->HasUnsafeTraps()); 368 EXPECT_TRUE(unsafe->HasUnsafeTraps());
444 369
445 const Arg<int> arg(0); 370 const Arg<int> arg(0);
446 ResultExpr maybe = If(arg == 0, allow).Else(unsafe); 371 ResultExpr maybe = If(arg == 0, allow).Else(unsafe);
447 EXPECT_TRUE(maybe->HasUnsafeTraps()); 372 EXPECT_TRUE(maybe->HasUnsafeTraps());
448 } 373 }
449 374
450 } // namespace 375 } // namespace
451 } // namespace bpf_dsl 376 } // namespace bpf_dsl
452 } // namespace sandbox 377 } // namespace sandbox
OLDNEW
« no previous file with comments | « no previous file | sandbox/linux/bpf_dsl/seccomp_macros.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698