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

Side by Side Diff: sandbox/linux/seccomp/socketcall.cc

Issue 371047: Allow the seccomp sandbox to be enabled, even if the suid sandbox has... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 1 month 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
« no previous file with comments | « sandbox/linux/seccomp/securemem.cc ('k') | sandbox/linux/seccomp/stat.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
1 #include "debug.h" 1 #include "debug.h"
2 #include "sandbox_impl.h" 2 #include "sandbox_impl.h"
3 3
4 namespace playground { 4 namespace playground {
5 5
6 #if defined(__NR_socket) 6 #if defined(__NR_socket)
7 7
8 ssize_t Sandbox::sandbox_recvfrom(int sockfd, void* buf, size_t len, int flags, 8 ssize_t Sandbox::sandbox_recvfrom(int sockfd, void* buf, size_t len, int flags,
9 void* from, socklen_t* fromlen) { 9 void* from, socklen_t* fromlen) {
10 Debug::syscall(__NR_recvfrom, "Executing handler"); 10 Debug::syscall(__NR_recvfrom, "Executing handler");
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 long rc; 197 long rc;
198 SysCalls sys; 198 SysCalls sys;
199 if (write(sys, processFdPub(), &request, sizeof(request)) != 199 if (write(sys, processFdPub(), &request, sizeof(request)) !=
200 sizeof(request) || 200 sizeof(request) ||
201 read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) { 201 read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) {
202 die("Failed to forward getsockopt() request [sandbox]"); 202 die("Failed to forward getsockopt() request [sandbox]");
203 } 203 }
204 return static_cast<int>(rc); 204 return static_cast<int>(rc);
205 } 205 }
206 206
207 bool Sandbox::process_recvfrom(int parentProc, int sandboxFd, int threadFdPub, 207 bool Sandbox::process_recvfrom(int parentMapsFd, int sandboxFd,
208 int threadFd, SecureMem::Args* mem) { 208 int threadFdPub, int threadFd,
209 SecureMem::Args* mem) {
209 // Read request 210 // Read request
210 RecvFrom recvfrom_req; 211 RecvFrom recvfrom_req;
211 SysCalls sys; 212 SysCalls sys;
212 if (read(sys, sandboxFd, &recvfrom_req, sizeof(recvfrom_req)) != 213 if (read(sys, sandboxFd, &recvfrom_req, sizeof(recvfrom_req)) !=
213 sizeof(recvfrom_req)) { 214 sizeof(recvfrom_req)) {
214 die("Failed to read parameters for recvfrom() [process]"); 215 die("Failed to read parameters for recvfrom() [process]");
215 } 216 }
216 217
217 // Unsupported flag encountered. Deny the call. 218 // Unsupported flag encountered. Deny the call.
218 if (recvfrom_req.flags & 219 if (recvfrom_req.flags &
219 ~(MSG_DONTWAIT|MSG_OOB|MSG_PEEK|MSG_TRUNC|MSG_WAITALL)) { 220 ~(MSG_DONTWAIT|MSG_OOB|MSG_PEEK|MSG_TRUNC|MSG_WAITALL)) {
220 SecureMem::abandonSystemCall(threadFd, -EINVAL); 221 SecureMem::abandonSystemCall(threadFd, -EINVAL);
221 return false; 222 return false;
222 } 223 }
223 224
224 // While we do not anticipate any particular need to receive data on 225 // While we do not anticipate any particular need to receive data on
225 // unconnected sockets, there is no particular risk in doing so. 226 // unconnected sockets, there is no particular risk in doing so.
226 SecureMem::sendSystemCall(threadFdPub, false, -1, mem, 227 SecureMem::sendSystemCall(threadFdPub, false, -1, mem,
227 __NR_recvfrom, recvfrom_req.sockfd, 228 __NR_recvfrom, recvfrom_req.sockfd,
228 recvfrom_req.buf, recvfrom_req.len, 229 recvfrom_req.buf, recvfrom_req.len,
229 recvfrom_req.flags, recvfrom_req.from, 230 recvfrom_req.flags, recvfrom_req.from,
230 recvfrom_req.fromlen); 231 recvfrom_req.fromlen);
231 return true; 232 return true;
232 } 233 }
233 234
234 bool Sandbox::process_recvmsg(int parentProc, int sandboxFd, int threadFdPub, 235 bool Sandbox::process_recvmsg(int parentMapsFd, int sandboxFd, int threadFdPub,
235 int threadFd, SecureMem::Args* mem) { 236 int threadFd, SecureMem::Args* mem) {
236 // Read request 237 // Read request
237 RecvMsg recvmsg_req; 238 RecvMsg recvmsg_req;
238 SysCalls sys; 239 SysCalls sys;
239 if (read(sys, sandboxFd, &recvmsg_req, sizeof(recvmsg_req)) != 240 if (read(sys, sandboxFd, &recvmsg_req, sizeof(recvmsg_req)) !=
240 sizeof(recvmsg_req)) { 241 sizeof(recvmsg_req)) {
241 die("Failed to read parameters for recvmsg() [process]"); 242 die("Failed to read parameters for recvmsg() [process]");
242 } 243 }
243 244
244 // Unsupported flag encountered. Deny the call. 245 // Unsupported flag encountered. Deny the call.
245 if (recvmsg_req.flags & 246 if (recvmsg_req.flags &
246 ~(MSG_DONTWAIT|MSG_OOB|MSG_PEEK|MSG_TRUNC|MSG_WAITALL)) { 247 ~(MSG_DONTWAIT|MSG_OOB|MSG_PEEK|MSG_TRUNC|MSG_WAITALL)) {
247 SecureMem::abandonSystemCall(threadFd, -EINVAL); 248 SecureMem::abandonSystemCall(threadFd, -EINVAL);
248 return false; 249 return false;
249 } 250 }
250 251
251 // Receiving messages is general not security critical. 252 // Receiving messages is general not security critical.
252 SecureMem::sendSystemCall(threadFdPub, false, -1, mem, 253 SecureMem::sendSystemCall(threadFdPub, false, -1, mem,
253 __NR_recvmsg, recvmsg_req.sockfd, 254 __NR_recvmsg, recvmsg_req.sockfd,
254 recvmsg_req.msg, recvmsg_req.flags); 255 recvmsg_req.msg, recvmsg_req.flags);
255 return true; 256 return true;
256 } 257 }
257 258
258 bool Sandbox::process_sendmsg(int parentProc, int sandboxFd, int threadFdPub, 259 bool Sandbox::process_sendmsg(int parentMapsFd, int sandboxFd, int threadFdPub,
259 int threadFd, SecureMem::Args* mem) { 260 int threadFd, SecureMem::Args* mem) {
260 // Read request 261 // Read request
261 struct { 262 struct {
262 SendMsg sendmsg_req; 263 SendMsg sendmsg_req;
263 struct msghdr msg; 264 struct msghdr msg;
264 } __attribute__((packed)) data; 265 } __attribute__((packed)) data;
265 SysCalls sys; 266 SysCalls sys;
266 if (read(sys, sandboxFd, &data, sizeof(data)) != sizeof(data)) { 267 if (read(sys, sandboxFd, &data, sizeof(data)) != sizeof(data)) {
267 die("Failed to read parameters for sendmsg() [process]"); 268 die("Failed to read parameters for sendmsg() [process]");
268 } 269 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 do { 301 do {
301 if (cmsg->cmsg_level != SOL_SOCKET || 302 if (cmsg->cmsg_level != SOL_SOCKET ||
302 cmsg->cmsg_type != SCM_RIGHTS) { 303 cmsg->cmsg_type != SCM_RIGHTS) {
303 goto deny; 304 goto deny;
304 } 305 }
305 } while ((cmsg = CMSG_NXTHDR(&data.msg, cmsg)) != NULL); 306 } while ((cmsg = CMSG_NXTHDR(&data.msg, cmsg)) != NULL);
306 } 307 }
307 308
308 // This must be a locked system call, because we have to ensure that the 309 // This must be a locked system call, because we have to ensure that the
309 // untrusted code does not tamper with the msghdr after we have examined it. 310 // untrusted code does not tamper with the msghdr after we have examined it.
310 SecureMem::lockSystemCall(parentProc, mem); 311 SecureMem::lockSystemCall(parentMapsFd, mem);
311 if (sizeof(extra) > 0) { 312 if (sizeof(extra) > 0) {
312 if (data.msg.msg_namelen > 0) { 313 if (data.msg.msg_namelen > 0) {
313 data.msg.msg_name = mem->pathname + sizeof(struct msghdr); 314 data.msg.msg_name = mem->pathname + sizeof(struct msghdr);
314 } 315 }
315 if (data.msg.msg_controllen > 0) { 316 if (data.msg.msg_controllen > 0) {
316 data.msg.msg_control = mem->pathname + sizeof(struct msghdr) + 317 data.msg.msg_control = mem->pathname + sizeof(struct msghdr) +
317 data.msg.msg_namelen; 318 data.msg.msg_namelen;
318 } 319 }
319 memcpy(mem->pathname + sizeof(struct msghdr), extra, sizeof(extra)); 320 memcpy(mem->pathname + sizeof(struct msghdr), extra, sizeof(extra));
320 } 321 }
321 memcpy(mem->pathname, &data.msg, sizeof(struct msghdr)); 322 memcpy(mem->pathname, &data.msg, sizeof(struct msghdr));
322 SecureMem::sendSystemCall(threadFdPub, true, parentProc, mem, 323 SecureMem::sendSystemCall(threadFdPub, true, parentMapsFd, mem,
323 __NR_sendmsg, data.sendmsg_req.sockfd, 324 __NR_sendmsg, data.sendmsg_req.sockfd,
324 mem->pathname - (char*)mem + (char*)mem->self, 325 mem->pathname - (char*)mem + (char*)mem->self,
325 data.sendmsg_req.flags); 326 data.sendmsg_req.flags);
326 return true; 327 return true;
327 } 328 }
328 329
329 bool Sandbox::process_sendto(int parentProc, int sandboxFd, int threadFdPub, 330 bool Sandbox::process_sendto(int parentMapsFd, int sandboxFd, int threadFdPub,
330 int threadFd, SecureMem::Args* mem) { 331 int threadFd, SecureMem::Args* mem) {
331 // Read request 332 // Read request
332 SendTo sendto_req; 333 SendTo sendto_req;
333 SysCalls sys; 334 SysCalls sys;
334 if (read(sys, sandboxFd, &sendto_req, sizeof(sendto_req)) != 335 if (read(sys, sandboxFd, &sendto_req, sizeof(sendto_req)) !=
335 sizeof(sendto_req)) { 336 sizeof(sendto_req)) {
336 die("Failed to read parameters for sendto() [process]"); 337 die("Failed to read parameters for sendto() [process]");
337 } 338 }
338 339
339 // The sandbox does not allow sending to arbitrary addresses. 340 // The sandbox does not allow sending to arbitrary addresses.
(...skipping 12 matching lines...) Expand all
352 // Sending data on a connected socket is similar to calling write(). 353 // Sending data on a connected socket is similar to calling write().
353 // Allow it. 354 // Allow it.
354 SecureMem::sendSystemCall(threadFdPub, false, -1, mem, 355 SecureMem::sendSystemCall(threadFdPub, false, -1, mem,
355 __NR_sendto, sendto_req.sockfd, 356 __NR_sendto, sendto_req.sockfd,
356 sendto_req.buf, sendto_req.len, 357 sendto_req.buf, sendto_req.len,
357 sendto_req.flags, sendto_req.to, 358 sendto_req.flags, sendto_req.to,
358 sendto_req.tolen); 359 sendto_req.tolen);
359 return true; 360 return true;
360 } 361 }
361 362
362 bool Sandbox::process_setsockopt(int parentProc, int sandboxFd, 363 bool Sandbox::process_setsockopt(int parentMapsFd, int sandboxFd,
363 int threadFdPub, int threadFd, 364 int threadFdPub, int threadFd,
364 SecureMem::Args* mem) { 365 SecureMem::Args* mem) {
365 // Read request 366 // Read request
366 SetSockOpt setsockopt_req; 367 SetSockOpt setsockopt_req;
367 SysCalls sys; 368 SysCalls sys;
368 if (read(sys, sandboxFd, &setsockopt_req, sizeof(setsockopt_req)) != 369 if (read(sys, sandboxFd, &setsockopt_req, sizeof(setsockopt_req)) !=
369 sizeof(setsockopt_req)) { 370 sizeof(setsockopt_req)) {
370 die("Failed to read parameters for setsockopt() [process]"); 371 die("Failed to read parameters for setsockopt() [process]");
371 } 372 }
372 373
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 break; 417 break;
417 } 418 }
418 break; 419 break;
419 default: 420 default:
420 break; 421 break;
421 } 422 }
422 SecureMem::abandonSystemCall(threadFd, -EINVAL); 423 SecureMem::abandonSystemCall(threadFd, -EINVAL);
423 return false; 424 return false;
424 } 425 }
425 426
426 bool Sandbox::process_getsockopt(int parentProc, int sandboxFd, 427 bool Sandbox::process_getsockopt(int parentMapsFd, int sandboxFd,
427 int threadFdPub, int threadFd, 428 int threadFdPub, int threadFd,
428 SecureMem::Args* mem) { 429 SecureMem::Args* mem) {
429 // Read request 430 // Read request
430 GetSockOpt getsockopt_req; 431 GetSockOpt getsockopt_req;
431 SysCalls sys; 432 SysCalls sys;
432 if (read(sys, sandboxFd, &getsockopt_req, sizeof(getsockopt_req)) != 433 if (read(sys, sandboxFd, &getsockopt_req, sizeof(getsockopt_req)) !=
433 sizeof(getsockopt_req)) { 434 sizeof(getsockopt_req)) {
434 die("Failed to read parameters for getsockopt() [process]"); 435 die("Failed to read parameters for getsockopt() [process]");
435 } 436 }
436 437
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 // Send request to trusted process and collect response from trusted thread. 700 // Send request to trusted process and collect response from trusted thread.
700 long rc; 701 long rc;
701 ssize_t len = sizeof(struct Request) + numExtraData; 702 ssize_t len = sizeof(struct Request) + numExtraData;
702 if (write(sys, processFdPub(), data, len) != len || 703 if (write(sys, processFdPub(), data, len) != len ||
703 read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) { 704 read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) {
704 die("Failed to forward socketcall() request [sandbox]"); 705 die("Failed to forward socketcall() request [sandbox]");
705 } 706 }
706 return static_cast<int>(rc); 707 return static_cast<int>(rc);
707 } 708 }
708 709
709 bool Sandbox::process_socketcall(int parentProc, int sandboxFd, 710 bool Sandbox::process_socketcall(int parentMapsFd, int sandboxFd,
710 int threadFdPub, int threadFd, 711 int threadFdPub, int threadFd,
711 SecureMem::Args* mem) { 712 SecureMem::Args* mem) {
712 // Read request 713 // Read request
713 SocketCall socketcall_req; 714 SocketCall socketcall_req;
714 SysCalls sys; 715 SysCalls sys;
715 if (read(sys, sandboxFd, &socketcall_req, sizeof(socketcall_req)) != 716 if (read(sys, sandboxFd, &socketcall_req, sizeof(socketcall_req)) !=
716 sizeof(socketcall_req)) { 717 sizeof(socketcall_req)) {
717 die("Failed to read parameters for socketcall() [process]"); 718 die("Failed to read parameters for socketcall() [process]");
718 } 719 }
719 720
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
817 goto deny; 818 goto deny;
818 } 819 }
819 // Sending data on a connected socket is similar to calling write(). 820 // Sending data on a connected socket is similar to calling write().
820 // Allow it. 821 // Allow it.
821 822
822 accept_complex: 823 accept_complex:
823 // The parameter block contains potentially security critical information 824 // The parameter block contains potentially security critical information
824 // that should not be tampered with after it has been inspected. Copy it 825 // that should not be tampered with after it has been inspected. Copy it
825 // into the write-protected securely shared memory before telling the 826 // into the write-protected securely shared memory before telling the
826 // trusted thread to execute the socket call. 827 // trusted thread to execute the socket call.
827 SecureMem::lockSystemCall(parentProc, mem); 828 SecureMem::lockSystemCall(parentMapsFd, mem);
828 memcpy(mem->pathname, &socketcall_req.args, sizeof(socketcall_req.args)); 829 memcpy(mem->pathname, &socketcall_req.args, sizeof(socketcall_req.args));
829 SecureMem::sendSystemCall(threadFdPub, true, parentProc, mem, 830 SecureMem::sendSystemCall(threadFdPub, true, parentMapsFd, mem,
830 __NR_socketcall, socketcall_req.call, 831 __NR_socketcall, socketcall_req.call,
831 mem->pathname - (char*)mem + (char*)mem->self); 832 mem->pathname - (char*)mem + (char*)mem->self);
832 return true; 833 return true;
833 case SYS_RECVFROM: 834 case SYS_RECVFROM:
834 // While we do not anticipate any particular need to receive data on 835 // While we do not anticipate any particular need to receive data on
835 // unconnected sockets, there is no particular risk in doing so. 836 // unconnected sockets, there is no particular risk in doing so.
836 // Fall through 837 // Fall through
837 case SYS_RECV: 838 case SYS_RECV:
838 if (socketcall_req.args.recv.flags & 839 if (socketcall_req.args.recv.flags &
839 ~(MSG_DONTWAIT|MSG_OOB|MSG_PEEK|MSG_TRUNC|MSG_WAITALL)) { 840 ~(MSG_DONTWAIT|MSG_OOB|MSG_PEEK|MSG_TRUNC|MSG_WAITALL)) {
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
963 if (cmsg->cmsg_level != SOL_SOCKET || 964 if (cmsg->cmsg_level != SOL_SOCKET ||
964 cmsg->cmsg_type != SCM_RIGHTS) { 965 cmsg->cmsg_type != SCM_RIGHTS) {
965 goto deny; 966 goto deny;
966 } 967 }
967 } while ((cmsg = CMSG_NXTHDR(msg, cmsg)) != NULL); 968 } while ((cmsg = CMSG_NXTHDR(msg, cmsg)) != NULL);
968 } 969 }
969 970
970 // This must be a locked system call, because we have to ensure that 971 // This must be a locked system call, because we have to ensure that
971 // the untrusted code does not tamper with the msghdr after we have 972 // the untrusted code does not tamper with the msghdr after we have
972 // examined it. 973 // examined it.
973 SecureMem::lockSystemCall(parentProc, mem); 974 SecureMem::lockSystemCall(parentMapsFd, mem);
974 socketcall_req.args.sendmsg.msg = 975 socketcall_req.args.sendmsg.msg =
975 reinterpret_cast<struct msghdr*>(mem->pathname + 976 reinterpret_cast<struct msghdr*>(mem->pathname +
976 sizeof(socketcall_req.args) - 977 sizeof(socketcall_req.args) -
977 (char*)mem + (char*)mem->self); 978 (char*)mem + (char*)mem->self);
978 memcpy(mem->pathname, &socketcall_req.args, sizeof(socketcall_req.args)); 979 memcpy(mem->pathname, &socketcall_req.args, sizeof(socketcall_req.args));
979 if (numSendmsgExtra) { 980 if (numSendmsgExtra) {
980 if (msg->msg_namelen > 0) { 981 if (msg->msg_namelen > 0) {
981 msg->msg_name = const_cast<struct msghdr*>( 982 msg->msg_name = const_cast<struct msghdr*>(
982 socketcall_req.args.sendmsg.msg) + 1; 983 socketcall_req.args.sendmsg.msg) + 1;
983 } 984 }
984 if (msg->msg_controllen > 0) { 985 if (msg->msg_controllen > 0) {
985 msg->msg_control = (char *)( 986 msg->msg_control = (char *)(
986 socketcall_req.args.sendmsg.msg + 1) + msg->msg_namelen; 987 socketcall_req.args.sendmsg.msg + 1) + msg->msg_namelen;
987 } 988 }
988 memcpy(mem->pathname + sizeof(socketcall_req.args) + sizeof(*msg), 989 memcpy(mem->pathname + sizeof(socketcall_req.args) + sizeof(*msg),
989 sendmsgExtra, numSendmsgExtra); 990 sendmsgExtra, numSendmsgExtra);
990 } 991 }
991 memcpy(mem->pathname + sizeof(socketcall_req.args), msg, sizeof(*msg)); 992 memcpy(mem->pathname + sizeof(socketcall_req.args), msg, sizeof(*msg));
992 SecureMem::sendSystemCall(threadFdPub, true, parentProc, mem, 993 SecureMem::sendSystemCall(threadFdPub, true, parentMapsFd, mem,
993 __NR_socketcall, socketcall_req.call, 994 __NR_socketcall, socketcall_req.call,
994 mem->pathname - (char*)mem + (char*)mem->self); 995 mem->pathname - (char*)mem + (char*)mem->self);
995 return true; 996 return true;
996 } 997 }
997 case SYS_RECVMSG: 998 case SYS_RECVMSG:
998 // Receiving messages is general not security critical. 999 // Receiving messages is general not security critical.
999 if (socketcall_req.args.recvmsg.flags & 1000 if (socketcall_req.args.recvmsg.flags &
1000 ~(MSG_DONTWAIT|MSG_OOB|MSG_PEEK|MSG_TRUNC|MSG_WAITALL)) { 1001 ~(MSG_DONTWAIT|MSG_OOB|MSG_PEEK|MSG_TRUNC|MSG_WAITALL)) {
1001 goto deny; 1002 goto deny;
1002 } 1003 }
1003 goto accept_complex; 1004 goto accept_complex;
1004 default: 1005 default:
1005 deny: 1006 deny:
1006 SecureMem::abandonSystemCall(threadFd, rc); 1007 SecureMem::abandonSystemCall(threadFd, rc);
1007 return false; 1008 return false;
1008 } 1009 }
1009 } 1010 }
1010 1011
1011 #endif 1012 #endif
1012 1013
1013 } // namespace 1014 } // namespace
OLDNEW
« no previous file with comments | « sandbox/linux/seccomp/securemem.cc ('k') | sandbox/linux/seccomp/stat.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698