OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/nacl/loader/nonsfi/nonsfi_sandbox.h" | 5 #include "components/nacl/loader/nonsfi/nonsfi_sandbox.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <linux/futex.h> | 9 #include <linux/futex.h> |
10 #include <linux/net.h> | 10 #include <linux/net.h> |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
54 // We allow following cases: | 54 // We allow following cases: |
55 // 1. F_SETFD + FD_CLOEXEC: libevent's epoll_init uses this. | 55 // 1. F_SETFD + FD_CLOEXEC: libevent's epoll_init uses this. |
56 // 2. F_GETFL: Used by SetNonBlocking in | 56 // 2. F_GETFL: Used by SetNonBlocking in |
57 // message_pump_libevent.cc and Channel::ChannelImpl::CreatePipe | 57 // message_pump_libevent.cc and Channel::ChannelImpl::CreatePipe |
58 // in ipc_channel_posix.cc. Note that the latter does not work | 58 // in ipc_channel_posix.cc. Note that the latter does not work |
59 // with EPERM. | 59 // with EPERM. |
60 // 3. F_SETFL: Used by evutil_make_socket_nonblocking in | 60 // 3. F_SETFL: Used by evutil_make_socket_nonblocking in |
61 // libevent and SetNonBlocking. As the latter mix O_NONBLOCK to | 61 // libevent and SetNonBlocking. As the latter mix O_NONBLOCK to |
62 // the return value of F_GETFL, so we need to allow O_ACCMODE in | 62 // the return value of F_GETFL, so we need to allow O_ACCMODE in |
63 // addition to O_NONBLOCK. | 63 // addition to O_NONBLOCK. |
64 const unsigned long denied_mask = ~(O_ACCMODE | O_NONBLOCK); | 64 const unsigned long kAllowedMask = O_ACCMODE | O_NONBLOCK; |
jln (very slow on Chromium)
2014/09/23 21:04:30
uint64 for consistency ?
mdempsky
2014/09/23 21:17:16
Done.
| |
65 return If((cmd == F_SETFD && long_arg == FD_CLOEXEC) || cmd == F_GETFL || | 65 return If((cmd == F_SETFD && long_arg == FD_CLOEXEC) || cmd == F_GETFL || |
66 (cmd == F_SETFL && (long_arg & denied_mask) == 0), | 66 (cmd == F_SETFL && (long_arg & ~kAllowedMask) == 0), |
67 Allow()).Else(CrashSIGSYS()); | 67 Allow()).Else(CrashSIGSYS()); |
68 } | 68 } |
69 | 69 |
70 ResultExpr RestrictClone() { | 70 ResultExpr RestrictClone() { |
71 // We allow clone only for new thread creation. | 71 // We allow clone only for new thread creation. |
72 const Arg<int> flags(0); | 72 const Arg<int> flags(0); |
73 return If(flags == (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | | 73 return If(flags == (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | |
74 CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS | | 74 CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS | |
75 CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID), | 75 CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID), |
76 Allow()).Else(CrashSIGSYSClone()); | 76 Allow()).Else(CrashSIGSYSClone()); |
77 } | 77 } |
78 | 78 |
79 ResultExpr RestrictFutexOperation() { | 79 ResultExpr RestrictFutexOperation() { |
80 // TODO(hamaji): Allow only FUTEX_PRIVATE_FLAG futexes. | 80 // TODO(hamaji): Allow only FUTEX_PRIVATE_FLAG futexes. |
81 const int kAllowedFutexFlags = FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME; | 81 const uint64_t kAllowedFutexFlags = FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME; |
82 const int kOperationMask = ~kAllowedFutexFlags; | |
83 const Arg<int> op(1); | 82 const Arg<int> op(1); |
84 return Switch(op & kOperationMask) | 83 return Switch(op & ~kAllowedFutexFlags) |
85 .CASES((FUTEX_WAIT, | 84 .CASES((FUTEX_WAIT, |
86 FUTEX_WAKE, | 85 FUTEX_WAKE, |
87 FUTEX_REQUEUE, | 86 FUTEX_REQUEUE, |
88 FUTEX_CMP_REQUEUE, | 87 FUTEX_CMP_REQUEUE, |
89 FUTEX_WAKE_OP, | 88 FUTEX_WAKE_OP, |
90 FUTEX_WAIT_BITSET, | 89 FUTEX_WAIT_BITSET, |
91 FUTEX_WAKE_BITSET), | 90 FUTEX_WAKE_BITSET), |
92 Allow()) | 91 Allow()) |
93 .Default(CrashSIGSYSFutex()); | 92 .Default(CrashSIGSYSFutex()); |
94 } | 93 } |
(...skipping 11 matching lines...) Expand all Loading... | |
106 const Arg<int> call(0); | 105 const Arg<int> call(0); |
107 return If(call == SYS_SOCKETPAIR || call == SYS_SHUTDOWN || | 106 return If(call == SYS_SOCKETPAIR || call == SYS_SHUTDOWN || |
108 call == SYS_SENDMSG || call == SYS_RECVMSG, | 107 call == SYS_SENDMSG || call == SYS_RECVMSG, |
109 Allow()).Else(CrashSIGSYS()); | 108 Allow()).Else(CrashSIGSYS()); |
110 } | 109 } |
111 #endif | 110 #endif |
112 | 111 |
113 ResultExpr RestrictMprotect() { | 112 ResultExpr RestrictMprotect() { |
114 // TODO(jln, keescook, drewry): Limit the use of mprotect by adding | 113 // TODO(jln, keescook, drewry): Limit the use of mprotect by adding |
115 // some features to linux kernel. | 114 // some features to linux kernel. |
116 const uint32_t denied_mask = ~(PROT_READ | PROT_WRITE | PROT_EXEC); | 115 const uint64_t kAllowedMask = PROT_READ | PROT_WRITE | PROT_EXEC; |
117 const Arg<int> prot(2); | 116 const Arg<int> prot(2); |
118 return If((prot & denied_mask) == 0, Allow()).Else(CrashSIGSYS()); | 117 return If((prot & ~kAllowedMask) == 0, Allow()).Else(CrashSIGSYS()); |
119 } | 118 } |
120 | 119 |
121 ResultExpr RestrictMmap() { | 120 ResultExpr RestrictMmap() { |
122 const uint32_t denied_flag_mask = ~(MAP_SHARED | MAP_PRIVATE | | 121 const uint64_t kAllowedFlagMask = |
123 MAP_ANONYMOUS | MAP_STACK | MAP_FIXED); | 122 MAP_SHARED | MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK | MAP_FIXED; |
124 // When PROT_EXEC is specified, IRT mmap of Non-SFI NaCl helper | 123 // When PROT_EXEC is specified, IRT mmap of Non-SFI NaCl helper |
125 // calls mmap without PROT_EXEC and then adds PROT_EXEC by mprotect, | 124 // calls mmap without PROT_EXEC and then adds PROT_EXEC by mprotect, |
126 // so we do not need to allow PROT_EXEC in mmap. | 125 // so we do not need to allow PROT_EXEC in mmap. |
127 const uint32_t denied_prot_mask = ~(PROT_READ | PROT_WRITE); | 126 const uint64_t kAllowedProtMask = PROT_READ | PROT_WRITE; |
128 const Arg<int> prot(2), flags(3); | 127 const Arg<int> prot(2), flags(3); |
129 return If((prot & denied_prot_mask) == 0 && (flags & denied_flag_mask) == 0, | 128 return If((prot & ~kAllowedProtMask) == 0 && (flags & ~kAllowedFlagMask) == 0, |
130 Allow()).Else(CrashSIGSYS()); | 129 Allow()).Else(CrashSIGSYS()); |
131 } | 130 } |
132 | 131 |
133 #if defined(__x86_64__) || defined(__arm__) | 132 #if defined(__x86_64__) || defined(__arm__) |
134 ResultExpr RestrictSocketpair() { | 133 ResultExpr RestrictSocketpair() { |
135 // Only allow AF_UNIX, PF_UNIX. Crash if anything else is seen. | 134 // Only allow AF_UNIX, PF_UNIX. Crash if anything else is seen. |
136 COMPILE_ASSERT(AF_UNIX == PF_UNIX, af_unix_pf_unix_different); | 135 COMPILE_ASSERT(AF_UNIX == PF_UNIX, af_unix_pf_unix_different); |
137 const Arg<int> domain(0); | 136 const Arg<int> domain(0); |
138 return If(domain == AF_UNIX, Allow()).Else(CrashSIGSYS()); | 137 return If(domain == AF_UNIX, Allow()).Else(CrashSIGSYS()); |
139 } | 138 } |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
306 scoped_ptr<sandbox::bpf_dsl::SandboxBPFDSLPolicy>( | 305 scoped_ptr<sandbox::bpf_dsl::SandboxBPFDSLPolicy>( |
307 new nacl::nonsfi::NaClNonSfiBPFSandboxPolicy())); | 306 new nacl::nonsfi::NaClNonSfiBPFSandboxPolicy())); |
308 if (!sandbox_is_initialized) | 307 if (!sandbox_is_initialized) |
309 return false; | 308 return false; |
310 RunSandboxSanityChecks(); | 309 RunSandboxSanityChecks(); |
311 return true; | 310 return true; |
312 } | 311 } |
313 | 312 |
314 } // namespace nonsfi | 313 } // namespace nonsfi |
315 } // namespace nacl | 314 } // namespace nacl |
OLD | NEW |