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

Side by Side 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, 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
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. 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 3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file. 4 * found in the LICENSE file.
5 */ 5 */
6 6
7 /* 7 /*
8 * NaCl service run-time, non-platform specific system call helper routines. 8 * NaCl service run-time, non-platform specific system call helper routines.
9 */ 9 */
10 #include <sys/types.h> 10 #include <sys/types.h>
11 #include <sys/stat.h> 11 #include <sys/stat.h>
12 12
13 #include <errno.h> 13 #include <errno.h>
14 #include <stdio.h> 14 #include <stdio.h>
15 #include <string.h>
15 16
16 #include "native_client/src/include/build_config.h" 17 #include "native_client/src/include/build_config.h"
17 18
18 #if NACL_WINDOWS 19 #if NACL_WINDOWS
19 #include <windows.h> 20 #include <windows.h>
20 #endif 21 #endif
21 22
22 #include "native_client/src/trusted/service_runtime/nacl_syscall_common.h" 23 #include "native_client/src/trusted/service_runtime/nacl_syscall_common.h"
23 24
24 #include "native_client/src/include/nacl_macros.h" 25 #include "native_client/src/include/nacl_macros.h"
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 return 0; 85 return 0;
85 } 86 }
86 87
87 int NaClAclBypassChecks = 0; 88 int NaClAclBypassChecks = 0;
88 89
89 void NaClInsecurelyBypassAllAclChecks(void) { 90 void NaClInsecurelyBypassAllAclChecks(void) {
90 NaClLog(LOG_WARNING, "BYPASSING ALL ACL CHECKS\n"); 91 NaClLog(LOG_WARNING, "BYPASSING ALL ACL CHECKS\n");
91 NaClAclBypassChecks = 1; 92 NaClAclBypassChecks = 1;
92 } 93 }
93 94
95 char *NaClRootDir = NULL;
96 size_t NaClRootDirLen = 0;
97
98 #if NACL_WINDOWS
99 int NaClMountRootDir(char *root) {
100 return 0;
101 }
102
103 int NaClSanitizePathLexically(char *path) {
104 /*
105 * TODO(jtolds): this could totally be made to work with Windows, but I'm
106 * unclear what the path separator and drive letter requirements are at this
107 * level.
108 */
109 return 0;
110 }
111 #elif NACL_LINUX || NACL_OSX
112 int NaClMountRootDir(char *root) {
113 NaClRootDir = strdup(root);
114 if (!NaClSanitizePathLexically(NaClRootDir)) {
115 goto fail;
116 }
117 NaClRootDirLen = strlen(NaClRootDir);
118 if (NaClRootDirLen <= 0) {
119 goto fail;
120 }
121 while (NaClRootDirLen > 0 && NaClRootDir[NaClRootDirLen-1] == '/') {
122 NaClRootDir[--NaClRootDirLen] = '\0';
123 }
124 return 1;
125 fail:
126 free(NaClRootDir);
127 NaClRootDir = NULL;
128 return 0;
129 }
130
131 int NaClSanitizePathLexically(char *path) {
132 size_t last_path_sep = 0, prev_sep = 0, next_char = 0;
133 size_t path_len = strlen(path);
134
135 /*
136 * Overall strategy:
137 * We're going to keep track of the last path separator we saw. Each time
138 * we see a new path separator, we'll mark off the last path element, then
139 * decide what to do with it. We'll either:
140 * * decide the path element was empty (a double slash) and slide everything
141 * back a byte.
142 * * decide the path element was '.' and slide everything back two bytes.
143 * * decide the path element is '..' and it's immediately after the root, so
144 * we'll slide everything back three bytes
145 * * decide the path element is '..' and it's not after the root, so we'll
146 * go find the previous path separator and slide everything back to it.
147 * * decide the path element is fine and continue with the new path
148 * separator.
149 *
150 * This strategy avoids mallocs.
151 */
152
153 /*
154 * This algorithm assumes that there is always at least space for
155 * "/\0", and the path is absolute, so make sure strlen(path) >= 1 and the
156 * path starts with '/'.
157 */
158 if (path_len <= 0 || path[0] != '/') {
159 return 0;
160 }
161
162 /*
163 * For the purposes of this algorithm, '/' and '\0' are both path separators.
164 * last_path_sep refers to the index of the last path separator (either one
165 * of the above two bytes) that we've seen so far.
166 *
167 * We'll loop as long as the last path separator isn't the null byte and do
168 * some cleanup after.
169 */
170 while (path[last_path_sep] != '\0') {
171
172 /*
173 * Let's find the full next path element.
174 */
175 next_char = last_path_sep + 1;
176 while (path[next_char] != '/' && path[next_char] != '\0') {
177 next_char++;
178 }
179
180 /* Check if the path element was empty (double-separator case) */
181 if (next_char == last_path_sep + 1) {
182 if (path[next_char] == '\0') {
183 /*
184 * Special '/\0' end case, allow a double separator when the second one
185 * is a null byte. This allows us to sanitize paths with or without
186 * trailing slashes.
187 */
188 last_path_sep = next_char;
189 continue;
190 }
191 /* Normal double-separator case. Just slide everything back one. */
192 memmove(path + last_path_sep, path + last_path_sep + 1,
193 (path_len + 1) - (last_path_sep + 1));
194 path_len -= 1;
195 continue;
196 }
197
198 /* Check if the last path element was "." */
199 if (next_char == last_path_sep + 2 && path[last_path_sep + 1] == '.') {
200 /* Slide everything back two */
201 memmove(path + last_path_sep, path + last_path_sep + 2,
202 (path_len + 1) - (last_path_sep + 2));
203 path_len -= 2;
204 continue;
205 }
206
207 /* Check if the last path element was ".." */
208 if (next_char == last_path_sep + 3 && path[last_path_sep + 1] == '.' &&
209 path[last_path_sep + 2] == '.') {
210 if (last_path_sep == 0) {
211 /* '..' after root case, just slide everything back three. */
212 memmove(path + last_path_sep, path + last_path_sep + 3,
213 (path_len + 1) - (last_path_sep + 3));
214 path_len -= 3;
215 continue;
216 }
217 /*
218 * Normal '..' case. Go find the previous path separator and then slide
219 * everything back to it.
220 */
221 prev_sep = last_path_sep - 1;
222 while (path[prev_sep] != '/') {
223 prev_sep--;
224 }
225 memmove(path + prev_sep, path + last_path_sep + 3,
226 (path_len + 1) - (last_path_sep + 3));
227 path_len -= (last_path_sep + 3 - prev_sep);
228 last_path_sep = prev_sep;
229 continue;
230 }
231
232 /* Default path element case. */
233 last_path_sep = next_char;
234 }
235
236 /*
237 * Cleanup scenario: whenever we slide something back, we overwrite the
238 * last path separator. For example, in the "/a/.\0" case, we slide
239 * everything starting at byte 4 back over byte 3, so the result is "/a\0".
240 * In the case of a full path "/.\0", the end result ends up being "\0", so
241 * we need to fix up root paths like this specially.
242 * N.B.: we know we have enough space in the buffer for this.
243 */
244 if (last_path_sep == 0) {
245 path[0] = '/';
246 path[1] = '\0';
247 }
248
249 return 1;
250 }
251
252 #else
253 #error Unsupported platform
254 #endif
255
256 int NaClFileAccessEnabled(void) {
257 return NaClAclBypassChecks || (NaClRootDir != NULL);
258 }
259
94 int NaClHighResolutionTimerEnabled(void) { 260 int NaClHighResolutionTimerEnabled(void) {
95 return NaClAclBypassChecks; 261 return NaClAclBypassChecks;
96 } 262 }
97 263
98 int32_t NaClSysGetpid(struct NaClAppThread *natp) { 264 int32_t NaClSysGetpid(struct NaClAppThread *natp) {
99 int32_t pid; 265 int32_t pid;
100 UNREFERENCED_PARAMETER(natp); 266 UNREFERENCED_PARAMETER(natp);
101 267
102 if (NaClAclBypassChecks) { 268 if (NaClAclBypassChecks) {
103 pid = GETPID(); 269 pid = GETPID();
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 #else 864 #else
699 #error Unsupported platform 865 #error Unsupported platform
700 #endif 866 #endif
701 break; 867 break;
702 } 868 }
703 case NACL_ABI__SC_PAGESIZE: { 869 case NACL_ABI__SC_PAGESIZE: {
704 result_value = 1 << 16; /* always 64k pages */ 870 result_value = 1 << 16; /* always 64k pages */
705 break; 871 break;
706 } 872 }
707 case NACL_ABI__SC_NACL_FILE_ACCESS_ENABLED: { 873 case NACL_ABI__SC_NACL_FILE_ACCESS_ENABLED: {
708 result_value = NaClAclBypassChecks; 874 result_value = NaClFileAccessEnabled();
709 break; 875 break;
710 } 876 }
711 case NACL_ABI__SC_NACL_LIST_MAPPINGS_ENABLED: { 877 case NACL_ABI__SC_NACL_LIST_MAPPINGS_ENABLED: {
712 result_value = nap->enable_list_mappings; 878 result_value = nap->enable_list_mappings;
713 break; 879 break;
714 } 880 }
715 case NACL_ABI__SC_NACL_PNACL_MODE: { 881 case NACL_ABI__SC_NACL_PNACL_MODE: {
716 result_value = nap->pnacl_mode; 882 result_value = nap->pnacl_mode;
717 break; 883 break;
718 } 884 }
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1007 return NaClSysClockGetCommon(natp, clk_id, (uintptr_t) tsp, 1173 return NaClSysClockGetCommon(natp, clk_id, (uintptr_t) tsp,
1008 NaClClockGetRes, 1); 1174 NaClClockGetRes, 1);
1009 } 1175 }
1010 1176
1011 int32_t NaClSysClockGetTime(struct NaClAppThread *natp, 1177 int32_t NaClSysClockGetTime(struct NaClAppThread *natp,
1012 int clk_id, 1178 int clk_id,
1013 uint32_t tsp) { 1179 uint32_t tsp) {
1014 return NaClSysClockGetCommon(natp, clk_id, (uintptr_t) tsp, 1180 return NaClSysClockGetCommon(natp, clk_id, (uintptr_t) tsp,
1015 NaClClockGetTime, 0); 1181 NaClClockGetTime, 0);
1016 } 1182 }
OLDNEW
« 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