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

Side by Side Diff: src/trusted/desc/linux/nacl_desc_sysv_shm.c

Issue 298443002: Remove unused support for SysV shared memory (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: Created 6 years, 7 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 | « src/trusted/desc/linux/nacl_desc_sysv_shm.h ('k') | src/trusted/desc/nacl_desc_base.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 /*
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6
7 /*
8 * NaCl Service Runtime. Transferrable shared memory objects.
9 */
10
11 #include "native_client/src/include/portability.h"
12 #include "native_client/src/include/nacl_platform.h"
13
14 #include <errno.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <sys/types.h>
18 #include <sys/shm.h>
19
20 #include "native_client/src/trusted/desc/nacl_desc_base.h"
21 #include "native_client/src/trusted/desc/nacl_desc_effector.h"
22 #include "native_client/src/trusted/desc/linux/nacl_desc_sysv_shm.h"
23
24 #include "native_client/src/shared/platform/nacl_find_addrsp.h"
25 #include "native_client/src/shared/platform/nacl_log.h"
26 #include "native_client/src/shared/platform/nacl_sync_checked.h"
27
28 #include "native_client/src/trusted/service_runtime/internal_errno.h"
29 #include "native_client/src/trusted/service_runtime/nacl_config.h"
30 #include "native_client/src/trusted/service_runtime/include/bits/mman.h"
31 #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
32 #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h"
33 #include "native_client/src/trusted/service_runtime/include/sys/stat.h"
34 #include "native_client/src/trusted/service_runtime/sel_util.h"
35
36
37 #if !defined(SIZE_T_MAX)
38 # define SIZE_T_MAX (~((size_t) 0))
39 #endif
40
41 /*
42 * This file contains the implementation of the NaClDescSysvShm
43 * subclass of NaClDesc.
44 *
45 * NaClDescSysvShm is the subclass that wraps SysV shared memory descriptors.
46 *
47 * Support for SysV shared memory descriptors is much more restricted than
48 * for other types of descriptors. In particular:
49 * 1) NaCl provides no method for untrusted creation of SysV shared memory.
50 * 2) Importing does not confer ownership of the descriptor, and hence
51 * we do not do the shmctl(IPC_RMID) to close it. The lifetime of the
52 * descriptor is controlled by the X server that created it, and returned
53 * it for use by Chrome.
54 */
55
56 static int NaClDescSysvShmSubclassCtorIntern(struct NaClDescSysvShm *self,
57 int id,
58 nacl_off64_t size,
59 int rmid_in_dtor) {
60 struct NaClDesc *basep = (struct NaClDesc *) self;
61
62 /*
63 * off_t is signed, but size_t is not; historically size_t is for
64 * sizeof and similar, and off_t is also used for stat structure
65 * st_size member. This runtime test detects large object sizes
66 * that are silently converted to negative values. Additionally,
67 * the size must be a multiple of 4K.
68 */
69 basep->base.vtbl = (struct NaClRefCountVtbl const *) NULL;
70 if ((size_t) size != NaClRoundPage((size_t) size)
71 || size < 0
72 || SIZE_T_MAX < (uint64_t) size) {
73 return 0;
74 }
75
76 self->id = id;
77 self->size = size;
78 self->rmid_in_dtor = rmid_in_dtor;
79 basep->base.vtbl = (struct NaClRefCountVtbl const *) &kNaClDescSysvShmVtbl;
80 return 1;
81 }
82
83 static int NaClDescSysvShmCtorIntern(struct NaClDescSysvShm *self,
84 int id,
85 nacl_off64_t size,
86 int rmid_in_dtor) {
87 struct NaClDesc *basep = (struct NaClDesc *) self;
88 int rv;
89
90 NACL_VTBL(NaClRefCount, self) = (struct NaClRefCountVtbl const *) NULL;
91
92 if (!NaClDescCtor(basep)) {
93 return 0;
94 }
95 rv = NaClDescSysvShmSubclassCtorIntern(self, id, size, rmid_in_dtor);
96 if (!rv) {
97 (*NACL_VTBL(NaClRefCount, self)->Dtor)((struct NaClRefCount *) self);
98 }
99 (*NACL_VTBL(NaClDesc, basep)->SetFlags)(basep, NACL_ABI_O_RDWR);
100 return rv;
101 }
102
103 int NaClDescSysvShmImportSubclassCtor(struct NaClDescSysvShm *self,
104 int id,
105 nacl_off64_t size) {
106 return NaClDescSysvShmSubclassCtorIntern(self, id, size, 0);
107 }
108
109 int NaClDescSysvShmImportCtor(struct NaClDescSysvShm *self,
110 int id,
111 nacl_off64_t size) {
112 return NaClDescSysvShmCtorIntern(self, id, size, 0);
113 }
114
115 /*
116 * Creates a NaClDesc containing a new shared memory region.
117 */
118 int NaClDescSysvShmCtor(struct NaClDescSysvShm *self,
119 nacl_off64_t size) {
120 int id;
121 int retval;
122
123 if (size < 0 || SIZE_T_MAX < (uint64_t) size) {
124 return 0;
125 }
126 /* Create the region. */
127 id = shmget(IPC_PRIVATE,
128 (int) size,
129 IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR);
130 if (-1 == id) {
131 return 0;
132 }
133 /* Construct the descriptor. */
134 retval = NaClDescSysvShmCtorIntern(self, id, size, 1);
135 /* If the constructor failed, mark the region for freeing. */
136 if (0 == retval) {
137 (void) shmctl(id, IPC_RMID, NULL);
138 return 0;
139 }
140 /* Return success. */
141 return 1;
142 }
143
144 static void NaClDescSysvShmDtor(struct NaClRefCount *vself) {
145 struct NaClDescSysvShm *self = (struct NaClDescSysvShm *) vself;
146
147 /*
148 * Importing does NOT confer ownership of the id. Hence the Dtor does not
149 * do the shmctl(IPC_RMID).
150 */
151 if (self->rmid_in_dtor) {
152 (void) shmctl(self->id, IPC_RMID, NULL);
153 }
154 /* NACL_INVALID_HANDLE is also an invalid id for shmat. */
155 self->id = NACL_INVALID_HANDLE;
156 vself->vtbl = (struct NaClRefCountVtbl const *) &kNaClDescVtbl;
157 (*vself->vtbl->Dtor)(vself);
158 }
159
160 /*
161 * For now, we just use shmat. This means that the NaCl module's mmap
162 * syscall must ask for the entire size, with a zero offset. In the
163 * future, we may choose to shmat to elsewhere in the trusted address
164 * space, and then mremap from there into the untrusted address space,
165 * using MREMAP_FIXED to ask for the new location. This approach has
166 * its own hazards, however since on x86-32 we are short on address
167 * space already, and requiring shmat, mremap, munmap means that we
168 * have to have enough trusted address space free to temporarily hold
169 * the maximum sized sysv shm object.
170 */
171 static uintptr_t NaClDescSysvShmMap(struct NaClDesc *vself,
172 struct NaClDescEffector *effp,
173 void *start_addr,
174 size_t len,
175 int prot,
176 int flags,
177 nacl_off64_t offset) {
178 struct NaClDescSysvShm *self = (struct NaClDescSysvShm *) vself;
179
180 int host_flags;
181 void *result;
182
183 UNREFERENCED_PARAMETER(effp);
184
185 NaClLog(4,
186 "NaClDescSysVShmMmap(,,0x%08"NACL_PRIxPTR",0x%"NACL_PRIxS","
187 "0x%x,0x%x,0x%08"NACL_PRIxNACL_OFF64")\n",
188 (uintptr_t) start_addr, len, prot, flags, offset);
189 /*
190 * shm must have NACL_ABI_MAP_SHARED in flags. we check, and may
191 * relax this in the future.
192 */
193 if ((NACL_ABI_MAP_SHARED) !=
194 (flags & (NACL_ABI_MAP_SHARING_MASK))) {
195 NaClLog(LOG_INFO,
196 ("NaClDescSysvShmMap: Mapping not"
197 " NACL_ABI_MAP_SHARED\n"));
198 return -NACL_ABI_EINVAL;
199 }
200
201 if (0 != (NACL_ABI_MAP_FIXED & flags) && NULL == start_addr) {
202 NaClLog(LOG_INFO,
203 ("NaClDescSysvShmMap: Mapping NACL_ABI_MAP_FIXED"
204 " but start_addr is NULL\n"));
205 return -NACL_ABI_EINVAL;
206 }
207 /* post-condition: if NULL == start_addr, then NACL_ABI_MAP_FIXED not set */
208
209 if (NULL == start_addr) {
210 uintptr_t addr;
211
212 if (!NaClFindAddressSpace(&addr, len)) {
213 NaClLog(1, "NaClDescSysvShmMap: could not find address space\n");
214 return -NACL_ABI_ENOMEM;
215 }
216 if (-1 == munmap((void *) addr, len)) {
217 NaClLog(LOG_FATAL,
218 "Could not unmap found space at 0x%"NACL_PRIxPTR"\n",
219 addr);
220 }
221 start_addr = (void *) addr;
222 }
223
224 /*
225 * shmat can only map the shared memory region starting at its beginning
226 * and continuing for its entire size.
227 */
228 if (0 != offset || self->size > len) {
229 NaClLog(LOG_INFO,
230 "NaClDescSysvShmMap: Mapping at non-zero offset or length"
231 " mismatch\n");
232 return -NACL_ABI_EINVAL;
233 }
234 /*
235 * prot must be not be PROT_NONE nor contain other than PROT_{READ|WRITE}
236 */
237 if (NACL_ABI_PROT_NONE == prot) {
238 NaClLog(LOG_INFO, "NaClDescSysvShmMap: PROT_NONE not supported\n");
239 return -NACL_ABI_EINVAL;
240 }
241 if (0 == (NACL_ABI_PROT_READ & prot)) {
242 NaClLog(LOG_INFO, "NaClDescSysvShmMap: PROT_READ not set\n");
243 return -NACL_ABI_EINVAL;
244 }
245 if (0 != (~(NACL_ABI_PROT_READ | NACL_ABI_PROT_WRITE) & prot)) {
246 NaClLog(LOG_INFO,
247 "NaClDescSysvShmMap: prot has other bits than PROT_{READ|WRITE}\n");
248 return -NACL_ABI_EINVAL;
249 }
250 /*
251 * Map from NACL_ABI_ prot and flags bits to shmat flags.
252 */
253 host_flags = SHM_REMAP;
254 if (NACL_ABI_PROT_READ == prot) {
255 host_flags |= SHM_RDONLY;
256 }
257
258 /*
259 * TODO(bsy): !NACL_ABI_MAP_FIXED, start_addr == NULL, find address
260 * space (assuming no race), and set start_addr appropriately.
261 *
262 * If SHM_REMAP is defined, use it. Else munmap and then shmat,
263 * leaving a timing hole for multithreaded race. Fail if we lose
264 * the race and let the user code retry.
265 */
266 /*
267 * Attach (map) the shared memory region.
268 */
269 result = shmat(self->id, (void *) start_addr, host_flags);
270 if (NACL_MAP_FAILED == result) {
271 NaClLog(LOG_FATAL, "NaClDescSysvMap: shmat failed %d\n", errno);
272 }
273 if (result != start_addr) {
274 NaClLog(LOG_FATAL,
275 ("NaClDescSysvShmMap: NACL_MAP_FIXED but"
276 " got 0x%08"NACL_PRIxPTR" instead of 0x%08"NACL_PRIxPTR"\n"),
277 (uintptr_t) result, (uintptr_t) start_addr);
278 }
279
280 return (uintptr_t) start_addr;
281 }
282
283 static int NaClDescSysvShmFstat(struct NaClDesc *vself,
284 struct nacl_abi_stat *stbp) {
285 struct NaClDescSysvShm *self = (struct NaClDescSysvShm *) vself;
286
287 if (self->size > INT32_MAX) {
288 return -NACL_ABI_EOVERFLOW;
289 }
290
291 stbp->nacl_abi_st_dev = 0;
292 stbp->nacl_abi_st_ino = 0x6c43614e;
293 stbp->nacl_abi_st_mode = (NACL_ABI_S_IFSHM_SYSV |
294 NACL_ABI_S_IRUSR |
295 NACL_ABI_S_IWUSR);
296 stbp->nacl_abi_st_nlink = 1;
297 stbp->nacl_abi_st_uid = -1;
298 stbp->nacl_abi_st_gid = -1;
299 stbp->nacl_abi_st_rdev = 0;
300 /* TODO(sehr): this should really use shmctl instead. */
301 stbp->nacl_abi_st_size = (nacl_abi_off_t) self->size;
302 stbp->nacl_abi_st_blksize = 0;
303 stbp->nacl_abi_st_blocks = 0;
304 stbp->nacl_abi_st_atime = 0;
305 stbp->nacl_abi_st_mtime = 0;
306 stbp->nacl_abi_st_ctime = 0;
307
308 return 0;
309 }
310
311 static int NaClDescSysvShmExternalizeSize(struct NaClDesc *vself,
312 size_t *nbytes,
313 size_t *nhandles) {
314 struct NaClDescSysvShm *self = (struct NaClDescSysvShm *) vself;
315 int rv;
316
317 rv = NaClDescExternalizeSize(vself, nbytes, nhandles);
318 if (0 != rv) {
319 return rv;
320 }
321 *nbytes += sizeof self->id + sizeof(nacl_off64_t);
322
323 return 0;
324 }
325
326 static int NaClDescSysvShmExternalize(struct NaClDesc *vself,
327 struct NaClDescXferState *xfer) {
328 struct NaClDescSysvShm *self = (struct NaClDescSysvShm *) vself;
329 nacl_off64_t size64 = self->size;
330 int rv;
331
332 rv = NaClDescExternalize(vself, xfer);
333 if (0 != rv) {
334 return rv;
335 }
336 memcpy(xfer->next_byte, &self->id, sizeof self->id);
337 xfer->next_byte += sizeof self->id;
338 memcpy(xfer->next_byte, &size64, sizeof size64);
339 xfer->next_byte += sizeof size64;
340 return 0;
341 }
342
343 struct NaClDescVtbl const kNaClDescSysvShmVtbl = {
344 {
345 NaClDescSysvShmDtor,
346 },
347 NaClDescSysvShmMap,
348 NACL_DESC_UNMAP_NOT_IMPLEMENTED
349 NaClDescReadNotImplemented,
350 NaClDescWriteNotImplemented,
351 NaClDescSeekNotImplemented,
352 NaClDescPReadNotImplemented,
353 NaClDescPWriteNotImplemented,
354 NaClDescSysvShmFstat,
355 NaClDescGetdentsNotImplemented,
356 NaClDescSysvShmExternalizeSize,
357 NaClDescSysvShmExternalize,
358 NaClDescLockNotImplemented,
359 NaClDescTryLockNotImplemented,
360 NaClDescUnlockNotImplemented,
361 NaClDescWaitNotImplemented,
362 NaClDescTimedWaitAbsNotImplemented,
363 NaClDescSignalNotImplemented,
364 NaClDescBroadcastNotImplemented,
365 NaClDescSendMsgNotImplemented,
366 NaClDescRecvMsgNotImplemented,
367 NaClDescLowLevelSendMsgNotImplemented,
368 NaClDescLowLevelRecvMsgNotImplemented,
369 NaClDescConnectAddrNotImplemented,
370 NaClDescAcceptConnNotImplemented,
371 NaClDescPostNotImplemented,
372 NaClDescSemWaitNotImplemented,
373 NaClDescGetValueNotImplemented,
374 NaClDescSetMetadata,
375 NaClDescGetMetadata,
376 NaClDescSetFlags,
377 NaClDescGetFlags,
378 NaClDescIsattyNotImplemented,
379 NACL_DESC_SYSV_SHM,
380 };
381
382 int NaClDescSysvShmInternalize(struct NaClDesc **out_desc,
383 struct NaClDescXferState *xfer,
384 struct NaClDescQuotaInterface *quota_interface) {
385 int rv;
386 struct NaClDescSysvShm *ndisp;
387 int id;
388 nacl_off64_t size;
389
390 UNREFERENCED_PARAMETER(quota_interface);
391 rv = -NACL_ABI_EIO;
392
393 ndisp = malloc(sizeof *ndisp);
394 if (NULL == ndisp) {
395 rv = -NACL_ABI_ENOMEM;
396 goto cleanup;
397 }
398
399 if (!NaClDescInternalizeCtor((struct NaClDesc *) ndisp, xfer)) {
400 free(ndisp);
401 ndisp = NULL;
402 rv = -NACL_ABI_ENOMEM;
403 goto cleanup;
404 }
405
406 if (xfer->next_byte + sizeof ndisp->id + sizeof ndisp->size >
407 xfer->byte_buffer_end) {
408 rv = -NACL_ABI_EIO;
409 goto cleanup;
410 }
411
412 memcpy(&id, xfer->next_byte, sizeof id);
413 xfer->next_byte += sizeof id;
414 memcpy(&size, xfer->next_byte, sizeof size);
415 xfer->next_byte += sizeof size;
416
417 if (!NaClDescSysvShmImportSubclassCtor(ndisp, id, size)) {
418 rv = -NACL_ABI_EIO;
419 goto cleanup;
420 }
421
422 *out_desc = (struct NaClDesc *) ndisp;
423 rv = 0;
424
425 cleanup:
426 if (rv < 0) {
427 NaClDescSafeUnref((struct NaClDesc *) ndisp);
428 }
429 return rv;
430 }
OLDNEW
« no previous file with comments | « src/trusted/desc/linux/nacl_desc_sysv_shm.h ('k') | src/trusted/desc/nacl_desc_base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698