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

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

Issue 10833044: Refactored ErrorCode into it's own class (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added unittest (and new framework to make this possible) Created 8 years, 4 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <ostream> 5 #include <ostream>
6 6
7 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" 7 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
8 #include "sandbox/linux/seccomp-bpf/verifier.h" 8 #include "sandbox/linux/seccomp-bpf/verifier.h"
9 #include "testing/gtest/include/gtest/gtest.h" 9 #include "testing/gtest/include/gtest/gtest.h"
10 10
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 Sandbox::STATUS_AVAILABLE) { 71 Sandbox::STATUS_AVAILABLE) {
72 ExitGroup(1); 72 ExitGroup(1);
73 } 73 }
74 Sandbox::setProcFd(proc_fd); 74 Sandbox::setProcFd(proc_fd);
75 Sandbox::setSandboxPolicy(evaluator, NULL); 75 Sandbox::setSandboxPolicy(evaluator, NULL);
76 Sandbox::startSandbox(); 76 Sandbox::startSandbox();
77 } 77 }
78 78
79 void RunInSandbox(Sandbox::EvaluateSyscall evaluator, 79 void RunInSandbox(Sandbox::EvaluateSyscall evaluator,
80 void (*SandboxedCode)()) { 80 void (*SandboxedCode)()) {
81 // TODO(markus): Implement IsEqual for ErrorCode 81 // TODO(jln): Implement IsEqual for ErrorCode
82 // IsEqual(evaluator(__NR_exit_group), Sandbox::SB_ALLOWED) << 82 // IsEqual(evaluator(__NR_exit_group), ErrorCode::ERR_ALLOWED) <<
83 // "You need to always allow exit_group() in your test policy"; 83 // "You need to always allow exit_group() in your test policy";
84 StartSandboxOrDie(evaluator); 84 StartSandboxOrDie(evaluator);
85 // TODO(jln): find a way to use the testing framework inside 85 // TODO(jln): find a way to use the testing framework inside
86 // SandboxedCode() or at the very least to surface errors 86 // SandboxedCode() or at the very least to surface errors
87 SandboxedCode(); 87 SandboxedCode();
88 // SandboxedCode() should have exited, this is a failure 88 // SandboxedCode() should have exited, this is a failure
89 ExitGroup(1); 89 ExitGroup(1);
90 } 90 }
91 91
92 // evaluator should always allow ExitGroup 92 // evaluator should always allow ExitGroup
(...skipping 10 matching lines...) Expand all
103 } else { 103 } else {
104 // The sandbox is not available. We should still try to exercise what we 104 // The sandbox is not available. We should still try to exercise what we
105 // can. 105 // can.
106 // TODO(markus): (crbug.com/141545) let us call the compiler from here. 106 // TODO(markus): (crbug.com/141545) let us call the compiler from here.
107 Sandbox::setSandboxPolicy(evaluator, NULL); 107 Sandbox::setSandboxPolicy(evaluator, NULL);
108 } 108 }
109 } 109 }
110 110
111 // A simple blacklist test 111 // A simple blacklist test
112 112
113 Sandbox::ErrorCode BlacklistNanosleepPolicy(int sysno) { 113 ErrorCode BlacklistNanosleepPolicy(int sysno) {
114 if (sysno < static_cast<int>(MIN_SYSCALL) || 114 if (sysno < static_cast<int>(MIN_SYSCALL) ||
115 sysno > static_cast<int>(MAX_SYSCALL)) { 115 sysno > static_cast<int>(MAX_SYSCALL)) {
116 // FIXME: we should really not have to do that in a trivial policy 116 // FIXME: we should really not have to do that in a trivial policy
117 return ENOSYS; 117 return ErrorCode(ENOSYS);
118 } 118 }
119 switch (sysno) { 119 switch (sysno) {
120 case __NR_nanosleep: 120 case __NR_nanosleep:
121 return EACCES; 121 return ErrorCode(EACCES);
122 default: 122 default:
123 return Sandbox::SB_ALLOWED; 123 return ErrorCode(ErrorCode::ERR_ALLOWED);
124 } 124 }
125 } 125 }
126 126
127 void NanosleepProcess(void) { 127 void NanosleepProcess(void) {
128 const struct timespec ts = {0, 0}; 128 const struct timespec ts = {0, 0};
129 errno = 0; 129 errno = 0;
130 if(syscall(__NR_nanosleep, &ts, NULL) != -1 || errno != EACCES) { 130 if(syscall(__NR_nanosleep, &ts, NULL) != -1 || errno != EACCES) {
131 ExitGroup(1); 131 ExitGroup(1);
132 } 132 }
133 ExitGroup(kExpectedReturnValue); 133 ExitGroup(kExpectedReturnValue);
134 } 134 }
135 135
136 TEST(SandboxBpf, ApplyBasicBlacklistPolicy) { 136 TEST(SandboxBpf, ApplyBasicBlacklistPolicy) {
137 TryPolicyInProcess(BlacklistNanosleepPolicy, NanosleepProcess); 137 TryPolicyInProcess(BlacklistNanosleepPolicy, NanosleepProcess);
138 } 138 }
139 139
140 // Now do a simple whitelist test 140 // Now do a simple whitelist test
141 141
142 Sandbox::ErrorCode WhitelistGetpidPolicy(int sysno) { 142 ErrorCode WhitelistGetpidPolicy(int sysno) {
143 switch (sysno) { 143 switch (sysno) {
144 case __NR_getpid: 144 case __NR_getpid:
145 case __NR_exit_group: 145 case __NR_exit_group:
146 return Sandbox::SB_ALLOWED; 146 return ErrorCode(ErrorCode::ERR_ALLOWED);
147 default: 147 default:
148 return ENOMEM; 148 return ErrorCode(ENOMEM);
149 } 149 }
150 } 150 }
151 151
152 void GetpidProcess(void) { 152 void GetpidProcess(void) {
153 errno = 0; 153 errno = 0;
154 // getpid() should be allowed 154 // getpid() should be allowed
155 if (syscall(__NR_getpid) < 0 || errno) 155 if (syscall(__NR_getpid) < 0 || errno)
156 ExitGroup(1); 156 ExitGroup(1);
157 // getpgid() should be denied 157 // getpgid() should be denied
158 if (getpgid(0) != -1 || errno != ENOMEM) 158 if (getpgid(0) != -1 || errno != ENOMEM)
(...skipping 13 matching lines...) Expand all
172 static int BlacklistNanosleepPolicySigsysAuxData; 172 static int BlacklistNanosleepPolicySigsysAuxData;
173 173
174 intptr_t EnomemHandler(const struct arch_seccomp_data& args, void *aux) { 174 intptr_t EnomemHandler(const struct arch_seccomp_data& args, void *aux) {
175 // We also check that the auxiliary data is correct 175 // We also check that the auxiliary data is correct
176 if (!aux) 176 if (!aux)
177 ExitGroup(1); 177 ExitGroup(1);
178 *(static_cast<int*>(aux)) = kExpectedReturnValue; 178 *(static_cast<int*>(aux)) = kExpectedReturnValue;
179 return -ENOMEM; 179 return -ENOMEM;
180 } 180 }
181 181
182 Sandbox::ErrorCode BlacklistNanosleepPolicySigsys(int sysno) { 182 ErrorCode BlacklistNanosleepPolicySigsys(int sysno) {
183 if (sysno < static_cast<int>(MIN_SYSCALL) || 183 if (sysno < static_cast<int>(MIN_SYSCALL) ||
184 sysno > static_cast<int>(MAX_SYSCALL)) { 184 sysno > static_cast<int>(MAX_SYSCALL)) {
185 // FIXME: we should really not have to do that in a trivial policy 185 // FIXME: we should really not have to do that in a trivial policy
186 return ENOSYS; 186 return ErrorCode(ENOSYS);
187 } 187 }
188 switch (sysno) { 188 switch (sysno) {
189 case __NR_nanosleep: 189 case __NR_nanosleep:
190 return Sandbox::ErrorCode(EnomemHandler, 190 return Sandbox::Trap(EnomemHandler,
191 static_cast<void *>(&BlacklistNanosleepPolicySigsysAuxData)); 191 static_cast<void *>(&BlacklistNanosleepPolicySigsysAuxData));
192 default: 192 default:
193 return Sandbox::SB_ALLOWED; 193 return ErrorCode(ErrorCode::ERR_ALLOWED);
194 } 194 }
195 } 195 }
196 196
197 void NanosleepProcessSigsys(void) { 197 void NanosleepProcessSigsys(void) {
198 const struct timespec ts = {0, 0}; 198 const struct timespec ts = {0, 0};
199 errno = 0; 199 errno = 0;
200 // getpid() should work properly 200 // getpid() should work properly
201 if (syscall(__NR_getpid) < 0) 201 if (syscall(__NR_getpid) < 0)
202 ExitGroup(1); 202 ExitGroup(1);
203 // Our Auxiliary Data, should be reset by the signal handler 203 // Our Auxiliary Data, should be reset by the signal handler
(...skipping 20 matching lines...) Expand all
224 // We try to make sure we exercise optimizations in the BPF compiler. We make 224 // We try to make sure we exercise optimizations in the BPF compiler. We make
225 // sure that the compiler can have an opportunity to coalesce syscalls with 225 // sure that the compiler can have an opportunity to coalesce syscalls with
226 // contiguous numbers and we also make sure that disjoint sets can return the 226 // contiguous numbers and we also make sure that disjoint sets can return the
227 // same errno. 227 // same errno.
228 int SysnoToRandomErrno(int sysno) { 228 int SysnoToRandomErrno(int sysno) {
229 // Small contiguous sets of 3 system calls return an errno equal to the 229 // Small contiguous sets of 3 system calls return an errno equal to the
230 // index of that set + 1 (so that we never return a NUL errno). 230 // index of that set + 1 (so that we never return a NUL errno).
231 return ((sysno & ~3) >> 2) % 29 + 1; 231 return ((sysno & ~3) >> 2) % 29 + 1;
232 } 232 }
233 233
234 Sandbox::ErrorCode SyntheticPolicy(int sysno) { 234 ErrorCode SyntheticPolicy(int sysno) {
235 if (sysno < static_cast<int>(MIN_SYSCALL) || 235 if (sysno < static_cast<int>(MIN_SYSCALL) ||
236 sysno > static_cast<int>(MAX_SYSCALL)) { 236 sysno > static_cast<int>(MAX_SYSCALL)) {
237 // FIXME: we should really not have to do that in a trivial policy. 237 // FIXME: we should really not have to do that in a trivial policy.
238 return ENOSYS; 238 return ErrorCode(ENOSYS);
239 } 239 }
240 240
241 // TODO(jorgelo): remove this restriction once crbug.com/141694 is fixed. 241 // TODO(jorgelo): remove this restriction once crbug.com/141694 is fixed.
242 #if defined(__arm__) 242 #if defined(__arm__)
243 if (sysno > kArmPublicSysnoCeiling) 243 if (sysno > kArmPublicSysnoCeiling)
244 return ENOSYS; 244 return ENOSYS;
245 #endif 245 #endif
246 246
247 if (sysno == __NR_exit_group) { 247 if (sysno == __NR_exit_group) {
248 // exit_group() is special, we really need it to work. 248 // exit_group() is special, we really need it to work.
249 return Sandbox::SB_ALLOWED; 249 return ErrorCode(ErrorCode::ERR_ALLOWED);
250 } else { 250 } else {
251 return SysnoToRandomErrno(sysno); 251 return ErrorCode(SysnoToRandomErrno(sysno));
252 } 252 }
253 } 253 }
254 254
255 void SyntheticProcess(void) { 255 void SyntheticProcess(void) {
256 // Ensure that that kExpectedReturnValue + syscallnumber + 1 does not int 256 // Ensure that that kExpectedReturnValue + syscallnumber + 1 does not int
257 // overflow. 257 // overflow.
258 if (std::numeric_limits<int>::max() - kExpectedReturnValue - 1 < 258 if (std::numeric_limits<int>::max() - kExpectedReturnValue - 1 <
259 static_cast<int>(MAX_SYSCALL)) { 259 static_cast<int>(MAX_SYSCALL)) {
260 ExitGroup(1); 260 ExitGroup(1);
261 } 261 }
(...skipping 22 matching lines...) Expand all
284 } 284 }
285 } 285 }
286 ExitGroup(kExpectedReturnValue); 286 ExitGroup(kExpectedReturnValue);
287 } 287 }
288 288
289 TEST(SandboxBpf, SyntheticPolicy) { 289 TEST(SandboxBpf, SyntheticPolicy) {
290 TryPolicyInProcess(SyntheticPolicy, SyntheticProcess); 290 TryPolicyInProcess(SyntheticPolicy, SyntheticProcess);
291 } 291 }
292 292
293 } // namespace 293 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698