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

Side by Side Diff: sandbox/linux/seccomp-bpf-helpers/bpf_dsl_unittest.cc

Issue 299743002: Add domain-specific language for BPF policies (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add explicit virtual destructors to test policies Created 6 years, 5 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 | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "sandbox/linux/seccomp-bpf-helpers/bpf_dsl.h"
6
7 #include <errno.h>
8 #include <netinet/in.h>
9 #include <sys/socket.h>
10 #include <sys/utsname.h>
11
12 #include "base/macros.h"
13 #include "sandbox/linux/seccomp-bpf/bpf_tests.h"
14 #include "sandbox/linux/seccomp-bpf/errorcode.h"
15 #include "sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h"
16
17 using namespace sandbox::bpf_dsl;
18
19 // Helper macro to assert that expression |expr| returns -1 and sets
20 // errno to |err|.
21 #define BPF_ASSERT_ERROR(err, expr) \
22 do { \
23 errno = 0; \
24 BPF_ASSERT_EQ(-1, expr); \
25 BPF_ASSERT_EQ(err, errno); \
26 } while (0)
27
28 namespace sandbox {
29
30 namespace {
31
32 class BasicPolicy : public SandboxBPFDSLPolicy {
33 public:
34 BasicPolicy() {}
35 virtual ~BasicPolicy() {}
36 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE {
37 if (sysno == __NR_getpgid) {
38 const Arg<pid_t> pid(0);
39 return If(pid == 0, Error(EPERM)).Else(Error(EINVAL));
40 }
41 return Allow();
42 }
43
44 private:
45 DISALLOW_COPY_AND_ASSIGN(BasicPolicy);
46 };
47
48 BPF_TEST_C(BPFDSL, Basic, BasicPolicy) {
49 BPF_ASSERT_ERROR(EPERM, getpgid(0));
50 BPF_ASSERT_ERROR(EINVAL, getpgid(1));
51 }
52
53 class BooleanLogicPolicy : public SandboxBPFDSLPolicy {
54 public:
55 BooleanLogicPolicy() {}
56 virtual ~BooleanLogicPolicy() {}
57 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE {
58 if (sysno == __NR_socketpair) {
jln (very slow on Chromium) 2014/06/27 01:45:50 x86 32 bits is unhappy with this since it's multip
mdempsky 2014/06/28 00:36:42 Ah, right.
59 const Arg<int> domain(0), type(1), protocol(2);
60 return If(domain == AF_UNIX &&
61 (type == SOCK_STREAM || type == SOCK_DGRAM) &&
62 protocol == 0,
63 Error(EPERM)).Else(Error(EINVAL));
64 }
65 return Allow();
66 }
67
68 private:
69 DISALLOW_COPY_AND_ASSIGN(BooleanLogicPolicy);
70 };
71
72 BPF_TEST_C(BPFDSL, BooleanLogic, BooleanLogicPolicy) {
73 int sv[2];
74
75 // Acceptable combinations that should return EPERM.
76 BPF_ASSERT_ERROR(EPERM, socketpair(AF_UNIX, SOCK_STREAM, 0, sv));
77 BPF_ASSERT_ERROR(EPERM, socketpair(AF_UNIX, SOCK_DGRAM, 0, sv));
78
79 // Combinations that are invalid for only one reason; should return EINVAL.
80 BPF_ASSERT_ERROR(EINVAL, socketpair(AF_INET, SOCK_STREAM, 0, sv));
81 BPF_ASSERT_ERROR(EINVAL, socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sv));
82 BPF_ASSERT_ERROR(EINVAL, socketpair(AF_UNIX, SOCK_STREAM, IPPROTO_TCP, sv));
83
84 // Completely unacceptable combination; should also return EINVAL.
85 BPF_ASSERT_ERROR(EINVAL,
86 socketpair(AF_INET, SOCK_SEQPACKET, IPPROTO_UDP, sv));
87 }
88
89 static const uintptr_t kDeadBeefAddr =
90 static_cast<uintptr_t>(0xdeadbeefdeadbeefULL);
91
92 class ArgSizePolicy : public SandboxBPFDSLPolicy {
93 public:
94 ArgSizePolicy() {}
95 virtual ~ArgSizePolicy() {}
96 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE {
97 if (sysno == __NR_uname) {
98 const Arg<uintptr_t> addr(0);
99 return If(addr == kDeadBeefAddr, Error(EPERM)).Else(Allow());
100 }
101 return Allow();
102 }
103
104 private:
105 DISALLOW_COPY_AND_ASSIGN(ArgSizePolicy);
106 };
107
108 BPF_TEST_C(BPFDSL, ArgSizeTest, ArgSizePolicy) {
109 struct utsname buf;
110 BPF_ASSERT_EQ(0, uname(&buf));
111
112 BPF_ASSERT_ERROR(EPERM,
113 uname(reinterpret_cast<struct utsname*>(kDeadBeefAddr)));
114 }
115
116 class TrappingPolicy : public SandboxBPFDSLPolicy {
117 public:
118 TrappingPolicy() {}
119 virtual ~TrappingPolicy() {}
120 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE {
121 if (sysno == __NR_uname) {
122 return Trap(UnameTrap, &count_);
123 }
124 return Allow();
125 }
126
127 private:
128 static intptr_t count_;
129
130 static intptr_t UnameTrap(const struct arch_seccomp_data& data, void* aux) {
131 BPF_ASSERT_EQ(&count_, aux);
132 return ++count_;
133 }
134
135 DISALLOW_COPY_AND_ASSIGN(TrappingPolicy);
136 };
137
138 intptr_t TrappingPolicy::count_;
139
140 BPF_TEST_C(BPFDSL, TrapTest, TrappingPolicy) {
141 BPF_ASSERT_EQ(1, uname(NULL));
142 BPF_ASSERT_EQ(2, uname(NULL));
143 BPF_ASSERT_EQ(3, uname(NULL));
144 }
145
146 class MaskingPolicy : public SandboxBPFDSLPolicy {
147 public:
148 MaskingPolicy() {}
149 virtual ~MaskingPolicy() {}
150 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE {
151 if (sysno == __NR_setuid) {
152 const Arg<uid_t> uid(0);
153 return If((uid & 0xf) == 0, Error(EINVAL)).Else(Error(EACCES));
154 }
155 if (sysno == __NR_setgid) {
156 const Arg<gid_t> gid(0);
157 return If((gid & 0xf0) == 0xf0, Error(EINVAL)).Else(Error(EACCES));
158 }
159 return Allow();
160 }
161
162 private:
163 DISALLOW_COPY_AND_ASSIGN(MaskingPolicy);
164 };
165
166 BPF_TEST_C(BPFDSL, MaskTest, MaskingPolicy) {
167 for (uid_t uid = 0; uid < 0x100; ++uid) {
168 const int expect_errno = (uid & 0xf) == 0 ? EINVAL : EACCES;
169 BPF_ASSERT_ERROR(expect_errno, setuid(uid));
170 }
171
172 for (gid_t gid = 0; gid < 0x100; ++gid) {
173 const int expect_errno = (gid & 0xf0) == 0xf0 ? EINVAL : EACCES;
174 BPF_ASSERT_ERROR(expect_errno, setgid(gid));
175 }
176 }
177
178 class ElseIfPolicy : public SandboxBPFDSLPolicy {
179 public:
180 ElseIfPolicy() {}
181 virtual ~ElseIfPolicy() {}
182 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE {
183 if (sysno == __NR_setuid) {
184 const Arg<uid_t> uid(0);
185 return If((uid & 0xfff) == 0, Error(0))
186 .ElseIf((uid & 0xff0) == 0, Error(EINVAL))
187 .ElseIf((uid & 0xf00) == 0, Error(EEXIST))
188 .Else(Error(EACCES));
189 }
190 return Allow();
191 }
192
193 private:
194 DISALLOW_COPY_AND_ASSIGN(ElseIfPolicy);
195 };
196
197 BPF_TEST_C(BPFDSL, ElseIfTest, ElseIfPolicy) {
198 BPF_ASSERT_EQ(0, setuid(0));
199
200 BPF_ASSERT_ERROR(EINVAL, setuid(0x0001));
201 BPF_ASSERT_ERROR(EINVAL, setuid(0x0002));
202
203 BPF_ASSERT_ERROR(EEXIST, setuid(0x0011));
204 BPF_ASSERT_ERROR(EEXIST, setuid(0x0022));
205
206 BPF_ASSERT_ERROR(EACCES, setuid(0x0111));
207 BPF_ASSERT_ERROR(EACCES, setuid(0x0222));
208 }
209
210 } // namespace
211
212 } // namespace sandbox
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698