| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "debug.h" | 5 #include "debug.h" |
| 6 #include "sandbox_impl.h" | 6 #include "sandbox_impl.h" |
| 7 #include "syscall_table.h" | 7 #include "syscall_table.h" |
| 8 | 8 |
| 9 namespace playground { | 9 namespace playground { |
| 10 | 10 |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 | 264 |
| 265 void* Sandbox::defaultSystemCallHandler(int syscallNum, void* arg0, void* arg1, | 265 void* Sandbox::defaultSystemCallHandler(int syscallNum, void* arg0, void* arg1, |
| 266 void* arg2, void* arg3, void* arg4, | 266 void* arg2, void* arg3, void* arg4, |
| 267 void* arg5) { | 267 void* arg5) { |
| 268 // TODO(markus): The following comment is currently not true, we do intercept
these system calls. Try to fix that. | 268 // TODO(markus): The following comment is currently not true, we do intercept
these system calls. Try to fix that. |
| 269 | 269 |
| 270 // We try to avoid intercepting read(), write(), and sigreturn(), as | 270 // We try to avoid intercepting read(), write(), and sigreturn(), as |
| 271 // these system calls are not restricted in Seccomp mode. But depending on | 271 // these system calls are not restricted in Seccomp mode. But depending on |
| 272 // the exact instruction sequence in libc, we might not be able to reliably | 272 // the exact instruction sequence in libc, we might not be able to reliably |
| 273 // filter out these system calls at the time when we instrument the code. | 273 // filter out these system calls at the time when we instrument the code. |
| 274 SysCalls sys; | 274 SysCalls sys; |
| 275 long rc; | 275 long rc; |
| 276 long long tm; |
| 276 switch (syscallNum) { | 277 switch (syscallNum) { |
| 277 case __NR_read: | 278 case __NR_read: |
| 278 Debug::syscall(syscallNum, "Allowing unrestricted system call"); | 279 Debug::syscall(&tm, syscallNum, "Allowing unrestricted system call"); |
| 279 rc = sys.read((long)arg0, arg1, (size_t)arg2); | 280 rc = sys.read((long)arg0, arg1, (size_t)arg2); |
| 280 break; | 281 break; |
| 281 case __NR_write: | 282 case __NR_write: |
| 282 Debug::syscall(syscallNum, "Allowing unrestricted system call"); | 283 Debug::syscall(&tm, syscallNum, "Allowing unrestricted system call"); |
| 283 rc = sys.write((long)arg0, arg1, (size_t)arg2); | 284 rc = sys.write((long)arg0, arg1, (size_t)arg2); |
| 284 break; | 285 break; |
| 285 case __NR_rt_sigreturn: | 286 case __NR_rt_sigreturn: |
| 286 Debug::syscall(syscallNum, "Allowing unrestricted system call"); | 287 Debug::syscall(&tm, syscallNum, "Allowing unrestricted system call"); |
| 287 rc = sys.rt_sigreturn((unsigned long)arg0); | 288 rc = sys.rt_sigreturn((unsigned long)arg0); |
| 288 break; | 289 break; |
| 289 default: | 290 default: |
| 290 if (Debug::isEnabled()) { | 291 if (Debug::isEnabled()) { |
| 291 // In debug mode, prevent stderr from being closed | 292 // In debug mode, prevent stderr from being closed |
| 292 if (syscallNum == __NR_close && arg0 == (void *)2) | 293 if (syscallNum == __NR_close && arg0 == (void *)2) |
| 293 return 0; | 294 return 0; |
| 294 } | 295 } |
| 295 | 296 |
| 296 if ((unsigned)syscallNum <= maxSyscall && | 297 if ((unsigned)syscallNum <= maxSyscall && |
| 297 syscallTable[syscallNum].handler == UNRESTRICTED_SYSCALL) { | 298 syscallTable[syscallNum].handler == UNRESTRICTED_SYSCALL) { |
| 298 Debug::syscall(syscallNum, "Allowing unrestricted system call"); | 299 Debug::syscall(&tm, syscallNum, "Allowing unrestricted system call"); |
| 299 perform_unrestricted: | 300 perform_unrestricted: |
| 300 struct { | 301 struct { |
| 301 int sysnum; | 302 int sysnum; |
| 302 void* unrestricted_req[6]; | 303 void* unrestricted_req[6]; |
| 303 } __attribute__((packed)) request = { | 304 } __attribute__((packed)) request = { |
| 304 syscallNum, { arg0, arg1, arg2, arg3, arg4, arg5 } }; | 305 syscallNum, { arg0, arg1, arg2, arg3, arg4, arg5 } }; |
| 305 | 306 |
| 306 int thread = threadFdPub(); | 307 int thread = threadFdPub(); |
| 307 void* rc; | 308 void* rc; |
| 308 if (write(sys, thread, &request, sizeof(request)) != sizeof(request) || | 309 if (write(sys, thread, &request, sizeof(request)) != sizeof(request) || |
| 309 read(sys, thread, &rc, sizeof(rc)) != sizeof(rc)) { | 310 read(sys, thread, &rc, sizeof(rc)) != sizeof(rc)) { |
| 310 die("Failed to forward unrestricted system call"); | 311 die("Failed to forward unrestricted system call"); |
| 311 } | 312 } |
| 313 Debug::elapsed(tm, syscallNum); |
| 312 return rc; | 314 return rc; |
| 313 } else if (Debug::isEnabled()) { | 315 } else if (Debug::isEnabled()) { |
| 314 Debug::syscall(syscallNum, | 316 Debug::syscall(&tm, syscallNum, |
| 315 "In production mode, this call would be disallowed"); | 317 "In production mode, this call would be disallowed"); |
| 316 goto perform_unrestricted; | 318 goto perform_unrestricted; |
| 317 } else { | 319 } else { |
| 318 return (void *)-ENOSYS; | 320 return (void *)-ENOSYS; |
| 319 } | 321 } |
| 320 } | 322 } |
| 321 if (rc < 0) { | 323 if (rc < 0) { |
| 322 rc = -sys.my_errno; | 324 rc = -sys.my_errno; |
| 323 } | 325 } |
| 326 Debug::elapsed(tm, syscallNum); |
| 324 return (void *)rc; | 327 return (void *)rc; |
| 325 } | 328 } |
| 326 | 329 |
| 327 } // namespace | 330 } // namespace |
| OLD | NEW |