| 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 |