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

Side by Side Diff: documentation/filesystem_access.txt

Issue 1211173002: add restricted filesystem access to sel_ldr Base URL: https://chromium.googlesource.com/native_client/src/native_client.git@master
Patch Set: add restricted filesystem access to sel_ldr Created 5 years, 5 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
« no previous file with comments | « no previous file | src/trusted/service_runtime/nacl_syscall_common.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 # Safe filesystem access
2
3 ## Background
4
5 Native Client is a phenomenally useful library for restricted code execution
6 that is useful beyond the browser. There’s all sorts of cases where one might
7 want to run untrusted code in a system disconnected from Chromium or the PPAPI.
8
9 In these cases, it is additionally useful to allow restricted filesystem
10 access, but to still run untrusted code. Prior to this change, `sel_ldr` did
11 not allow for safe and restricted filesystem access.
12
13 ## Requirements
14
15 * Very low overhead File I/O
16 * Give users the ability to have selective read-only or read/write access
17 * Give users control over the entire filesystem layout presented to the
18 untrusted application.
19
20 ## Feature user experience
21
22 This feature adds one additional commandline argument `-m` to `sel_ldr`. `-m`
23 takes a path to the directory to be used as the root by the untrusted
24 application.
25
26 **IMPORTANT WARNING**: The user should take great pains to make sure there are
27 no relative symlinks at all or any absolute symlinks to outside of the
28 `chroot` path inside the tree. It would be easy to get this wrong and may be
29 safer to disallow starting with a path that has any symlinks contained inside
30 at all.
31
32 All of the given requirements can be satisfied by this `chroot`-style
33 interface:
34
35 * The only overhead for file I/O is in adding (and sanitizing) a path prefix
36 to absolute paths passed through to the host. For relative paths, an
37 additional `Getcwd` call is necessary.
38 * Read-only or read/write access can be controlled using normal filesystem
39 permissions for the user running the `sel_ldr` process.
40 * Using host-side filesystem primitives such as Linux bind mounts, users can
41 map disparate paths from the host into the untrusted process's root.
42
43 ## Implementation
44
45 For the most part, this feature is simple and relatively straightforward to
46 add. When `-m` is given (even if `-a` is not), file operations will be enabled
47 and the provided chroot path will be added as a path prefix to all absolute
48 paths passed through to the host. Paths will be sanitized to make sure no
49 escapes are made with `..` path elements.
50
51 Relative paths are slightly more complex. Instead of prepending the path
52 prefix, the CWD is checked to make sure it resides in the chroot path, then it
53 is prepended, then everything after the chroot path in the resultant path is
54 sanitized.
55
56 Given that strategy, the following syscall changes were straightforward:
57
58 * `NaClSysOpen`
59 * `NaClSysStat`
60 * `NaClSysMkdir`
61 * `NaClSysRmdir`
62 * `NaClSysUnlink`
63 * `NaClSysTruncate`
64 * `NaClSysLink`
65 * `NaClSysRename`
66 * `NaClSysChmod`
67 * `NaClSysAccess`
68 * `NaClSysUtimes`
69
70 ### Path sanitization
71
72 Path sanitization happens lexically, in the sense that no disk I/O happens
73 while attempting to put the path in canonical form. Essentially, the path
74 elements are parsed, and double path separators, '.' path elements, and '..'
75 path elements are all handled and cleaned up prior to disk access.
76
77 While this approach (assuming the algorithm is correct) is a secure way to
78 eliminate parent folder references, it does result in a slight change of POSIX
79 semantics. "/a/.." does not always refer to the same inode as "/", even if
80 practically it almost always does.
81
82 ### Symlinks
83
84 Ideally, symlinks should behave as if we had just chrooted into the path given
85 to `-m` (which means they would resolve relative to the untrusted root).
86
87 However, it's not straightforward to have `sel_ldr` call `chroot` itself to
88 make the kernel do appropriate symlink resolution in a cross-platform way. So
89 our other option to support symlinks is to do an Lstat on every path load and
90 try to resolve symlinks ourselves. This would be a pretty big performance hit
91 and a significant amount of complication needing auditing. We wouldn't be able
92 to just pass through sanitized paths to the host's open call without making
93 sure the untrusted app hadn't created a symlink pointing elsewhere to jump out
94 of jail.
95
96 So instead, for v1 we're just not supporting symlinks. `Readlink` and `Lstat`
97 don't allow the untrusted process access to any information the chroot
98 filesystem creator didn't give it access to, so those are allowed when `-m` is
99 given, but the symlink creation call will fail.
100
101 Further, the path passed to `-m` might have symlinks in it, so it is up to the
102 creator of the filesystem passed to `-m` to sanitize it for bad (or even
103 relative!) symlinks prior to safely running `sel_ldr`. This is a significant
104 amount of sharpness and potential insecurity this feature might bring, so it
105 might be worth just failing to start if symlinks exist at any subpath from the
106 path given to `-m`. Currently we're going to allow the sharpness of this
107 interface.
108
109 The following syscalls relate to symlinks.
110
111 * `NaClSysLstat` - pass through (with appropriate path changes)
112 * `NaClSysSymlink` - always fails
113 * `NaClSysReadlink` - pass through (with appropriate path changes)
114
115 ### Current working directory
116
117 Being able to read the current working directory (aside from `readlink`,
118 previously discussed) is the only syscall that has a path going from the host
119 back to the untrusted application. All other syscalls are one way - paths go
120 from the untrusted application out to the host.
121
122 The current working directory, unless we call the host's `chdir` at startup to
123 the path given to `-m`, might not be inside of the untrusted application's
124 filesystem.
125
126 This affects the following two syscalls:
127
128 * `NaClSysChdir` - always adds the path prefix
129 * `NaClSysGetcwd` - checks if the path is sanitized and starts with the path
130 prefix. if it doesn't start with the path prefix this syscall fails.
131
132 ### Filehandle syscalls
133
134 These syscalls require no changes and are safe to just enable like they would
135 be with `-a` when `-m` is passed:
136
137 * `NaClSysGetdents` - `..` might reference an inode outside of the untrusted
138 root, but that's okay because the untrusted application can't do anything
139 with it.
140 * `NaClSysFstat` - no different than `stat`, which is already allowed.
141
142 For both of these calls, we might need to make sure there's no file descriptors
143 in the untrusted application that reference files outside of the untrusted
144 root, but even if we don't there's very little the untrusted application could
145 do with the data these calls return.
OLDNEW
« no previous file with comments | « no previous file | src/trusted/service_runtime/nacl_syscall_common.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698