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

Unified Diff: src/trusted/service_runtime/nacl_syscall_common.c

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 | « src/trusted/service_runtime/nacl_syscall_common.h ('k') | src/trusted/service_runtime/sel_main.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/trusted/service_runtime/nacl_syscall_common.c
diff --git a/src/trusted/service_runtime/nacl_syscall_common.c b/src/trusted/service_runtime/nacl_syscall_common.c
index 4a19502c52ceb198b07054532eb055a5b5a998ec..01165d81a3831824d95d3551e7c28bbd43ff82f4 100644
--- a/src/trusted/service_runtime/nacl_syscall_common.c
+++ b/src/trusted/service_runtime/nacl_syscall_common.c
@@ -12,6 +12,7 @@
#include <errno.h>
#include <stdio.h>
+#include <string.h>
#include "native_client/src/include/build_config.h"
@@ -91,6 +92,171 @@ void NaClInsecurelyBypassAllAclChecks(void) {
NaClAclBypassChecks = 1;
}
+char *NaClRootDir = NULL;
+size_t NaClRootDirLen = 0;
+
+#if NACL_WINDOWS
+int NaClMountRootDir(char *root) {
+ return 0;
+}
+
+int NaClSanitizePathLexically(char *path) {
+ /*
+ * TODO(jtolds): this could totally be made to work with Windows, but I'm
+ * unclear what the path separator and drive letter requirements are at this
+ * level.
+ */
+ return 0;
+}
+#elif NACL_LINUX || NACL_OSX
+int NaClMountRootDir(char *root) {
+ NaClRootDir = strdup(root);
+ if (!NaClSanitizePathLexically(NaClRootDir)) {
+ goto fail;
+ }
+ NaClRootDirLen = strlen(NaClRootDir);
+ if (NaClRootDirLen <= 0) {
+ goto fail;
+ }
+ while (NaClRootDirLen > 0 && NaClRootDir[NaClRootDirLen-1] == '/') {
+ NaClRootDir[--NaClRootDirLen] = '\0';
+ }
+ return 1;
+fail:
+ free(NaClRootDir);
+ NaClRootDir = NULL;
+ return 0;
+}
+
+int NaClSanitizePathLexically(char *path) {
+ size_t last_path_sep = 0, prev_sep = 0, next_char = 0;
+ size_t path_len = strlen(path);
+
+ /*
+ * Overall strategy:
+ * We're going to keep track of the last path separator we saw. Each time
+ * we see a new path separator, we'll mark off the last path element, then
+ * decide what to do with it. We'll either:
+ * * decide the path element was empty (a double slash) and slide everything
+ * back a byte.
+ * * decide the path element was '.' and slide everything back two bytes.
+ * * decide the path element is '..' and it's immediately after the root, so
+ * we'll slide everything back three bytes
+ * * decide the path element is '..' and it's not after the root, so we'll
+ * go find the previous path separator and slide everything back to it.
+ * * decide the path element is fine and continue with the new path
+ * separator.
+ *
+ * This strategy avoids mallocs.
+ */
+
+ /*
+ * This algorithm assumes that there is always at least space for
+ * "/\0", and the path is absolute, so make sure strlen(path) >= 1 and the
+ * path starts with '/'.
+ */
+ if (path_len <= 0 || path[0] != '/') {
+ return 0;
+ }
+
+ /*
+ * For the purposes of this algorithm, '/' and '\0' are both path separators.
+ * last_path_sep refers to the index of the last path separator (either one
+ * of the above two bytes) that we've seen so far.
+ *
+ * We'll loop as long as the last path separator isn't the null byte and do
+ * some cleanup after.
+ */
+ while (path[last_path_sep] != '\0') {
+
+ /*
+ * Let's find the full next path element.
+ */
+ next_char = last_path_sep + 1;
+ while (path[next_char] != '/' && path[next_char] != '\0') {
+ next_char++;
+ }
+
+ /* Check if the path element was empty (double-separator case) */
+ if (next_char == last_path_sep + 1) {
+ if (path[next_char] == '\0') {
+ /*
+ * Special '/\0' end case, allow a double separator when the second one
+ * is a null byte. This allows us to sanitize paths with or without
+ * trailing slashes.
+ */
+ last_path_sep = next_char;
+ continue;
+ }
+ /* Normal double-separator case. Just slide everything back one. */
+ memmove(path + last_path_sep, path + last_path_sep + 1,
+ (path_len + 1) - (last_path_sep + 1));
+ path_len -= 1;
+ continue;
+ }
+
+ /* Check if the last path element was "." */
+ if (next_char == last_path_sep + 2 && path[last_path_sep + 1] == '.') {
+ /* Slide everything back two */
+ memmove(path + last_path_sep, path + last_path_sep + 2,
+ (path_len + 1) - (last_path_sep + 2));
+ path_len -= 2;
+ continue;
+ }
+
+ /* Check if the last path element was ".." */
+ if (next_char == last_path_sep + 3 && path[last_path_sep + 1] == '.' &&
+ path[last_path_sep + 2] == '.') {
+ if (last_path_sep == 0) {
+ /* '..' after root case, just slide everything back three. */
+ memmove(path + last_path_sep, path + last_path_sep + 3,
+ (path_len + 1) - (last_path_sep + 3));
+ path_len -= 3;
+ continue;
+ }
+ /*
+ * Normal '..' case. Go find the previous path separator and then slide
+ * everything back to it.
+ */
+ prev_sep = last_path_sep - 1;
+ while (path[prev_sep] != '/') {
+ prev_sep--;
+ }
+ memmove(path + prev_sep, path + last_path_sep + 3,
+ (path_len + 1) - (last_path_sep + 3));
+ path_len -= (last_path_sep + 3 - prev_sep);
+ last_path_sep = prev_sep;
+ continue;
+ }
+
+ /* Default path element case. */
+ last_path_sep = next_char;
+ }
+
+ /*
+ * Cleanup scenario: whenever we slide something back, we overwrite the
+ * last path separator. For example, in the "/a/.\0" case, we slide
+ * everything starting at byte 4 back over byte 3, so the result is "/a\0".
+ * In the case of a full path "/.\0", the end result ends up being "\0", so
+ * we need to fix up root paths like this specially.
+ * N.B.: we know we have enough space in the buffer for this.
+ */
+ if (last_path_sep == 0) {
+ path[0] = '/';
+ path[1] = '\0';
+ }
+
+ return 1;
+}
+
+#else
+#error Unsupported platform
+#endif
+
+int NaClFileAccessEnabled(void) {
+ return NaClAclBypassChecks || (NaClRootDir != NULL);
+}
+
int NaClHighResolutionTimerEnabled(void) {
return NaClAclBypassChecks;
}
@@ -705,7 +871,7 @@ int32_t NaClSysSysconf(struct NaClAppThread *natp,
break;
}
case NACL_ABI__SC_NACL_FILE_ACCESS_ENABLED: {
- result_value = NaClAclBypassChecks;
+ result_value = NaClFileAccessEnabled();
break;
}
case NACL_ABI__SC_NACL_LIST_MAPPINGS_ENABLED: {
« no previous file with comments | « src/trusted/service_runtime/nacl_syscall_common.h ('k') | src/trusted/service_runtime/sel_main.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698