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

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

Issue 3225010: Pull seccomp-sandbox in via DEPS rather than using an in-tree copy... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 3 months 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/ioctl.cc ('k') | sandbox/linux/seccomp/library.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "debug.h"
6 #include "sandbox_impl.h"
7
8 namespace playground {
9
10 #ifndef IPC_PRIVATE
11 #define IPC_PRIVATE 0
12 #endif
13 #ifndef IPC_RMID
14 #define IPC_RMID 0
15 #endif
16 #ifndef IPC_64
17 #define IPC_64 256
18 #endif
19
20 #if defined(__NR_shmget)
21 void* Sandbox::sandbox_shmat(int shmid, const void* shmaddr, int shmflg) {
22 long long tm;
23 Debug::syscall(&tm, __NR_shmat, "Executing handler");
24
25 struct {
26 int sysnum;
27 long long cookie;
28 ShmAt shmat_req;
29 } __attribute__((packed)) request;
30 request.sysnum = __NR_shmat;
31 request.cookie = cookie();
32 request.shmat_req.shmid = shmid;
33 request.shmat_req.shmaddr = shmaddr;
34 request.shmat_req.shmflg = shmflg;
35
36 long rc;
37 SysCalls sys;
38 if (write(sys, processFdPub(), &request, sizeof(request)) !=
39 sizeof(request) ||
40 read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) {
41 die("Failed to forward shmat() request [sandbox]");
42 }
43 Debug::elapsed(tm, __NR_shmat);
44 return reinterpret_cast<void *>(rc);
45 }
46
47 long Sandbox::sandbox_shmctl(int shmid, int cmd, void* buf) {
48 long long tm;
49 Debug::syscall(&tm, __NR_shmctl, "Executing handler");
50
51 struct {
52 int sysnum;
53 long long cookie;
54 ShmCtl shmctl_req;
55 } __attribute__((packed)) request;
56 request.sysnum = __NR_shmctl;
57 request.cookie = cookie();
58 request.shmctl_req.shmid = shmid;
59 request.shmctl_req.cmd = cmd;
60 request.shmctl_req.buf = buf;
61
62 long rc;
63 SysCalls sys;
64 if (write(sys, processFdPub(), &request, sizeof(request)) !=
65 sizeof(request) ||
66 read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) {
67 die("Failed to forward shmctl() request [sandbox]");
68 }
69 Debug::elapsed(tm, __NR_shmctl);
70 return rc;
71 }
72
73 long Sandbox::sandbox_shmdt(const void* shmaddr) {
74 long long tm;
75 Debug::syscall(&tm, __NR_shmdt, "Executing handler");
76
77 struct {
78 int sysnum;
79 long long cookie;
80 ShmDt shmdt_req;
81 } __attribute__((packed)) request;
82 request.sysnum = __NR_shmdt;
83 request.cookie = cookie();
84 request.shmdt_req.shmaddr = shmaddr;
85
86 long rc;
87 SysCalls sys;
88 if (write(sys, processFdPub(), &request, sizeof(request)) !=
89 sizeof(request) ||
90 read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) {
91 die("Failed to forward shmdt() request [sandbox]");
92 }
93 Debug::elapsed(tm, __NR_shmdt);
94 return rc;
95 }
96
97 long Sandbox::sandbox_shmget(int key, size_t size, int shmflg) {
98 long long tm;
99 Debug::syscall(&tm, __NR_shmget, "Executing handler");
100
101 struct {
102 int sysnum;
103 long long cookie;
104 ShmGet shmget_req;
105 } __attribute__((packed)) request;
106 request.sysnum = __NR_shmget;
107 request.cookie = cookie();
108 request.shmget_req.key = key;
109 request.shmget_req.size = size;
110 request.shmget_req.shmflg = shmflg;
111
112 long rc;
113 SysCalls sys;
114 if (write(sys, processFdPub(), &request, sizeof(request)) !=
115 sizeof(request) ||
116 read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) {
117 die("Failed to forward shmget() request [sandbox]");
118 }
119 Debug::elapsed(tm, __NR_shmget);
120 return rc;
121 }
122
123 bool Sandbox::process_shmat(int parentMapsFd, int sandboxFd, int threadFdPub,
124 int threadFd, SecureMem::Args* mem) {
125 // Read request
126 ShmAt shmat_req;
127 SysCalls sys;
128 if (read(sys, sandboxFd, &shmat_req, sizeof(shmat_req)) !=
129 sizeof(shmat_req)) {
130 die("Failed to read parameters for shmat() [process]");
131 }
132
133 // We only allow attaching to the shm identifier that was returned by
134 // the most recent call to shmget(IPC_PRIVATE)
135 if (shmat_req.shmaddr || shmat_req.shmflg || shmat_req.shmid != mem->shmId) {
136 mem->shmId = -1;
137 SecureMem::abandonSystemCall(threadFd, -EINVAL);
138 return false;
139 }
140
141 mem->shmId = -1;
142 SecureMem::sendSystemCall(threadFdPub, false, -1, mem,
143 __NR_shmat, shmat_req.shmid, shmat_req.shmaddr,
144 shmat_req.shmflg);
145 return true;
146 }
147
148 bool Sandbox::process_shmctl(int parentMapsFd, int sandboxFd, int threadFdPub,
149 int threadFd, SecureMem::Args* mem) {
150 // Read request
151 ShmCtl shmctl_req;
152 SysCalls sys;
153 if (read(sys, sandboxFd, &shmctl_req, sizeof(shmctl_req)) !=
154 sizeof(shmctl_req)) {
155 die("Failed to read parameters for shmctl() [process]");
156 }
157
158 // The only shmctl() operation that we need to support is removal. This
159 // operation is generally safe.
160 if ((shmctl_req.cmd & ~(IPC_64 | IPC_RMID)) || shmctl_req.buf) {
161 mem->shmId = -1;
162 SecureMem::abandonSystemCall(threadFd, -EINVAL);
163 return false;
164 }
165
166 mem->shmId = -1;
167 SecureMem::sendSystemCall(threadFdPub, false, -1, mem,
168 __NR_shmctl, shmctl_req.shmid, shmctl_req.cmd,
169 shmctl_req.buf);
170 return true;
171 }
172
173 bool Sandbox::process_shmdt(int parentMapsFd, int sandboxFd, int threadFdPub,
174 int threadFd, SecureMem::Args* mem) {
175 // Read request
176 ShmDt shmdt_req;
177 SysCalls sys;
178 if (read(sys, sandboxFd, &shmdt_req, sizeof(shmdt_req)) !=
179 sizeof(shmdt_req)) {
180 die("Failed to read parameters for shmdt() [process]");
181 }
182
183 // Detaching shared memory segments it generally safe, but just in case
184 // of a kernel bug, we make sure that the address does not fall into any
185 // of the reserved memory regions.
186 ProtectedMap::const_iterator iter = protectedMap_.lower_bound(
187 (void *)shmdt_req.shmaddr);
188 if (iter != protectedMap_.begin()) {
189 --iter;
190 }
191 for (; iter != protectedMap_.end() && iter->first <= shmdt_req.shmaddr;
192 ++iter){
193 if (shmdt_req.shmaddr < reinterpret_cast<void *>(
194 reinterpret_cast<char *>(iter->first) + iter->second) &&
195 shmdt_req.shmaddr >= iter->first) {
196 mem->shmId = -1;
197 SecureMem::abandonSystemCall(threadFd, -EINVAL);
198 return false;
199 }
200 }
201
202 mem->shmId = -1;
203 SecureMem::sendSystemCall(threadFdPub, false, -1, mem,
204 __NR_shmdt, shmdt_req.shmaddr);
205 return true;
206 }
207
208 bool Sandbox::process_shmget(int parentMapsFd, int sandboxFd, int threadFdPub,
209 int threadFd, SecureMem::Args* mem) {
210 // Read request
211 ShmGet shmget_req;
212 SysCalls sys;
213 if (read(sys, sandboxFd, &shmget_req, sizeof(shmget_req)) !=
214 sizeof(shmget_req)) {
215 die("Failed to read parameters for shmget() [process]");
216 }
217
218 // We do not want to allow the sandboxed application to access arbitrary
219 // shared memory regions. We only allow it to access regions that it
220 // created itself.
221 if (shmget_req.key != IPC_PRIVATE || shmget_req.shmflg & ~0777) {
222 mem->shmId = -1;
223 SecureMem::abandonSystemCall(threadFd, -EINVAL);
224 return false;
225 }
226
227 mem->shmId = -1;
228 SecureMem::sendSystemCall(threadFdPub, false, -1, mem,
229 __NR_shmget, shmget_req.key, shmget_req.size,
230 shmget_req.shmflg);
231 return true;
232 }
233 #endif
234
235 #if defined(__NR_ipc)
236 #ifndef SHMAT
237 #define SHMAT 21
238 #endif
239 #ifndef SHMDT
240 #define SHMDT 22
241 #endif
242 #ifndef SHMGET
243 #define SHMGET 23
244 #endif
245 #ifndef SHMCTL
246 #define SHMCTL 24
247 #endif
248
249 long Sandbox::sandbox_ipc(unsigned call, int first, int second, int third,
250 void* ptr, long fifth) {
251 long long tm;
252 Debug::syscall(&tm, __NR_ipc, "Executing handler", call);
253 struct {
254 int sysnum;
255 long long cookie;
256 IPC ipc_req;
257 } __attribute__((packed)) request;
258 request.sysnum = __NR_ipc;
259 request.cookie = cookie();
260 request.ipc_req.call = call;
261 request.ipc_req.first = first;
262 request.ipc_req.second = second;
263 request.ipc_req.third = third;
264 request.ipc_req.ptr = ptr;
265 request.ipc_req.fifth = fifth;
266
267 long rc;
268 SysCalls sys;
269 if (write(sys, processFdPub(), &request, sizeof(request)) !=
270 sizeof(request) ||
271 read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) {
272 die("Failed to forward ipc() request [sandbox]");
273 }
274 Debug::elapsed(tm, __NR_ipc, call);
275 return rc;
276 }
277
278 bool Sandbox::process_ipc(int parentMapsFd, int sandboxFd, int threadFdPub,
279 int threadFd, SecureMem::Args* mem) {
280 // Read request
281 IPC ipc_req;
282 SysCalls sys;
283 if (read(sys, sandboxFd, &ipc_req, sizeof(ipc_req)) != sizeof(ipc_req)) {
284 die("Failed to read parameters for ipc() [process]");
285 }
286
287 // We do not support all of the SysV IPC calls. In fact, we only support
288 // the minimum feature set necessary for Chrome's renderers to share memory
289 // with the X server.
290 switch (ipc_req.call) {
291 case SHMAT: {
292 // We only allow attaching to the shm identifier that was returned by
293 // the most recent call to shmget(IPC_PRIVATE)
294 if (ipc_req.ptr || ipc_req.second || ipc_req.first != mem->shmId) {
295 goto deny;
296 }
297 accept:
298 mem->shmId = -1;
299 SecureMem::sendSystemCall(threadFdPub, false, -1, mem,
300 __NR_ipc, ipc_req.call, ipc_req.first,
301 ipc_req.second, ipc_req.third, ipc_req.ptr,
302 ipc_req.fifth);
303 return true;
304 }
305 case SHMCTL:
306 // The only shmctl() operation that we need to support is removal. This
307 // operation is generally safe.
308 if ((ipc_req.second & ~(IPC_64 | IPC_RMID)) || ipc_req.ptr) {
309 goto deny;
310 } else {
311 goto accept;
312 }
313 case SHMDT: {
314 // Detaching shared memory segments it generally safe, but just in case
315 // of a kernel bug, we make sure that the address does not fall into any
316 // of the reserved memory regions.
317 ProtectedMap::const_iterator iter = protectedMap_.lower_bound(
318 (void *)ipc_req.ptr);
319 if (iter != protectedMap_.begin()) {
320 --iter;
321 }
322 for (; iter != protectedMap_.end() && iter->first <=ipc_req.ptr; ++iter){
323 if (ipc_req.ptr < reinterpret_cast<void *>(
324 reinterpret_cast<char *>(iter->first) + iter->second) &&
325 ipc_req.ptr >= iter->first) {
326 goto deny;
327 }
328 }
329 goto accept;
330 }
331 case SHMGET:
332 // We do not want to allow the sandboxed application to access arbitrary
333 // shared memory regions. We only allow it to access regions that it
334 // created itself.
335 if (ipc_req.first != IPC_PRIVATE || ipc_req.third & ~0777) {
336 goto deny;
337 } else {
338 goto accept;
339 }
340 default:
341 // Other than SysV shared memory, we do not actually need to support any
342 // other SysV IPC calls.
343 deny:
344 mem->shmId = -1;
345 SecureMem::abandonSystemCall(threadFd, -EINVAL);
346 return false;
347 }
348 }
349 #endif
350
351 } // namespace
OLDNEW
« no previous file with comments | « sandbox/linux/seccomp/ioctl.cc ('k') | sandbox/linux/seccomp/library.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698