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

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: Cleanup CHECK statements a little bit Created 6 years, 6 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 namespace sandbox {
20
21 namespace {
22
23 class BasicPolicy : public SandboxBPFDSLPolicy {
24 public:
25 BasicPolicy() {}
26 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE {
27 if (sysno == __NR_getpgid) {
28 const Arg<pid_t> pid(0);
29 return If(pid == 0).Then(
30 Error(EPERM)
31 ).Else(
32 Error(EINVAL)
33 );
34 }
35 return Allow();
36 }
37
38 private:
39 DISALLOW_COPY_AND_ASSIGN(BasicPolicy);
40 };
41
42 BPF_TEST_C(BPFDSL, Basic, BasicPolicy) {
43 BPF_ASSERT_EQ(-1, getpgid(0));
44 BPF_ASSERT_EQ(EPERM, errno);
45
46 BPF_ASSERT_EQ(-1, getpgid(1));
47 BPF_ASSERT_EQ(EINVAL, errno);
48 }
49
50 class BooleanLogicPolicy : public SandboxBPFDSLPolicy {
51 public:
52 BooleanLogicPolicy() {}
53 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE {
54 if (sysno == __NR_socketpair) {
55 const Arg<int> domain(0), type(1), protocol(2);
56 return If(domain == AF_UNIX &&
57 (type == SOCK_STREAM || type == SOCK_DGRAM) &&
58 protocol == 0).Then(
59 Error(EPERM)
60 ).Else(
61 Error(EINVAL)
62 );
63 }
64 return Allow();
65 }
66
67 private:
68 DISALLOW_COPY_AND_ASSIGN(BooleanLogicPolicy);
69 };
70
71 void AssertSocketPairError(int expected_errno,
72 int domain,
73 int type,
74 int protocol) {
75 int sv[2];
76 BPF_ASSERT_EQ(-1, socketpair(domain, type, protocol, sv));
77 BPF_ASSERT_EQ(expected_errno, errno);
78 }
79
80 BPF_TEST_C(BPFDSL, BooleanLogic, BooleanLogicPolicy) {
81 // Acceptable combinations that should return EPERM.
82 AssertSocketPairError(EPERM, AF_UNIX, SOCK_STREAM, 0);
83 AssertSocketPairError(EPERM, AF_UNIX, SOCK_DGRAM, 0);
84
85 // Combinations that are invalid for only one reason; should return EINVAL.
86 AssertSocketPairError(EINVAL, AF_INET, SOCK_STREAM, 0);
87 AssertSocketPairError(EINVAL, AF_UNIX, SOCK_SEQPACKET, 0);
88 AssertSocketPairError(EINVAL, AF_UNIX, SOCK_STREAM, IPPROTO_TCP);
89
90 // Completely unacceptable combination; should also return EINVAL.
91 AssertSocketPairError(EINVAL, AF_INET, SOCK_SEQPACKET, IPPROTO_UDP);
92 }
93
94 static const uintptr_t kDeadBeefAddr =
95 static_cast<uintptr_t>(0xdeadbeefdeadbeefULL);
96
97 class ArgSizePolicy : public SandboxBPFDSLPolicy {
98 public:
99 ArgSizePolicy() {}
100 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE {
101 if (sysno == __NR_uname) {
102 const Arg<uintptr_t> addr(0);
103 return If(addr == kDeadBeefAddr).Then(
104 Error(EPERM)
105 ).Else(
106 Allow()
107 );
108 }
109 return Allow();
110 }
111
112 private:
113 DISALLOW_COPY_AND_ASSIGN(ArgSizePolicy);
114 };
115
116 BPF_TEST_C(BPFDSL, ArgSizeTest, ArgSizePolicy) {
117 struct utsname buf;
118 BPF_ASSERT_EQ(0, uname(&buf));
119
120 BPF_ASSERT_EQ(-1, uname(reinterpret_cast<struct utsname*>(kDeadBeefAddr)));
121 BPF_ASSERT_EQ(EPERM, errno);
122 }
123
124 class TrappingPolicy : public SandboxBPFDSLPolicy {
125 public:
126 TrappingPolicy() {}
127 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE {
128 if (sysno == __NR_uname) {
129 return Trap(UnameTrap, &count_);
130 }
131 return Allow();
132 }
133
134 private:
135 static intptr_t count_;
136
137 static intptr_t UnameTrap(const struct arch_seccomp_data& data, void* aux) {
138 BPF_ASSERT_EQ(&count_, aux);
139 return ++count_;
140 }
141
142 DISALLOW_COPY_AND_ASSIGN(TrappingPolicy);
143 };
144
145 intptr_t TrappingPolicy::count_;
146
147 BPF_TEST_C(BPFDSL, TrapTest, TrappingPolicy) {
148 BPF_ASSERT_EQ(1, uname(NULL));
149 BPF_ASSERT_EQ(2, uname(NULL));
150 BPF_ASSERT_EQ(3, uname(NULL));
151 }
152
153 class MaskingPolicy : public SandboxBPFDSLPolicy {
154 public:
155 MaskingPolicy() {}
156 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE {
157 if (sysno == __NR_setuid) {
158 const Arg<uid_t> uid(0);
159 return If((uid & 0xf) == 0).Then(
160 Error(EINVAL)
161 ).Else(
162 Error(EACCES)
163 );
164 }
165 if (sysno == __NR_setgid) {
166 const Arg<gid_t> gid(0);
167 return If((gid & 0xf0) == 0xf0).Then(
168 Error(EINVAL)
169 ).Else(
170 Error(EACCES)
171 );
172 }
173 return Allow();
174 }
175
176 private:
177 DISALLOW_COPY_AND_ASSIGN(MaskingPolicy);
178 };
179
180 BPF_TEST_C(BPFDSL, MaskTest, MaskingPolicy) {
181 for (uid_t uid = 0; uid < 0x100; ++uid) {
182 BPF_ASSERT_EQ(-1, setuid(uid));
183 BPF_ASSERT_EQ((uid & 0xf) == 0 ? EINVAL : EACCES, errno);
184 }
185
186 for (gid_t gid = 0; gid < 0x100; ++gid) {
187 BPF_ASSERT_EQ(-1, setgid(gid));
188 BPF_ASSERT_EQ((gid & 0xf0) == 0xf0 ? EINVAL : EACCES, errno);
189 }
190 }
191
192 class ElseIfPolicy : public SandboxBPFDSLPolicy {
193 public:
194 ElseIfPolicy() {}
195 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE {
196 if (sysno == __NR_setuid) {
197 const Arg<uid_t> uid(0);
198 return If(uid == 0).Then(
199 Error(0)
200 ).ElseIf((uid & 0xf0f0) == 0).Then(
201 Error(EINVAL)
202 ).ElseIf((uid & 0x00ff) == 0).Then(
203 Error(EEXIST)
204 ).Else(
205 Error(EACCES)
206 );
207 }
208 return Allow();
209 }
210
211 private:
212 DISALLOW_COPY_AND_ASSIGN(ElseIfPolicy);
213 };
214
215 BPF_TEST_C(BPFDSL, ElseIfTest, ElseIfPolicy) {
216 BPF_ASSERT_EQ(0, setuid(0));
217
218 BPF_ASSERT_EQ(-1, setuid(0x0001));
219 BPF_ASSERT_EQ(EINVAL, errno);
220 BPF_ASSERT_EQ(-1, setuid(0x0100));
221 BPF_ASSERT_EQ(EINVAL, errno);
222
223 BPF_ASSERT_EQ(-1, setuid(0x1000));
224 BPF_ASSERT_EQ(EEXIST, errno);
225 BPF_ASSERT_EQ(-1, setuid(0x2000));
226 BPF_ASSERT_EQ(EEXIST, errno);
227
228 BPF_ASSERT_EQ(-1, setuid(0x1234));
229 BPF_ASSERT_EQ(EACCES, errno);
230 }
231
232 } // namespace
233
234 } // namespace sandbox
OLDNEW
« sandbox/linux/seccomp-bpf-helpers/bpf_dsl.cc ('K') | « sandbox/linux/seccomp-bpf-helpers/bpf_dsl.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698