| 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 playground { | 8 namespace playground { |
| 9 | 9 |
| 10 #if defined(__NR_socket) | 10 #if defined(__NR_socket) |
| 11 | 11 |
| 12 ssize_t Sandbox::sandbox_recvfrom(int sockfd, void* buf, size_t len, int flags, | 12 ssize_t Sandbox::sandbox_recvfrom(int sockfd, void* buf, size_t len, int flags, |
| 13 void* from, socklen_t* fromlen) { | 13 void* from, socklen_t* fromlen) { |
| 14 Debug::syscall(__NR_recvfrom, "Executing handler"); | 14 long long tm; |
| 15 Debug::syscall(&tm, __NR_recvfrom, "Executing handler"); |
| 15 | 16 |
| 16 SysCalls sys; | 17 SysCalls sys; |
| 17 if (!from && !flags) { | 18 if (!from && !flags) { |
| 18 // recv() with a NULL sender and no flags is the same as read(), which | 19 // recv() with a NULL sender and no flags is the same as read(), which |
| 19 // is unrestricted in seccomp mode. | 20 // is unrestricted in seccomp mode. |
| 20 Debug::message("Replaced recv() with call to read()"); | 21 Debug::message("Replaced recv() with call to read()"); |
| 21 ssize_t rc = sys.read(sockfd, buf, len); | 22 ssize_t rc = sys.read(sockfd, buf, len); |
| 22 if (rc < 0) { | 23 if (rc < 0) { |
| 24 Debug::elapsed(tm, __NR_recvfrom); |
| 23 return -sys.my_errno; | 25 return -sys.my_errno; |
| 24 } else { | 26 } else { |
| 27 Debug::elapsed(tm, __NR_recvfrom); |
| 25 return rc; | 28 return rc; |
| 26 } | 29 } |
| 27 } | 30 } |
| 28 | 31 |
| 29 struct { | 32 struct { |
| 30 int sysnum; | 33 int sysnum; |
| 31 long long cookie; | 34 long long cookie; |
| 32 RecvFrom recvfrom_req; | 35 RecvFrom recvfrom_req; |
| 33 } __attribute__((packed)) request; | 36 } __attribute__((packed)) request; |
| 34 request.sysnum = __NR_recvfrom; | 37 request.sysnum = __NR_recvfrom; |
| 35 request.cookie = cookie(); | 38 request.cookie = cookie(); |
| 36 request.recvfrom_req.sockfd = sockfd; | 39 request.recvfrom_req.sockfd = sockfd; |
| 37 request.recvfrom_req.buf = buf; | 40 request.recvfrom_req.buf = buf; |
| 38 request.recvfrom_req.len = len; | 41 request.recvfrom_req.len = len; |
| 39 request.recvfrom_req.flags = flags; | 42 request.recvfrom_req.flags = flags; |
| 40 request.recvfrom_req.from = from; | 43 request.recvfrom_req.from = from; |
| 41 request.recvfrom_req.fromlen = fromlen; | 44 request.recvfrom_req.fromlen = fromlen; |
| 42 | 45 |
| 43 long rc; | 46 long rc; |
| 44 if (write(sys, processFdPub(), &request, sizeof(request)) != | 47 if (write(sys, processFdPub(), &request, sizeof(request)) != |
| 45 sizeof(request) || | 48 sizeof(request) || |
| 46 read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) { | 49 read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) { |
| 47 die("Failed to forward recvfrom() request [sandbox]"); | 50 die("Failed to forward recvfrom() request [sandbox]"); |
| 48 } | 51 } |
| 52 Debug::elapsed(tm, __NR_recvfrom); |
| 49 return static_cast<int>(rc); | 53 return static_cast<int>(rc); |
| 50 } | 54 } |
| 51 | 55 |
| 52 ssize_t Sandbox::sandbox_recvmsg(int sockfd, struct msghdr* msg, int flags) { | 56 ssize_t Sandbox::sandbox_recvmsg(int sockfd, struct msghdr* msg, int flags) { |
| 53 Debug::syscall(__NR_recvmsg, "Executing handler"); | 57 long long tm; |
| 58 Debug::syscall(&tm, __NR_recvmsg, "Executing handler"); |
| 54 | 59 |
| 55 // We cannot simplify recvmsg() to recvfrom(), recv() or read(), as we do | 60 // We cannot simplify recvmsg() to recvfrom(), recv() or read(), as we do |
| 56 // not know whether the caller needs us to set msg->msg_flags. | 61 // not know whether the caller needs us to set msg->msg_flags. |
| 57 struct { | 62 struct { |
| 58 int sysnum; | 63 int sysnum; |
| 59 long long cookie; | 64 long long cookie; |
| 60 RecvMsg recvmsg_req; | 65 RecvMsg recvmsg_req; |
| 61 } __attribute__((packed)) request; | 66 } __attribute__((packed)) request; |
| 62 request.sysnum = __NR_recvmsg; | 67 request.sysnum = __NR_recvmsg; |
| 63 request.cookie = cookie(); | 68 request.cookie = cookie(); |
| 64 request.recvmsg_req.sockfd = sockfd; | 69 request.recvmsg_req.sockfd = sockfd; |
| 65 request.recvmsg_req.msg = msg; | 70 request.recvmsg_req.msg = msg; |
| 66 request.recvmsg_req.flags = flags; | 71 request.recvmsg_req.flags = flags; |
| 67 | 72 |
| 68 long rc; | 73 long rc; |
| 69 SysCalls sys; | 74 SysCalls sys; |
| 70 if (write(sys, processFdPub(), &request, sizeof(request)) != | 75 if (write(sys, processFdPub(), &request, sizeof(request)) != |
| 71 sizeof(request) || | 76 sizeof(request) || |
| 72 read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) { | 77 read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) { |
| 73 die("Failed to forward recvmsg() request [sandbox]"); | 78 die("Failed to forward recvmsg() request [sandbox]"); |
| 74 } | 79 } |
| 80 Debug::elapsed(tm, __NR_recvmsg); |
| 75 return static_cast<int>(rc); | 81 return static_cast<int>(rc); |
| 76 } | 82 } |
| 77 | 83 |
| 78 size_t Sandbox::sandbox_sendmsg(int sockfd, const struct msghdr* msg, | 84 size_t Sandbox::sandbox_sendmsg(int sockfd, const struct msghdr* msg, |
| 79 int flags) { | 85 int flags) { |
| 80 Debug::syscall(__NR_sendmsg, "Executing handler"); | 86 long long tm; |
| 87 Debug::syscall(&tm, __NR_sendmsg, "Executing handler"); |
| 81 | 88 |
| 82 if (msg->msg_iovlen == 1 && msg->msg_controllen == 0) { | 89 if (msg->msg_iovlen == 1 && msg->msg_controllen == 0) { |
| 83 // sendmsg() can sometimes be simplified as sendto() | 90 // sendmsg() can sometimes be simplified as sendto() |
| 84 return sandbox_sendto(sockfd, msg->msg_iov, msg->msg_iovlen, | 91 return sandbox_sendto(sockfd, msg->msg_iov, msg->msg_iovlen, |
| 85 flags, msg->msg_name, msg->msg_namelen); | 92 flags, msg->msg_name, msg->msg_namelen); |
| 86 } | 93 } |
| 87 | 94 |
| 88 struct Request { | 95 struct Request { |
| 89 int sysnum; | 96 int sysnum; |
| 90 long long cookie; | 97 long long cookie; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 104 msg->msg_namelen, | 111 msg->msg_namelen, |
| 105 msg->msg_control, msg->msg_controllen); | 112 msg->msg_control, msg->msg_controllen); |
| 106 | 113 |
| 107 long rc; | 114 long rc; |
| 108 SysCalls sys; | 115 SysCalls sys; |
| 109 if (write(sys, processFdPub(), &data, sizeof(data)) != | 116 if (write(sys, processFdPub(), &data, sizeof(data)) != |
| 110 (ssize_t)sizeof(data) || | 117 (ssize_t)sizeof(data) || |
| 111 read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) { | 118 read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) { |
| 112 die("Failed to forward sendmsg() request [sandbox]"); | 119 die("Failed to forward sendmsg() request [sandbox]"); |
| 113 } | 120 } |
| 121 Debug::elapsed(tm, __NR_sendmsg); |
| 114 return static_cast<int>(rc); | 122 return static_cast<int>(rc); |
| 115 } | 123 } |
| 116 | 124 |
| 117 ssize_t Sandbox::sandbox_sendto(int sockfd, const void* buf, size_t len, | 125 ssize_t Sandbox::sandbox_sendto(int sockfd, const void* buf, size_t len, |
| 118 int flags, const void* to, socklen_t tolen) { | 126 int flags, const void* to, socklen_t tolen) { |
| 119 Debug::syscall(__NR_sendto, "Executing handler"); | 127 long long tm; |
| 128 Debug::syscall(&tm, __NR_sendto, "Executing handler"); |
| 120 | 129 |
| 121 SysCalls sys; | 130 SysCalls sys; |
| 122 if (!to && !flags) { | 131 if (!to && !flags) { |
| 123 // sendto() with a NULL recipient and no flags is the same as write(), | 132 // sendto() with a NULL recipient and no flags is the same as write(), |
| 124 // which is unrestricted in seccomp mode. | 133 // which is unrestricted in seccomp mode. |
| 125 Debug::message("Replaced sendto() with call to write()"); | 134 Debug::message("Replaced sendto() with call to write()"); |
| 126 ssize_t rc = sys.write(sockfd, buf, len); | 135 ssize_t rc = sys.write(sockfd, buf, len); |
| 127 if (rc < 0) { | 136 if (rc < 0) { |
| 137 Debug::elapsed(tm, __NR_sendto); |
| 128 return -sys.my_errno; | 138 return -sys.my_errno; |
| 129 } else { | 139 } else { |
| 140 Debug::elapsed(tm, __NR_sendto); |
| 130 return rc; | 141 return rc; |
| 131 } | 142 } |
| 132 } | 143 } |
| 133 | 144 |
| 134 struct { | 145 struct { |
| 135 int sysnum; | 146 int sysnum; |
| 136 long long cookie; | 147 long long cookie; |
| 137 SendTo sendto_req; | 148 SendTo sendto_req; |
| 138 } __attribute__((packed)) request; | 149 } __attribute__((packed)) request; |
| 139 request.sysnum = __NR_sendto; | 150 request.sysnum = __NR_sendto; |
| 140 request.cookie = cookie(); | 151 request.cookie = cookie(); |
| 141 request.sendto_req.sockfd = sockfd; | 152 request.sendto_req.sockfd = sockfd; |
| 142 request.sendto_req.buf = buf; | 153 request.sendto_req.buf = buf; |
| 143 request.sendto_req.len = len; | 154 request.sendto_req.len = len; |
| 144 request.sendto_req.flags = flags; | 155 request.sendto_req.flags = flags; |
| 145 request.sendto_req.to = to; | 156 request.sendto_req.to = to; |
| 146 request.sendto_req.tolen = tolen; | 157 request.sendto_req.tolen = tolen; |
| 147 | 158 |
| 148 long rc; | 159 long rc; |
| 149 if (write(sys, processFdPub(), &request, sizeof(request)) != | 160 if (write(sys, processFdPub(), &request, sizeof(request)) != |
| 150 sizeof(request) || | 161 sizeof(request) || |
| 151 read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) { | 162 read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) { |
| 152 die("Failed to forward sendto() request [sandbox]"); | 163 die("Failed to forward sendto() request [sandbox]"); |
| 153 } | 164 } |
| 165 Debug::elapsed(tm, __NR_sendto); |
| 154 return static_cast<int>(rc); | 166 return static_cast<int>(rc); |
| 155 } | 167 } |
| 156 | 168 |
| 157 int Sandbox::sandbox_setsockopt(int sockfd, int level, int optname, | 169 int Sandbox::sandbox_setsockopt(int sockfd, int level, int optname, |
| 158 const void* optval, socklen_t optlen) { | 170 const void* optval, socklen_t optlen) { |
| 159 Debug::syscall(__NR_setsockopt, "Executing handler"); | 171 long long tm; |
| 172 Debug::syscall(&tm, __NR_setsockopt, "Executing handler"); |
| 160 | 173 |
| 161 struct { | 174 struct { |
| 162 int sysnum; | 175 int sysnum; |
| 163 long long cookie; | 176 long long cookie; |
| 164 SetSockOpt setsockopt_req; | 177 SetSockOpt setsockopt_req; |
| 165 } __attribute__((packed)) request; | 178 } __attribute__((packed)) request; |
| 166 request.sysnum = __NR_setsockopt; | 179 request.sysnum = __NR_setsockopt; |
| 167 request.cookie = cookie(); | 180 request.cookie = cookie(); |
| 168 request.setsockopt_req.sockfd = sockfd; | 181 request.setsockopt_req.sockfd = sockfd; |
| 169 request.setsockopt_req.level = level; | 182 request.setsockopt_req.level = level; |
| 170 request.setsockopt_req.optname = optname; | 183 request.setsockopt_req.optname = optname; |
| 171 request.setsockopt_req.optval = optval; | 184 request.setsockopt_req.optval = optval; |
| 172 request.setsockopt_req.optlen = optlen; | 185 request.setsockopt_req.optlen = optlen; |
| 173 | 186 |
| 174 long rc; | 187 long rc; |
| 175 SysCalls sys; | 188 SysCalls sys; |
| 176 if (write(sys, processFdPub(), &request, sizeof(request)) != | 189 if (write(sys, processFdPub(), &request, sizeof(request)) != |
| 177 sizeof(request) || | 190 sizeof(request) || |
| 178 read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) { | 191 read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) { |
| 179 die("Failed to forward setsockopt() request [sandbox]"); | 192 die("Failed to forward setsockopt() request [sandbox]"); |
| 180 } | 193 } |
| 194 Debug::elapsed(tm, __NR_setsockopt); |
| 181 return static_cast<int>(rc); | 195 return static_cast<int>(rc); |
| 182 } | 196 } |
| 183 | 197 |
| 184 int Sandbox::sandbox_getsockopt(int sockfd, int level, int optname, | 198 int Sandbox::sandbox_getsockopt(int sockfd, int level, int optname, |
| 185 void* optval, socklen_t* optlen) { | 199 void* optval, socklen_t* optlen) { |
| 186 Debug::syscall(__NR_getsockopt, "Executing handler"); | 200 long long tm; |
| 201 Debug::syscall(&tm, __NR_getsockopt, "Executing handler"); |
| 187 | 202 |
| 188 struct { | 203 struct { |
| 189 int sysnum; | 204 int sysnum; |
| 190 long long cookie; | 205 long long cookie; |
| 191 GetSockOpt getsockopt_req; | 206 GetSockOpt getsockopt_req; |
| 192 } __attribute__((packed)) request; | 207 } __attribute__((packed)) request; |
| 193 request.sysnum = __NR_getsockopt; | 208 request.sysnum = __NR_getsockopt; |
| 194 request.cookie = cookie(); | 209 request.cookie = cookie(); |
| 195 request.getsockopt_req.sockfd = sockfd; | 210 request.getsockopt_req.sockfd = sockfd; |
| 196 request.getsockopt_req.level = level; | 211 request.getsockopt_req.level = level; |
| 197 request.getsockopt_req.optname = optname; | 212 request.getsockopt_req.optname = optname; |
| 198 request.getsockopt_req.optval = optval; | 213 request.getsockopt_req.optval = optval; |
| 199 request.getsockopt_req.optlen = optlen; | 214 request.getsockopt_req.optlen = optlen; |
| 200 | 215 |
| 201 long rc; | 216 long rc; |
| 202 SysCalls sys; | 217 SysCalls sys; |
| 203 if (write(sys, processFdPub(), &request, sizeof(request)) != | 218 if (write(sys, processFdPub(), &request, sizeof(request)) != |
| 204 sizeof(request) || | 219 sizeof(request) || |
| 205 read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) { | 220 read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) { |
| 206 die("Failed to forward getsockopt() request [sandbox]"); | 221 die("Failed to forward getsockopt() request [sandbox]"); |
| 207 } | 222 } |
| 223 Debug::elapsed(tm, __NR_getsockopt); |
| 208 return static_cast<int>(rc); | 224 return static_cast<int>(rc); |
| 209 } | 225 } |
| 210 | 226 |
| 211 bool Sandbox::process_recvfrom(int parentMapsFd, int sandboxFd, | 227 bool Sandbox::process_recvfrom(int parentMapsFd, int sandboxFd, |
| 212 int threadFdPub, int threadFd, | 228 int threadFdPub, int threadFd, |
| 213 SecureMem::Args* mem) { | 229 SecureMem::Args* mem) { |
| 214 // Read request | 230 // Read request |
| 215 RecvFrom recvfrom_req; | 231 RecvFrom recvfrom_req; |
| 216 SysCalls sys; | 232 SysCalls sys; |
| 217 if (read(sys, sandboxFd, &recvfrom_req, sizeof(recvfrom_req)) != | 233 if (read(sys, sandboxFd, &recvfrom_req, sizeof(recvfrom_req)) != |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 546 { SIZE(getsockopt) }, | 562 { SIZE(getsockopt) }, |
| 547 { SIZE(sendmsg) }, | 563 { SIZE(sendmsg) }, |
| 548 { SIZE(recvmsg) }, | 564 { SIZE(recvmsg) }, |
| 549 { SIZE(accept4) } | 565 { SIZE(accept4) } |
| 550 #undef STRUCT | 566 #undef STRUCT |
| 551 #undef SIZE | 567 #undef SIZE |
| 552 #undef OFF | 568 #undef OFF |
| 553 }; | 569 }; |
| 554 | 570 |
| 555 int Sandbox::sandbox_socketcall(int call, void* args) { | 571 int Sandbox::sandbox_socketcall(int call, void* args) { |
| 556 Debug::syscall(__NR_socketcall, "Executing handler", call); | 572 long long tm; |
| 573 Debug::syscall(&tm, __NR_socketcall, "Executing handler", call); |
| 557 | 574 |
| 558 // When demultiplexing socketcall(), only accept calls that have a valid | 575 // When demultiplexing socketcall(), only accept calls that have a valid |
| 559 // "call" opcode. | 576 // "call" opcode. |
| 560 if (call < SYS_SOCKET || call > SYS_ACCEPT4) { | 577 if (call < SYS_SOCKET || call > SYS_ACCEPT4) { |
| 578 Debug::elapsed(tm, __NR_socketcall, call); |
| 561 return -ENOSYS; | 579 return -ENOSYS; |
| 562 } | 580 } |
| 563 | 581 |
| 564 // Some type of calls include a pointer to an address or name, which cannot | 582 // Some type of calls include a pointer to an address or name, which cannot |
| 565 // be accessed by the trusted process, as it lives in a separate address | 583 // be accessed by the trusted process, as it lives in a separate address |
| 566 // space. For these calls, append the extra data to the serialized request. | 584 // space. For these calls, append the extra data to the serialized request. |
| 567 // This requires some copying of data, as we have to make sure there is | 585 // This requires some copying of data, as we have to make sure there is |
| 568 // only a single atomic call to write(). | 586 // only a single atomic call to write(). |
| 569 socklen_t numExtraData = 0; | 587 socklen_t numExtraData = 0; |
| 570 const void* extraDataAddr = NULL; | 588 const void* extraDataAddr = NULL; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 640 numExtraData = 0; | 658 numExtraData = 0; |
| 641 } | 659 } |
| 642 if (call == SYS_SEND && !request->socketcall_req.args.send.flags) { | 660 if (call == SYS_SEND && !request->socketcall_req.args.send.flags) { |
| 643 // send() with no flags is the same as write(), which is unrestricted | 661 // send() with no flags is the same as write(), which is unrestricted |
| 644 // in seccomp mode. | 662 // in seccomp mode. |
| 645 Debug::message("Replaced socketcall() with call to write()"); | 663 Debug::message("Replaced socketcall() with call to write()"); |
| 646 ssize_t rc = sys.write(request->socketcall_req.args.send.sockfd, | 664 ssize_t rc = sys.write(request->socketcall_req.args.send.sockfd, |
| 647 request->socketcall_req.args.send.buf, | 665 request->socketcall_req.args.send.buf, |
| 648 request->socketcall_req.args.send.len); | 666 request->socketcall_req.args.send.len); |
| 649 if (rc < 0) { | 667 if (rc < 0) { |
| 668 Debug::elapsed(tm, __NR_socketcall, call); |
| 650 return -sys.my_errno; | 669 return -sys.my_errno; |
| 651 } else { | 670 } else { |
| 671 Debug::elapsed(tm, __NR_socketcall, call); |
| 652 return rc; | 672 return rc; |
| 653 } | 673 } |
| 654 } | 674 } |
| 655 | 675 |
| 656 // Simplify recv(), and recvfrom(), if there are simpler equivalent calls. | 676 // Simplify recv(), and recvfrom(), if there are simpler equivalent calls. |
| 657 // This allows us to occasionally replace them with calls to read(), which | 677 // This allows us to occasionally replace them with calls to read(), which |
| 658 // don't have to be forwarded to the trusted process. | 678 // don't have to be forwarded to the trusted process. |
| 659 // We cannot simplify recvmsg() to recvfrom(), recv() or read(), as we do | 679 // We cannot simplify recvmsg() to recvfrom(), recv() or read(), as we do |
| 660 // not know whether the caller needs us to set msg->msg_flags. | 680 // not know whether the caller needs us to set msg->msg_flags. |
| 661 if (call == SYS_RECVFROM && !request->socketcall_req.args.recvfrom.from) { | 681 if (call == SYS_RECVFROM && !request->socketcall_req.args.recvfrom.from) { |
| 662 // recvfrom() with a NULL address buffer is the same as recv() | 682 // recvfrom() with a NULL address buffer is the same as recv() |
| 663 call = SYS_RECV; | 683 call = SYS_RECV; |
| 664 } | 684 } |
| 665 if (call == SYS_RECV && !request->socketcall_req.args.recv.flags) { | 685 if (call == SYS_RECV && !request->socketcall_req.args.recv.flags) { |
| 666 // recv() with no flags is the same as read(), which is unrestricted | 686 // recv() with no flags is the same as read(), which is unrestricted |
| 667 // in seccomp mode. | 687 // in seccomp mode. |
| 668 Debug::message("Replaced socketcall() with call to read()"); | 688 Debug::message("Replaced socketcall() with call to read()"); |
| 669 ssize_t rc = sys.read(request->socketcall_req.args.recv.sockfd, | 689 ssize_t rc = sys.read(request->socketcall_req.args.recv.sockfd, |
| 670 request->socketcall_req.args.recv.buf, | 690 request->socketcall_req.args.recv.buf, |
| 671 request->socketcall_req.args.recv.len); | 691 request->socketcall_req.args.recv.len); |
| 672 if (rc < 0) { | 692 if (rc < 0) { |
| 693 Debug::elapsed(tm, __NR_socketcall, call); |
| 673 return -sys.my_errno; | 694 return -sys.my_errno; |
| 674 } else { | 695 } else { |
| 696 Debug::elapsed(tm, __NR_socketcall, call); |
| 675 return rc; | 697 return rc; |
| 676 } | 698 } |
| 677 } | 699 } |
| 678 | 700 |
| 679 // Fill in the rest of the request header. | 701 // Fill in the rest of the request header. |
| 680 request->sysnum = __NR_socketcall; | 702 request->sysnum = __NR_socketcall; |
| 681 request->cookie = cookie(); | 703 request->cookie = cookie(); |
| 682 request->socketcall_req.call = call; | 704 request->socketcall_req.call = call; |
| 683 request->socketcall_req.arg_ptr = args; | 705 request->socketcall_req.arg_ptr = args; |
| 684 int padding = sizeof(request->socketcall_req.args) - | 706 int padding = sizeof(request->socketcall_req.args) - |
| (...skipping 16 matching lines...) Expand all Loading... |
| 701 memcpy(request + 1, extraDataAddr, numExtraData); | 723 memcpy(request + 1, extraDataAddr, numExtraData); |
| 702 } | 724 } |
| 703 | 725 |
| 704 // Send request to trusted process and collect response from trusted thread. | 726 // Send request to trusted process and collect response from trusted thread. |
| 705 long rc; | 727 long rc; |
| 706 ssize_t len = sizeof(struct Request) + numExtraData; | 728 ssize_t len = sizeof(struct Request) + numExtraData; |
| 707 if (write(sys, processFdPub(), data, len) != len || | 729 if (write(sys, processFdPub(), data, len) != len || |
| 708 read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) { | 730 read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) { |
| 709 die("Failed to forward socketcall() request [sandbox]"); | 731 die("Failed to forward socketcall() request [sandbox]"); |
| 710 } | 732 } |
| 733 Debug::elapsed(tm, __NR_socketcall, call); |
| 711 return static_cast<int>(rc); | 734 return static_cast<int>(rc); |
| 712 } | 735 } |
| 713 | 736 |
| 714 bool Sandbox::process_socketcall(int parentMapsFd, int sandboxFd, | 737 bool Sandbox::process_socketcall(int parentMapsFd, int sandboxFd, |
| 715 int threadFdPub, int threadFd, | 738 int threadFdPub, int threadFd, |
| 716 SecureMem::Args* mem) { | 739 SecureMem::Args* mem) { |
| 717 // Read request | 740 // Read request |
| 718 SocketCall socketcall_req; | 741 SocketCall socketcall_req; |
| 719 SysCalls sys; | 742 SysCalls sys; |
| 720 if (read(sys, sandboxFd, &socketcall_req, sizeof(socketcall_req)) != | 743 if (read(sys, sandboxFd, &socketcall_req, sizeof(socketcall_req)) != |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1009 default: | 1032 default: |
| 1010 deny: | 1033 deny: |
| 1011 SecureMem::abandonSystemCall(threadFd, rc); | 1034 SecureMem::abandonSystemCall(threadFd, rc); |
| 1012 return false; | 1035 return false; |
| 1013 } | 1036 } |
| 1014 } | 1037 } |
| 1015 | 1038 |
| 1016 #endif | 1039 #endif |
| 1017 | 1040 |
| 1018 } // namespace | 1041 } // namespace |
| OLD | NEW |