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

Side by Side Diff: src/trusted/service_runtime/sys_filename.c

Issue 23484041: Split filename-based syscall implementations into a separate file (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: Fix missing #includes for Windows Created 7 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 | « src/trusted/service_runtime/sys_filename.h ('k') | no next file » | 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) 2013 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 #include "native_client/src/trusted/service_runtime/sys_filename.h"
8
9 #include <string.h>
10
11 #include "native_client/src/shared/platform/nacl_host_desc.h"
12 #include "native_client/src/shared/platform/nacl_host_dir.h"
13 #include "native_client/src/trusted/desc/nacl_desc_dir.h"
14 #include "native_client/src/trusted/desc/nacl_desc_io.h"
15 #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
16 #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h"
17 #include "native_client/src/trusted/service_runtime/include/sys/stat.h"
18 #include "native_client/src/trusted/service_runtime/nacl_app_thread.h"
19 #include "native_client/src/trusted/service_runtime/nacl_copy.h"
20 #include "native_client/src/trusted/service_runtime/nacl_syscall_common.h"
21 #include "native_client/src/trusted/service_runtime/sel_ldr.h"
22
23
24 /*
25 * NaClOpenAclCheck: Is the NaCl app authorized to open this file? The
26 * return value is syscall return convention, so 0 is success and
27 * small negative numbers are negated errno values.
28 */
29 int32_t NaClOpenAclCheck(struct NaClApp *nap,
30 char const *path,
31 int flags,
32 int mode) {
33 /*
34 * TODO(bsy): provide some minimal authorization check, based on
35 * whether a debug flag is set; eventually provide a data-driven
36 * authorization configuration mechanism, perhaps persisted via
37 * gears. need GUI for user configuration, as well as designing an
38 * appropriate language (with sufficient expressiveness), however.
39 */
40 NaClLog(1, "NaClOpenAclCheck(0x%08"NACL_PRIxPTR", %s, 0%o, 0%o)\n",
41 (uintptr_t) nap, path, flags, mode);
42 if (3 < NaClLogGetVerbosity()) {
43 NaClLog(0, "O_ACCMODE: 0%o\n", flags & NACL_ABI_O_ACCMODE);
44 NaClLog(0, "O_RDONLY = %d\n", NACL_ABI_O_RDONLY);
45 NaClLog(0, "O_WRONLY = %d\n", NACL_ABI_O_WRONLY);
46 NaClLog(0, "O_RDWR = %d\n", NACL_ABI_O_RDWR);
47 #define FLOG(VAR, BIT) do {\
48 NaClLog(1, "%s: %s\n", #BIT, (VAR & BIT) ? "yes" : "no");\
49 } while (0)
50 FLOG(flags, NACL_ABI_O_CREAT);
51 FLOG(flags, NACL_ABI_O_TRUNC);
52 FLOG(flags, NACL_ABI_O_APPEND);
53 #undef FLOG
54 }
55 if (NaClAclBypassChecks) {
56 return 0;
57 }
58 return -NACL_ABI_EACCES;
59 }
60
61 /*
62 * NaClStatAclCheck: Is the NaCl app authorized to stat this pathname? The
63 * return value is syscall return convention, so 0 is success and
64 * small negative numbers are negated errno values.
65 *
66 * This is primarily for debug use. File access should be through
67 * SRPC-based file servers.
68 */
69 int32_t NaClStatAclCheck(struct NaClApp *nap,
70 char const *path) {
71 NaClLog(2,
72 "NaClStatAclCheck(0x%08"NACL_PRIxPTR", %s)\n", (uintptr_t) nap, path);
73 if (NaClAclBypassChecks) {
74 return 0;
75 }
76 return -NACL_ABI_EACCES;
77 }
78
79 static uint32_t CopyPathFromUser(struct NaClApp *nap,
80 char *dest,
81 size_t num_bytes,
82 uintptr_t src) {
83 /*
84 * NaClCopyInFromUserZStr may (try to) get bytes that is outside the
85 * app's address space and generate a fault.
86 */
87 if (!NaClCopyInFromUserZStr(nap, dest, num_bytes, src)) {
88 if (dest[0] == '\0') {
89 NaClLog(LOG_ERROR, "NaClSys: invalid address for pathname\n");
90 return -NACL_ABI_EFAULT;
91 }
92
93 NaClLog(LOG_ERROR, "NaClSys: pathname string too long\n");
94 return -NACL_ABI_ENAMETOOLONG;
95 }
96
97 return 0;
98 }
99
100 int32_t NaClSysOpen(struct NaClAppThread *natp,
101 char *pathname,
102 int flags,
103 int mode) {
104 struct NaClApp *nap = natp->nap;
105 uint32_t retval = -NACL_ABI_EINVAL;
106 char path[NACL_CONFIG_PATH_MAX];
107 nacl_host_stat_t stbuf;
108 int allowed_flags;
109
110 NaClLog(3, "NaClSysOpen(0x%08"NACL_PRIxPTR", "
111 "0x%08"NACL_PRIxPTR", 0x%x, 0x%x)\n",
112 (uintptr_t) natp, (uintptr_t) pathname, flags, mode);
113
114 retval = CopyPathFromUser(nap, path, sizeof path, (uintptr_t) pathname);
115 if (0 != retval)
116 goto cleanup;
117
118 allowed_flags = (NACL_ABI_O_ACCMODE | NACL_ABI_O_CREAT
119 | NACL_ABI_O_TRUNC | NACL_ABI_O_APPEND);
120 if (0 != (flags & ~allowed_flags)) {
121 NaClLog(LOG_WARNING, "Invalid open flags 0%o, ignoring extraneous bits\n",
122 flags);
123 flags &= allowed_flags;
124 }
125 if (0 != (mode & ~0600)) {
126 NaClLog(1, "IGNORING Invalid access mode bits 0%o\n", mode);
127 mode &= 0600;
128 }
129
130 retval = NaClOpenAclCheck(nap, path, flags, mode);
131 if (0 != retval) {
132 NaClLog(3, "Open ACL check rejected \"%s\".\n", path);
133 goto cleanup;
134 }
135
136 /*
137 * Perform a stat to determine whether the file is a directory.
138 *
139 * NB: it is okay for the stat to fail, since the request may be to
140 * create a new file.
141 *
142 * There is a race conditions here: between the stat and the
143 * open-as-a-file and open-as-a-dir, the type of the object that the
144 * path refers to can change.
145 */
146 retval = NaClHostDescStat(path, &stbuf);
147
148 /* Windows does not have S_ISDIR(m) macro */
149 if (0 == retval && S_IFDIR == (S_IFDIR & stbuf.st_mode)) {
150 struct NaClHostDir *hd;
151
152 hd = malloc(sizeof *hd);
153 if (NULL == hd) {
154 retval = -NACL_ABI_ENOMEM;
155 goto cleanup;
156 }
157 retval = NaClHostDirOpen(hd, path);
158 NaClLog(1, "NaClHostDirOpen(0x%08"NACL_PRIxPTR", %s) returned %d\n",
159 (uintptr_t) hd, path, retval);
160 if (0 == retval) {
161 retval = NaClSetAvail(nap,
162 ((struct NaClDesc *) NaClDescDirDescMake(hd)));
163 NaClLog(1, "Entered directory into open file table at %d\n",
164 retval);
165 }
166 } else {
167 struct NaClHostDesc *hd;
168
169 hd = malloc(sizeof *hd);
170 if (NULL == hd) {
171 retval = -NACL_ABI_ENOMEM;
172 goto cleanup;
173 }
174 retval = NaClHostDescOpen(hd, path, flags, mode);
175 NaClLog(1,
176 "NaClHostDescOpen(0x%08"NACL_PRIxPTR", %s, 0%o, 0%o) returned %d\n",
177 (uintptr_t) hd, path, flags, mode, retval);
178 if (0 == retval) {
179 struct NaClDesc *desc = (struct NaClDesc *) NaClDescIoDescMake(hd);
180 if ((flags & NACL_ABI_O_ACCMODE) == NACL_ABI_O_RDONLY) {
181 /*
182 * Let any read-only open be used for PROT_EXEC mmap
183 * calls. Under -a, the user informally warrants that
184 * files' code segments won't be changed after open.
185 */
186 NaClDescSetFlags(desc,
187 NaClDescGetFlags(desc) | NACL_DESC_FLAGS_MMAP_EXEC_OK);
188 }
189 retval = NaClSetAvail(nap, desc);
190 NaClLog(1, "Entered into open file table at %d\n", retval);
191 }
192 }
193 cleanup:
194 return retval;
195 }
196
197 int32_t NaClSysStat(struct NaClAppThread *natp,
198 const char *pathname,
199 struct nacl_abi_stat *buf) {
200 struct NaClApp *nap = natp->nap;
201 int32_t retval = -NACL_ABI_EINVAL;
202 char path[NACL_CONFIG_PATH_MAX];
203 nacl_host_stat_t stbuf;
204
205 NaClLog(3,
206 ("Entered NaClSysStat(0x%08"NACL_PRIxPTR", 0x%08"NACL_PRIxPTR","
207 " 0x%08"NACL_PRIxPTR")\n"),
208 (uintptr_t) natp, (uintptr_t) pathname, (uintptr_t) buf);
209
210 retval = CopyPathFromUser(nap, path, sizeof path, (uintptr_t) pathname);
211 if (0 != retval)
212 goto cleanup;
213
214 retval = NaClStatAclCheck(nap, path);
215 if (0 != retval)
216 goto cleanup;
217
218 /*
219 * Perform a host stat.
220 */
221 retval = NaClHostDescStat(path, &stbuf);
222 if (0 == retval) {
223 struct nacl_abi_stat abi_stbuf;
224
225 retval = NaClAbiStatHostDescStatXlateCtor(&abi_stbuf,
226 &stbuf);
227 if (!NaClCopyOutToUser(nap, (uintptr_t) buf,
228 &abi_stbuf, sizeof abi_stbuf)) {
229 retval = -NACL_ABI_EFAULT;
230 }
231 }
232 cleanup:
233 return retval;
234 }
235
236 int32_t NaClSysMkdir(struct NaClAppThread *natp,
237 uint32_t pathname,
238 int mode) {
239 struct NaClApp *nap = natp->nap;
240 char path[NACL_CONFIG_PATH_MAX];
241 int32_t retval = -NACL_ABI_EINVAL;
242
243 if (!NaClAclBypassChecks) {
244 retval = -NACL_ABI_EACCES;
245 goto cleanup;
246 }
247
248 retval = CopyPathFromUser(nap, path, sizeof path, pathname);
249 if (0 != retval)
250 goto cleanup;
251
252 retval = NaClHostDescMkdir(path, mode);
253 cleanup:
254 return retval;
255 }
256
257 int32_t NaClSysRmdir(struct NaClAppThread *natp,
258 uint32_t pathname) {
259 struct NaClApp *nap = natp->nap;
260 char path[NACL_CONFIG_PATH_MAX];
261 int32_t retval = -NACL_ABI_EINVAL;
262
263 if (!NaClAclBypassChecks) {
264 retval = -NACL_ABI_EACCES;
265 goto cleanup;
266 }
267
268 retval = CopyPathFromUser(nap, path, sizeof path, pathname);
269 if (0 != retval)
270 goto cleanup;
271
272 retval = NaClHostDescRmdir(path);
273 cleanup:
274 return retval;
275 }
276
277 int32_t NaClSysChdir(struct NaClAppThread *natp,
278 uint32_t pathname) {
279 struct NaClApp *nap = natp->nap;
280 char path[NACL_CONFIG_PATH_MAX];
281 int32_t retval = -NACL_ABI_EINVAL;
282
283 if (!NaClAclBypassChecks) {
284 retval = -NACL_ABI_EACCES;
285 goto cleanup;
286 }
287
288 retval = CopyPathFromUser(nap, path, sizeof path, pathname);
289 if (0 != retval)
290 goto cleanup;
291
292 retval = NaClHostDescChdir(path);
293 cleanup:
294 return retval;
295 }
296
297 int32_t NaClSysGetcwd(struct NaClAppThread *natp,
298 uint32_t buffer,
299 int len) {
300 struct NaClApp *nap = natp->nap;
301 int32_t retval = -NACL_ABI_EINVAL;
302 char path[NACL_CONFIG_PATH_MAX];
303
304 if (!NaClAclBypassChecks) {
305 retval = -NACL_ABI_EACCES;
306 goto cleanup;
307 }
308
309 if (len >= NACL_CONFIG_PATH_MAX)
310 len = NACL_CONFIG_PATH_MAX - 1;
311
312 retval = NaClHostDescGetcwd(path, len);
313 if (retval != 0)
314 goto cleanup;
315
316 if (!NaClCopyOutToUser(nap, buffer, &path, strlen(path) + 1))
317 retval = -NACL_ABI_EFAULT;
318
319 cleanup:
320 return retval;
321 }
322
323 int32_t NaClSysUnlink(struct NaClAppThread *natp,
324 uint32_t pathname) {
325 struct NaClApp *nap = natp->nap;
326 char path[NACL_CONFIG_PATH_MAX];
327 int32_t retval = -NACL_ABI_EINVAL;
328
329 if (!NaClAclBypassChecks) {
330 retval = -NACL_ABI_EACCES;
331 goto cleanup;
332 }
333
334 retval = CopyPathFromUser(nap, path, sizeof path, pathname);
335 if (0 != retval)
336 goto cleanup;
337
338 retval = NaClHostDescUnlink(path);
339 cleanup:
340 return retval;
341 }
OLDNEW
« no previous file with comments | « src/trusted/service_runtime/sys_filename.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698