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

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: Rebased, and removed "protected" as requested by jln 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 "sandbox/linux/seccomp-bpf/sandbox_bpf.h" 5 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
6 #include "sandbox/linux/seccomp-bpf/verifier.h" 6 #include "sandbox/linux/seccomp-bpf/verifier.h"
7 #include "testing/gtest/include/gtest/gtest.h" 7 #include "testing/gtest/include/gtest/gtest.h"
8 8
9 using namespace playground2; 9 using namespace playground2;
10 10
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 ExitGroup(1); 59 ExitGroup(1);
60 } 60 }
61 Sandbox::setProcFd(proc_fd); 61 Sandbox::setProcFd(proc_fd);
62 Sandbox::setSandboxPolicy(evaluator, NULL); 62 Sandbox::setSandboxPolicy(evaluator, NULL);
63 Sandbox::startSandbox(); 63 Sandbox::startSandbox();
64 } 64 }
65 65
66 void RunInSandbox(Sandbox::EvaluateSyscall evaluator, 66 void RunInSandbox(Sandbox::EvaluateSyscall evaluator,
67 void (*SandboxedCode)()) { 67 void (*SandboxedCode)()) {
68 // TODO(jln): Implement IsEqual for ErrorCode 68 // TODO(jln): Implement IsEqual for ErrorCode
69 // IsEqual(evaluator(__NR_exit_group), Sandbox::SB_ALLOWED) << 69 // IsEqual(evaluator(__NR_exit_group), ErrorCode::ERR_ALLOWED) <<
70 // "You need to always allow exit_group() in your test policy"; 70 // "You need to always allow exit_group() in your test policy";
71 StartSandboxOrDie(evaluator); 71 StartSandboxOrDie(evaluator);
72 // TODO(jln): find a way to use the testing framework inside 72 // TODO(jln): find a way to use the testing framework inside
73 // SandboxedCode() or at the very least to surface errors 73 // SandboxedCode() or at the very least to surface errors
74 SandboxedCode(); 74 SandboxedCode();
75 // SandboxedCode() should have exited, this is a failure 75 // SandboxedCode() should have exited, this is a failure
76 ExitGroup(1); 76 ExitGroup(1);
77 } 77 }
78 78
79 // evaluator should always allow ExitGroup 79 // evaluator should always allow ExitGroup
80 // SandboxedCode should ExitGroup(kExpectedReturnValue) if and only if 80 // SandboxedCode should ExitGroup(kExpectedReturnValue) if and only if
81 // things go as expected. 81 // things go as expected.
82 void TryPolicyInProcess(Sandbox::EvaluateSyscall evaluator, 82 void TryPolicyInProcess(Sandbox::EvaluateSyscall evaluator,
83 void (*SandboxedCode)()) { 83 void (*SandboxedCode)()) {
84 // TODO(jln) figure out a way to surface whether we're actually testing 84 // TODO(jln) figure out a way to surface whether we're actually testing
85 // something or not. 85 // something or not.
86 if (Sandbox::supportsSeccompSandbox(-1) == Sandbox::STATUS_AVAILABLE) { 86 if (Sandbox::supportsSeccompSandbox(-1) == Sandbox::STATUS_AVAILABLE) {
87 EXPECT_EXIT(RunInSandbox(evaluator, SandboxedCode), 87 EXPECT_EXIT(RunInSandbox(evaluator, SandboxedCode),
88 ::testing::ExitedWithCode(kExpectedReturnValue), 88 ::testing::ExitedWithCode(kExpectedReturnValue),
89 ""); 89 "");
90 } 90 }
91 } 91 }
92 92
93 // A simple blacklist test 93 // A simple blacklist test
94 94
95 Sandbox::ErrorCode BlacklistNanosleepPolicy(int sysno) { 95 ErrorCode BlacklistNanosleepPolicy(int sysno) {
96 if (sysno < static_cast<int>(MIN_SYSCALL) || 96 if (sysno < static_cast<int>(MIN_SYSCALL) ||
97 sysno > static_cast<int>(MAX_SYSCALL)) { 97 sysno > static_cast<int>(MAX_SYSCALL)) {
98 // FIXME: we should really not have to do that in a trivial policy 98 // FIXME: we should really not have to do that in a trivial policy
99 return ENOSYS; 99 return ENOSYS;
100 } 100 }
101 switch (sysno) { 101 switch (sysno) {
102 case __NR_nanosleep: 102 case __NR_nanosleep:
103 return EACCES; 103 return EACCES;
104 default: 104 default:
105 return Sandbox::SB_ALLOWED; 105 return ErrorCode::ERR_ALLOWED;
106 } 106 }
107 } 107 }
108 108
109 void NanosleepProcess(void) { 109 void NanosleepProcess(void) {
110 const struct timespec ts = {0, 0}; 110 const struct timespec ts = {0, 0};
111 errno = 0; 111 errno = 0;
112 if(syscall(__NR_nanosleep, &ts, NULL) != -1 || errno != EACCES) { 112 if(syscall(__NR_nanosleep, &ts, NULL) != -1 || errno != EACCES) {
113 ExitGroup(1); 113 ExitGroup(1);
114 } 114 }
115 ExitGroup(kExpectedReturnValue); 115 ExitGroup(kExpectedReturnValue);
116 } 116 }
117 117
118 TEST(SandboxBpf, ApplyBasicBlacklistPolicy) { 118 TEST(SandboxBpf, ApplyBasicBlacklistPolicy) {
119 TryPolicyInProcess(BlacklistNanosleepPolicy, NanosleepProcess); 119 TryPolicyInProcess(BlacklistNanosleepPolicy, NanosleepProcess);
120 } 120 }
121 121
122 // Now do a simple whitelist test 122 // Now do a simple whitelist test
123 123
124 Sandbox::ErrorCode WhitelistGetpidPolicy(int sysno) { 124 ErrorCode WhitelistGetpidPolicy(int sysno) {
125 switch (sysno) { 125 switch (sysno) {
126 case __NR_getpid: 126 case __NR_getpid:
127 case __NR_exit_group: 127 case __NR_exit_group:
128 return Sandbox::SB_ALLOWED; 128 return ErrorCode::ERR_ALLOWED;
129 default: 129 default:
130 return ENOMEM; 130 return ENOMEM;
131 } 131 }
132 } 132 }
133 133
134 void GetpidProcess(void) { 134 void GetpidProcess(void) {
135 errno = 0; 135 errno = 0;
136 // getpid() should be allowed 136 // getpid() should be allowed
137 if (syscall(__NR_getpid) < 0 || errno) 137 if (syscall(__NR_getpid) < 0 || errno)
138 ExitGroup(1); 138 ExitGroup(1);
(...skipping 15 matching lines...) Expand all
154 static int BlacklistNanosleepPolicySigsysAuxData; 154 static int BlacklistNanosleepPolicySigsysAuxData;
155 155
156 intptr_t EnomemHandler(const struct arch_seccomp_data& args, void *aux) { 156 intptr_t EnomemHandler(const struct arch_seccomp_data& args, void *aux) {
157 // We also check that the auxiliary data is correct 157 // We also check that the auxiliary data is correct
158 if (!aux) 158 if (!aux)
159 ExitGroup(1); 159 ExitGroup(1);
160 *(static_cast<int*>(aux)) = kExpectedReturnValue; 160 *(static_cast<int*>(aux)) = kExpectedReturnValue;
161 return -ENOMEM; 161 return -ENOMEM;
162 } 162 }
163 163
164 Sandbox::ErrorCode BlacklistNanosleepPolicySigsys(int sysno) { 164 ErrorCode BlacklistNanosleepPolicySigsys(int sysno) {
165 if (sysno < static_cast<int>(MIN_SYSCALL) || 165 if (sysno < static_cast<int>(MIN_SYSCALL) ||
166 sysno > static_cast<int>(MAX_SYSCALL)) { 166 sysno > static_cast<int>(MAX_SYSCALL)) {
167 // FIXME: we should really not have to do that in a trivial policy 167 // FIXME: we should really not have to do that in a trivial policy
168 return ENOSYS; 168 return ENOSYS;
169 } 169 }
170 switch (sysno) { 170 switch (sysno) {
171 case __NR_nanosleep: 171 case __NR_nanosleep:
172 return Sandbox::ErrorCode(EnomemHandler, 172 return Sandbox::Trap(EnomemHandler,
173 static_cast<void *>(&BlacklistNanosleepPolicySigsysAuxData)); 173 static_cast<void *>(&BlacklistNanosleepPolicySigsysAuxData));
174 default: 174 default:
175 return Sandbox::SB_ALLOWED; 175 return ErrorCode::ERR_ALLOWED;
176 } 176 }
177 } 177 }
178 178
179 void NanosleepProcessSigsys(void) { 179 void NanosleepProcessSigsys(void) {
180 const struct timespec ts = {0, 0}; 180 const struct timespec ts = {0, 0};
181 errno = 0; 181 errno = 0;
182 // getpid() should work properly 182 // getpid() should work properly
183 if (syscall(__NR_getpid) < 0) 183 if (syscall(__NR_getpid) < 0)
184 ExitGroup(1); 184 ExitGroup(1);
185 // Our Auxiliary Data, should be reset by the signal handler 185 // Our Auxiliary Data, should be reset by the signal handler
(...skipping 20 matching lines...) Expand all
206 // We try to make sure we exercise optimizations in the BPF compiler. We make 206 // We try to make sure we exercise optimizations in the BPF compiler. We make
207 // sure that the compiler can have an opportunity to coalesce syscalls with 207 // sure that the compiler can have an opportunity to coalesce syscalls with
208 // contiguous numbers and we also make sure that disjoint sets can return the 208 // contiguous numbers and we also make sure that disjoint sets can return the
209 // same errno. 209 // same errno.
210 int SysnoToRandomErrno(int sysno) { 210 int SysnoToRandomErrno(int sysno) {
211 // Small contiguous sets of 3 system calls return an errno equal to the 211 // Small contiguous sets of 3 system calls return an errno equal to the
212 // index of that set + 1 (so that we never return a NUL errno). 212 // index of that set + 1 (so that we never return a NUL errno).
213 return ((sysno & ~3) >> 2) % 29 + 1; 213 return ((sysno & ~3) >> 2) % 29 + 1;
214 } 214 }
215 215
216 Sandbox::ErrorCode SyntheticPolicy(int sysno) { 216 ErrorCode SyntheticPolicy(int sysno) {
217 if (sysno < static_cast<int>(MIN_SYSCALL) || 217 if (sysno < static_cast<int>(MIN_SYSCALL) ||
218 sysno > static_cast<int>(MAX_SYSCALL)) { 218 sysno > static_cast<int>(MAX_SYSCALL)) {
219 // FIXME: we should really not have to do that in a trivial policy. 219 // FIXME: we should really not have to do that in a trivial policy.
220 return ENOSYS; 220 return ENOSYS;
221 } 221 }
222 if (sysno == __NR_exit_group) { 222 if (sysno == __NR_exit_group) {
223 // exit_group() is special, we really need it to work. 223 // exit_group() is special, we really need it to work.
224 return Sandbox::SB_ALLOWED; 224 return ErrorCode::ERR_ALLOWED;
225 } else { 225 } else {
226 return SysnoToRandomErrno(sysno); 226 return SysnoToRandomErrno(sysno);
227 } 227 }
228 } 228 }
229 229
230 void SyntheticProcess(void) { 230 void SyntheticProcess(void) {
231 // Ensure that that kExpectedReturnValue + syscallnumber + 1 does not int 231 // Ensure that that kExpectedReturnValue + syscallnumber + 1 does not int
232 // overflow. 232 // overflow.
233 if (std::numeric_limits<int>::max() - kExpectedReturnValue - 1 < 233 if (std::numeric_limits<int>::max() - kExpectedReturnValue - 1 <
234 static_cast<int>(MAX_SYSCALL)) { 234 static_cast<int>(MAX_SYSCALL)) {
(...skipping 16 matching lines...) Expand all
251 } 251 }
252 } 252 }
253 ExitGroup(kExpectedReturnValue); 253 ExitGroup(kExpectedReturnValue);
254 } 254 }
255 255
256 TEST(SandboxBpf, SyntheticPolicy) { 256 TEST(SandboxBpf, SyntheticPolicy) {
257 TryPolicyInProcess(SyntheticPolicy, SyntheticProcess); 257 TryPolicyInProcess(SyntheticPolicy, SyntheticProcess);
258 } 258 }
259 259
260 } // namespace 260 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698