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 | 7 |
| 8 namespace { |
| 9 |
| 10 bool AllowedSetSockOpt(const Sandbox::SetSockOpt& setsockopt_req) { |
| 11 switch (setsockopt_req.level) { |
| 12 case SOL_SOCKET: |
| 13 switch (setsockopt_req.optname) { |
| 14 case SO_KEEPALIVE: |
| 15 case SO_LINGER: |
| 16 case SO_OOBINLINE: |
| 17 case SO_RCVBUF: |
| 18 case SO_RCVLOWAT: |
| 19 case SO_SNDLOWAT: |
| 20 case SO_RCVTIMEO: |
| 21 case SO_SNDTIMEO: |
| 22 case SO_REUSEADDR: |
| 23 case SO_SNDBUF: |
| 24 case SO_TIMESTAMP: |
| 25 return true; |
| 26 } |
| 27 break; |
| 28 case IPPROTO_TCP: |
| 29 switch (setsockopt_req.optname) { |
| 30 case TCP_CORK: |
| 31 case TCP_DEFER_ACCEPT: |
| 32 case TCP_INFO: |
| 33 case TCP_KEEPCNT: |
| 34 case TCP_KEEPIDLE: |
| 35 case TCP_KEEPINTVL: |
| 36 case TCP_LINGER2: |
| 37 case TCP_MAXSEG: |
| 38 case TCP_NODELAY: |
| 39 case TCP_QUICKACK: |
| 40 case TCP_SYNCNT: |
| 41 case TCP_WINDOW_CLAMP: |
| 42 return true; |
| 43 } |
| 44 break; |
| 45 } |
| 46 return false; |
| 47 } |
| 48 |
| 49 bool AllowedGetSockOpt(const Sandbox::GetSockOpt& getsockopt_req) { |
| 50 switch (getsockopt_req.level) { |
| 51 case SOL_SOCKET: |
| 52 switch (getsockopt_req.optname) { |
| 53 case SO_ACCEPTCONN: |
| 54 case SO_ERROR: |
| 55 case SO_KEEPALIVE: |
| 56 case SO_LINGER: |
| 57 case SO_OOBINLINE: |
| 58 case SO_RCVBUF: |
| 59 case SO_RCVLOWAT: |
| 60 case SO_SNDLOWAT: |
| 61 case SO_RCVTIMEO: |
| 62 case SO_SNDTIMEO: |
| 63 case SO_REUSEADDR: |
| 64 case SO_SNDBUF: |
| 65 case SO_TIMESTAMP: |
| 66 case SO_TYPE: |
| 67 return true; |
| 68 } |
| 69 break; |
| 70 case IPPROTO_TCP: |
| 71 switch (getsockopt_req.optname) { |
| 72 case TCP_CORK: |
| 73 case TCP_DEFER_ACCEPT: |
| 74 case TCP_INFO: |
| 75 case TCP_KEEPCNT: |
| 76 case TCP_KEEPIDLE: |
| 77 case TCP_KEEPINTVL: |
| 78 case TCP_LINGER2: |
| 79 case TCP_MAXSEG: |
| 80 case TCP_NODELAY: |
| 81 case TCP_QUICKACK: |
| 82 case TCP_SYNCNT: |
| 83 case TCP_WINDOW_CLAMP: |
| 84 return true; |
| 85 } |
| 86 break; |
| 87 } |
| 88 return false; |
| 89 } |
| 90 |
| 91 } // namespace |
| 92 |
8 namespace playground { | 93 namespace playground { |
9 | 94 |
10 #if defined(__NR_socket) | 95 #if defined(__NR_socket) |
11 | 96 |
12 ssize_t Sandbox::sandbox_recvfrom(int sockfd, void* buf, size_t len, int flags, | 97 ssize_t Sandbox::sandbox_recvfrom(int sockfd, void* buf, size_t len, int flags, |
13 void* from, socklen_t* fromlen) { | 98 void* from, socklen_t* fromlen) { |
14 long long tm; | 99 long long tm; |
15 Debug::syscall(&tm, __NR_recvfrom, "Executing handler"); | 100 Debug::syscall(&tm, __NR_recvfrom, "Executing handler"); |
16 | 101 |
17 SysCalls sys; | 102 SysCalls sys; |
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 | 413 |
329 bool Sandbox::process_setsockopt(const SyscallRequestInfo* info) { | 414 bool Sandbox::process_setsockopt(const SyscallRequestInfo* info) { |
330 // Read request | 415 // Read request |
331 SetSockOpt setsockopt_req; | 416 SetSockOpt setsockopt_req; |
332 SysCalls sys; | 417 SysCalls sys; |
333 if (read(sys, info->trustedProcessFd, &setsockopt_req, | 418 if (read(sys, info->trustedProcessFd, &setsockopt_req, |
334 sizeof(setsockopt_req)) != sizeof(setsockopt_req)) { | 419 sizeof(setsockopt_req)) != sizeof(setsockopt_req)) { |
335 die("Failed to read parameters for setsockopt() [process]"); | 420 die("Failed to read parameters for setsockopt() [process]"); |
336 } | 421 } |
337 | 422 |
338 switch (setsockopt_req.level) { | 423 if (AllowedSetSockOpt(setsockopt_req)) { |
339 case SOL_SOCKET: | 424 SecureMem::sendSystemCall(*info, false, setsockopt_req.sockfd, |
340 switch (setsockopt_req.optname) { | 425 setsockopt_req.level, setsockopt_req.optname, |
341 case SO_KEEPALIVE: | 426 setsockopt_req.optval, setsockopt_req.optlen); |
342 case SO_LINGER: | 427 return true; |
343 case SO_OOBINLINE: | |
344 case SO_RCVBUF: | |
345 case SO_RCVLOWAT: | |
346 case SO_SNDLOWAT: | |
347 case SO_RCVTIMEO: | |
348 case SO_SNDTIMEO: | |
349 case SO_REUSEADDR: | |
350 case SO_SNDBUF: | |
351 case SO_TIMESTAMP: | |
352 SecureMem::sendSystemCall(*info, false, setsockopt_req.sockfd, | |
353 setsockopt_req.level, setsockopt_req.optname, | |
354 setsockopt_req.optval, setsockopt_req.optlen); | |
355 return true; | |
356 default: | |
357 break; | |
358 } | |
359 break; | |
360 case IPPROTO_TCP: | |
361 switch (setsockopt_req.optname) { | |
362 case TCP_CORK: | |
363 case TCP_DEFER_ACCEPT: | |
364 case TCP_INFO: | |
365 case TCP_KEEPCNT: | |
366 case TCP_KEEPIDLE: | |
367 case TCP_KEEPINTVL: | |
368 case TCP_LINGER2: | |
369 case TCP_MAXSEG: | |
370 case TCP_NODELAY: | |
371 case TCP_QUICKACK: | |
372 case TCP_SYNCNT: | |
373 case TCP_WINDOW_CLAMP: | |
374 SecureMem::sendSystemCall(*info, false, setsockopt_req.sockfd, | |
375 setsockopt_req.level, setsockopt_req.optname, | |
376 setsockopt_req.optval, setsockopt_req.optlen); | |
377 return true; | |
378 default: | |
379 break; | |
380 } | |
381 break; | |
382 default: | |
383 break; | |
384 } | 428 } |
385 SecureMem::abandonSystemCall(*info, -EINVAL); | 429 SecureMem::abandonSystemCall(*info, -EINVAL); |
386 return false; | 430 return false; |
387 } | 431 } |
388 | 432 |
389 bool Sandbox::process_getsockopt(const SyscallRequestInfo* info) { | 433 bool Sandbox::process_getsockopt(const SyscallRequestInfo* info) { |
390 // Read request | 434 // Read request |
391 GetSockOpt getsockopt_req; | 435 GetSockOpt getsockopt_req; |
392 SysCalls sys; | 436 SysCalls sys; |
393 if (read(sys, info->trustedProcessFd, &getsockopt_req, | 437 if (read(sys, info->trustedProcessFd, &getsockopt_req, |
394 sizeof(getsockopt_req)) != sizeof(getsockopt_req)) { | 438 sizeof(getsockopt_req)) != sizeof(getsockopt_req)) { |
395 die("Failed to read parameters for getsockopt() [process]"); | 439 die("Failed to read parameters for getsockopt() [process]"); |
396 } | 440 } |
397 | 441 |
398 switch (getsockopt_req.level) { | 442 if (AllowedGetSockOpt(getsockopt_req)) { |
399 case SOL_SOCKET: | 443 SecureMem::sendSystemCall(*info, false, getsockopt_req.sockfd, |
400 switch (getsockopt_req.optname) { | 444 getsockopt_req.level, getsockopt_req.optname, |
401 case SO_ACCEPTCONN: | 445 getsockopt_req.optval, getsockopt_req.optlen); |
402 case SO_ERROR: | 446 return true; |
403 case SO_KEEPALIVE: | |
404 case SO_LINGER: | |
405 case SO_OOBINLINE: | |
406 case SO_RCVBUF: | |
407 case SO_RCVLOWAT: | |
408 case SO_SNDLOWAT: | |
409 case SO_RCVTIMEO: | |
410 case SO_SNDTIMEO: | |
411 case SO_REUSEADDR: | |
412 case SO_SNDBUF: | |
413 case SO_TIMESTAMP: | |
414 case SO_TYPE: | |
415 SecureMem::sendSystemCall(*info, false, getsockopt_req.sockfd, | |
416 getsockopt_req.level, getsockopt_req.optname, | |
417 getsockopt_req.optval, getsockopt_req.optlen); | |
418 return true; | |
419 default: | |
420 break; | |
421 } | |
422 break; | |
423 case IPPROTO_TCP: | |
424 switch (getsockopt_req.optname) { | |
425 case TCP_CORK: | |
426 case TCP_DEFER_ACCEPT: | |
427 case TCP_INFO: | |
428 case TCP_KEEPCNT: | |
429 case TCP_KEEPIDLE: | |
430 case TCP_KEEPINTVL: | |
431 case TCP_LINGER2: | |
432 case TCP_MAXSEG: | |
433 case TCP_NODELAY: | |
434 case TCP_QUICKACK: | |
435 case TCP_SYNCNT: | |
436 case TCP_WINDOW_CLAMP: | |
437 SecureMem::sendSystemCall(*info, false, getsockopt_req.sockfd, | |
438 getsockopt_req.level, getsockopt_req.optname, | |
439 getsockopt_req.optval, getsockopt_req.optlen); | |
440 return true; | |
441 default: | |
442 break; | |
443 } | |
444 break; | |
445 default: | |
446 break; | |
447 } | 447 } |
448 SecureMem::abandonSystemCall(*info, -EINVAL); | 448 SecureMem::abandonSystemCall(*info, -EINVAL); |
449 return false; | 449 return false; |
450 } | 450 } |
451 | 451 |
452 #endif | 452 #endif |
453 #if defined(__NR_socketcall) | 453 #if defined(__NR_socketcall) |
454 | 454 |
455 enum { | 455 enum { |
456 SYS_SOCKET = 1, | 456 SYS_SOCKET = 1, |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
807 // Unsupported flag encountered. Deny the call. | 807 // Unsupported flag encountered. Deny the call. |
808 goto deny; | 808 goto deny; |
809 } | 809 } |
810 // Receiving data on a connected socket is similar to calling read(). | 810 // Receiving data on a connected socket is similar to calling read(). |
811 // Allow it. | 811 // Allow it. |
812 goto accept_complex; | 812 goto accept_complex; |
813 case SYS_SHUTDOWN: | 813 case SYS_SHUTDOWN: |
814 // Shutting down a socket is always OK. | 814 // Shutting down a socket is always OK. |
815 goto accept_simple; | 815 goto accept_simple; |
816 case SYS_SETSOCKOPT: | 816 case SYS_SETSOCKOPT: |
817 switch (socketcall_req.args.setsockopt.level) { | 817 if (AllowedSetSockOpt(socketcall_req.args.setsockopt)) { |
818 case SOL_SOCKET: | 818 goto accept_complex; |
819 switch (socketcall_req.args.setsockopt.optname) { | |
820 case SO_KEEPALIVE: | |
821 case SO_LINGER: | |
822 case SO_OOBINLINE: | |
823 case SO_RCVBUF: | |
824 case SO_RCVLOWAT: | |
825 case SO_SNDLOWAT: | |
826 case SO_RCVTIMEO: | |
827 case SO_SNDTIMEO: | |
828 case SO_REUSEADDR: | |
829 case SO_SNDBUF: | |
830 case SO_TIMESTAMP: | |
831 goto accept_complex; | |
832 default: | |
833 break; | |
834 } | |
835 break; | |
836 case IPPROTO_TCP: | |
837 switch (socketcall_req.args.setsockopt.optname) { | |
838 case TCP_CORK: | |
839 case TCP_DEFER_ACCEPT: | |
840 case TCP_INFO: | |
841 case TCP_KEEPCNT: | |
842 case TCP_KEEPIDLE: | |
843 case TCP_KEEPINTVL: | |
844 case TCP_LINGER2: | |
845 case TCP_MAXSEG: | |
846 case TCP_NODELAY: | |
847 case TCP_QUICKACK: | |
848 case TCP_SYNCNT: | |
849 case TCP_WINDOW_CLAMP: | |
850 goto accept_complex; | |
851 default: | |
852 break; | |
853 } | |
854 break; | |
855 default: | |
856 break; | |
857 } | 819 } |
858 goto deny; | 820 goto deny; |
859 case SYS_GETSOCKOPT: | 821 case SYS_GETSOCKOPT: |
860 switch (socketcall_req.args.getsockopt.level) { | 822 if (AllowedGetSockOpt(socketcall_req.args.getsockopt)) { |
861 case SOL_SOCKET: | 823 goto accept_complex; |
862 switch (socketcall_req.args.getsockopt.optname) { | |
863 case SO_ACCEPTCONN: | |
864 case SO_ERROR: | |
865 case SO_KEEPALIVE: | |
866 case SO_LINGER: | |
867 case SO_OOBINLINE: | |
868 case SO_RCVBUF: | |
869 case SO_RCVLOWAT: | |
870 case SO_SNDLOWAT: | |
871 case SO_RCVTIMEO: | |
872 case SO_SNDTIMEO: | |
873 case SO_REUSEADDR: | |
874 case SO_SNDBUF: | |
875 case SO_TIMESTAMP: | |
876 case SO_TYPE: | |
877 goto accept_complex; | |
878 default: | |
879 break; | |
880 } | |
881 break; | |
882 case IPPROTO_TCP: | |
883 switch (socketcall_req.args.getsockopt.optname) { | |
884 case TCP_CORK: | |
885 case TCP_DEFER_ACCEPT: | |
886 case TCP_INFO: | |
887 case TCP_KEEPCNT: | |
888 case TCP_KEEPIDLE: | |
889 case TCP_KEEPINTVL: | |
890 case TCP_LINGER2: | |
891 case TCP_MAXSEG: | |
892 case TCP_NODELAY: | |
893 case TCP_QUICKACK: | |
894 case TCP_SYNCNT: | |
895 case TCP_WINDOW_CLAMP: | |
896 goto accept_complex; | |
897 default: | |
898 break; | |
899 } | |
900 break; | |
901 default: | |
902 break; | |
903 } | 824 } |
904 goto deny; | 825 goto deny; |
905 case SYS_SENDMSG: { | 826 case SYS_SENDMSG: { |
906 struct msghdr* msg = reinterpret_cast<struct msghdr*>(extra); | 827 struct msghdr* msg = reinterpret_cast<struct msghdr*>(extra); |
907 | 828 |
908 if (CMSG_ALIGN(sizeof(socketcall_req.args)) + | 829 if (CMSG_ALIGN(sizeof(socketcall_req.args)) + |
909 CMSG_ALIGN(sizeof(*msg)) + | 830 CMSG_ALIGN(sizeof(*msg)) + |
910 numSendmsgExtra > | 831 numSendmsgExtra > |
911 sizeof(info->mem->pathname)) { | 832 sizeof(info->mem->pathname)) { |
912 goto deny; | 833 goto deny; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
978 default: | 899 default: |
979 deny: | 900 deny: |
980 SecureMem::abandonSystemCall(*info, rc); | 901 SecureMem::abandonSystemCall(*info, rc); |
981 return false; | 902 return false; |
982 } | 903 } |
983 } | 904 } |
984 | 905 |
985 #endif | 906 #endif |
986 | 907 |
987 } // namespace | 908 } // namespace |
OLD | NEW |