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

Unified 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, 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/trusted/service_runtime/nacl_syscall_common.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: documentation/filesystem_access.txt
diff --git a/documentation/filesystem_access.txt b/documentation/filesystem_access.txt
new file mode 100644
index 0000000000000000000000000000000000000000..2fc702d277eb8f1c28383eb2eeaa99c69b1bde66
--- /dev/null
+++ b/documentation/filesystem_access.txt
@@ -0,0 +1,145 @@
+# Safe filesystem access
+
+## Background
+
+Native Client is a phenomenally useful library for restricted code execution
+that is useful beyond the browser. There’s all sorts of cases where one might
+want to run untrusted code in a system disconnected from Chromium or the PPAPI.
+
+In these cases, it is additionally useful to allow restricted filesystem
+access, but to still run untrusted code. Prior to this change, `sel_ldr` did
+not allow for safe and restricted filesystem access.
+
+## Requirements
+
+* Very low overhead File I/O
+* Give users the ability to have selective read-only or read/write access
+* Give users control over the entire filesystem layout presented to the
+ untrusted application.
+
+## Feature user experience
+
+This feature adds one additional commandline argument `-m` to `sel_ldr`. `-m`
+takes a path to the directory to be used as the root by the untrusted
+application.
+
+**IMPORTANT WARNING**: The user should take great pains to make sure there are
+no relative symlinks at all or any absolute symlinks to outside of the
+`chroot` path inside the tree. It would be easy to get this wrong and may be
+safer to disallow starting with a path that has any symlinks contained inside
+at all.
+
+All of the given requirements can be satisfied by this `chroot`-style
+interface:
+
+ * The only overhead for file I/O is in adding (and sanitizing) a path prefix
+ to absolute paths passed through to the host. For relative paths, an
+ additional `Getcwd` call is necessary.
+ * Read-only or read/write access can be controlled using normal filesystem
+ permissions for the user running the `sel_ldr` process.
+ * Using host-side filesystem primitives such as Linux bind mounts, users can
+ map disparate paths from the host into the untrusted process's root.
+
+## Implementation
+
+For the most part, this feature is simple and relatively straightforward to
+add. When `-m` is given (even if `-a` is not), file operations will be enabled
+and the provided chroot path will be added as a path prefix to all absolute
+paths passed through to the host. Paths will be sanitized to make sure no
+escapes are made with `..` path elements.
+
+Relative paths are slightly more complex. Instead of prepending the path
+prefix, the CWD is checked to make sure it resides in the chroot path, then it
+is prepended, then everything after the chroot path in the resultant path is
+sanitized.
+
+Given that strategy, the following syscall changes were straightforward:
+
+ * `NaClSysOpen`
+ * `NaClSysStat`
+ * `NaClSysMkdir`
+ * `NaClSysRmdir`
+ * `NaClSysUnlink`
+ * `NaClSysTruncate`
+ * `NaClSysLink`
+ * `NaClSysRename`
+ * `NaClSysChmod`
+ * `NaClSysAccess`
+ * `NaClSysUtimes`
+
+### Path sanitization
+
+Path sanitization happens lexically, in the sense that no disk I/O happens
+while attempting to put the path in canonical form. Essentially, the path
+elements are parsed, and double path separators, '.' path elements, and '..'
+path elements are all handled and cleaned up prior to disk access.
+
+While this approach (assuming the algorithm is correct) is a secure way to
+eliminate parent folder references, it does result in a slight change of POSIX
+semantics. "/a/.." does not always refer to the same inode as "/", even if
+practically it almost always does.
+
+### Symlinks
+
+Ideally, symlinks should behave as if we had just chrooted into the path given
+to `-m` (which means they would resolve relative to the untrusted root).
+
+However, it's not straightforward to have `sel_ldr` call `chroot` itself to
+make the kernel do appropriate symlink resolution in a cross-platform way. So
+our other option to support symlinks is to do an Lstat on every path load and
+try to resolve symlinks ourselves. This would be a pretty big performance hit
+and a significant amount of complication needing auditing. We wouldn't be able
+to just pass through sanitized paths to the host's open call without making
+sure the untrusted app hadn't created a symlink pointing elsewhere to jump out
+of jail.
+
+So instead, for v1 we're just not supporting symlinks. `Readlink` and `Lstat`
+don't allow the untrusted process access to any information the chroot
+filesystem creator didn't give it access to, so those are allowed when `-m` is
+given, but the symlink creation call will fail.
+
+Further, the path passed to `-m` might have symlinks in it, so it is up to the
+creator of the filesystem passed to `-m` to sanitize it for bad (or even
+relative!) symlinks prior to safely running `sel_ldr`. This is a significant
+amount of sharpness and potential insecurity this feature might bring, so it
+might be worth just failing to start if symlinks exist at any subpath from the
+path given to `-m`. Currently we're going to allow the sharpness of this
+interface.
+
+The following syscalls relate to symlinks.
+
+ * `NaClSysLstat` - pass through (with appropriate path changes)
+ * `NaClSysSymlink` - always fails
+ * `NaClSysReadlink` - pass through (with appropriate path changes)
+
+### Current working directory
+
+Being able to read the current working directory (aside from `readlink`,
+previously discussed) is the only syscall that has a path going from the host
+back to the untrusted application. All other syscalls are one way - paths go
+from the untrusted application out to the host.
+
+The current working directory, unless we call the host's `chdir` at startup to
+the path given to `-m`, might not be inside of the untrusted application's
+filesystem.
+
+This affects the following two syscalls:
+
+ * `NaClSysChdir` - always adds the path prefix
+ * `NaClSysGetcwd` - checks if the path is sanitized and starts with the path
+ prefix. if it doesn't start with the path prefix this syscall fails.
+
+### Filehandle syscalls
+
+These syscalls require no changes and are safe to just enable like they would
+be with `-a` when `-m` is passed:
+
+ * `NaClSysGetdents` - `..` might reference an inode outside of the untrusted
+ root, but that's okay because the untrusted application can't do anything
+ with it.
+ * `NaClSysFstat` - no different than `stat`, which is already allowed.
+
+For both of these calls, we might need to make sure there's no file descriptors
+in the untrusted application that reference files outside of the untrusted
+root, but even if we don't there's very little the untrusted application could
+do with the data these calls return.
« 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