diff options
author | Aleksey Manevich <manevich.aleksey@gmail.com> | 2016-08-18 18:03:24 +0300 |
---|---|---|
committer | Aleksey Manevich <manevich.aleksey@gmail.com> | 2016-08-18 18:03:24 +0300 |
commit | 3f69d4f42c45bfca9e68f9c3fec02edd0ae53c07 (patch) | |
tree | 9f33c90d25a3a1c53495fc8159aaa3e5109a045c /src/firejail/no_sandbox.c | |
parent | overlay etc. (diff) | |
download | firejail-3f69d4f42c45bfca9e68f9c3fec02edd0ae53c07.tar.gz firejail-3f69d4f42c45bfca9e68f9c3fec02edd0ae53c07.tar.zst firejail-3f69d4f42c45bfca9e68f9c3fec02edd0ae53c07.zip |
run_no_sandbox fix
Diffstat (limited to 'src/firejail/no_sandbox.c')
-rw-r--r-- | src/firejail/no_sandbox.c | 151 |
1 files changed, 108 insertions, 43 deletions
diff --git a/src/firejail/no_sandbox.c b/src/firejail/no_sandbox.c index 80ed72dca..090c06761 100644 --- a/src/firejail/no_sandbox.c +++ b/src/firejail/no_sandbox.c | |||
@@ -162,54 +162,119 @@ int check_kernel_procs(void) { | |||
162 | void run_no_sandbox(int argc, char **argv) { | 162 | void run_no_sandbox(int argc, char **argv) { |
163 | EUID_ASSERT(); | 163 | EUID_ASSERT(); |
164 | 164 | ||
165 | // build command | 165 | // process limited subset of options |
166 | char *command = NULL; | 166 | int i; |
167 | int allocated = 0; | 167 | for (i = 0; i < argc; i++) { |
168 | if (argc == 1) | 168 | if (strcmp(argv[i], "--csh") == 0) { |
169 | command = "/bin/bash"; | 169 | if (arg_shell_none) { |
170 | else { | 170 | fprintf(stderr, "Error: --shell=none was already specified.\n"); |
171 | // calculate length | 171 | exit(1); |
172 | int len = 0; | 172 | } |
173 | int i; | 173 | if (cfg.shell) { |
174 | for (i = 1; i < argc; i++) { | 174 | fprintf(stderr, "Error: only one default user shell can be specified\n"); |
175 | if (i == 1 && strcmp(argv[i], "-c") == 0) | 175 | exit(1); |
176 | continue; | 176 | } |
177 | if (*argv[i] == '-') | 177 | cfg.shell = "/bin/csh"; |
178 | continue; | ||
179 | break; | ||
180 | } | 178 | } |
181 | int start_index = i; | 179 | else if (strcmp(argv[i], "--zsh") == 0) { |
182 | for (i = start_index; i < argc; i++) | 180 | if (arg_shell_none) { |
183 | len += strlen(argv[i]) + 3; | 181 | fprintf(stderr, "Error: --shell=none was already specified.\n"); |
184 | 182 | exit(1); | |
185 | // allocate | 183 | } |
186 | command = malloc(len + 1); | 184 | if (cfg.shell) { |
187 | if (!command) | 185 | fprintf(stderr, "Error: only one default user shell can be specified\n"); |
188 | errExit("malloc"); | 186 | exit(1); |
189 | memset(command, 0, len + 1); | 187 | } |
190 | allocated = 1; | 188 | cfg.shell = "/bin/zsh"; |
191 | 189 | } | |
192 | // copy | 190 | else if (strcmp(argv[i], "--shell=none") == 0) { |
193 | for (i = start_index; i < argc; i++) { | 191 | arg_shell_none = 1; |
194 | if (strchr(argv[i], '&')) { | 192 | if (cfg.shell) { |
195 | strcat(command, "\""); | 193 | fprintf(stderr, "Error: a shell was already specified\n"); |
196 | strcat(command, argv[i]); | 194 | exit(1); |
197 | strcat(command, "\" "); | 195 | } |
196 | } | ||
197 | else if (strncmp(argv[i], "--shell=", 8) == 0) { | ||
198 | if (arg_shell_none) { | ||
199 | fprintf(stderr, "Error: --shell=none was already specified.\n"); | ||
200 | exit(1); | ||
201 | } | ||
202 | invalid_filename(argv[i] + 8); | ||
203 | |||
204 | if (cfg.shell) { | ||
205 | fprintf(stderr, "Error: only one user shell can be specified\n"); | ||
206 | exit(1); | ||
207 | } | ||
208 | cfg.shell = argv[i] + 8; | ||
209 | |||
210 | if (is_dir(cfg.shell) || strstr(cfg.shell, "..")) { | ||
211 | fprintf(stderr, "Error: invalid shell\n"); | ||
212 | exit(1); | ||
198 | } | 213 | } |
199 | else { | 214 | |
200 | strcat(command, argv[i]); | 215 | // access call checks as real UID/GID, not as effective UID/GID |
201 | strcat(command, " "); | 216 | if(cfg.chrootdir) { |
217 | char *shellpath; | ||
218 | if (asprintf(&shellpath, "%s%s", cfg.chrootdir, cfg.shell) == -1) | ||
219 | errExit("asprintf"); | ||
220 | if (access(shellpath, R_OK)) { | ||
221 | fprintf(stderr, "Error: cannot access shell file in chroot\n"); | ||
222 | exit(1); | ||
223 | } | ||
224 | free(shellpath); | ||
225 | } else if (access(cfg.shell, R_OK)) { | ||
226 | fprintf(stderr, "Error: cannot access shell file\n"); | ||
227 | exit(1); | ||
202 | } | 228 | } |
203 | } | 229 | } |
204 | } | 230 | } |
205 | 231 | ||
206 | // start the program in /bin/sh | 232 | // use $SHELL to get shell used in sandbox |
233 | if (!arg_shell_none && !cfg.shell) { | ||
234 | char *shell = secure_getenv("SHELL"); | ||
235 | if (access(shell, R_OK) == 0) | ||
236 | cfg.shell = shell; | ||
237 | } | ||
238 | // guess shell otherwise | ||
239 | if (!arg_shell_none && !cfg.shell) { | ||
240 | guess_shell(); | ||
241 | if (arg_debug) | ||
242 | printf("Autoselecting %s as shell\n", cfg.shell); | ||
243 | } | ||
244 | if (!arg_shell_none && !cfg.shell) { | ||
245 | fprintf(stderr, "Error: unable to guess your shell, please set explicitly by using --shell option.\n"); | ||
246 | exit(1); | ||
247 | } | ||
248 | |||
249 | int prog_index = 0; | ||
250 | // find first non option arg | ||
251 | for (i = 1; i < argc; i++) { | ||
252 | if (strncmp(argv[i],"--",2) != 0) { | ||
253 | prog_index = i; | ||
254 | break; | ||
255 | } | ||
256 | } | ||
257 | |||
258 | if (!arg_shell_none) { | ||
259 | if (prog_index == 0) { | ||
260 | cfg.command_line = cfg.shell; | ||
261 | cfg.window_title = cfg.shell; | ||
262 | } else { | ||
263 | build_cmdline(&cfg.command_line, &cfg.window_title, argc, argv, prog_index); | ||
264 | } | ||
265 | } | ||
266 | |||
267 | cfg.original_argv = argv; | ||
268 | cfg.original_program_index = prog_index; | ||
269 | |||
270 | char *command; | ||
271 | if (prog_index == 0) | ||
272 | command = cfg.shell; | ||
273 | else | ||
274 | command = argv[prog_index]; | ||
207 | if (!arg_quiet) | 275 | if (!arg_quiet) |
208 | fprintf(stderr, "Warning: an existing sandbox was detected. " | 276 | fprintf(stderr, "Warning: an existing sandbox was detected. " |
209 | "%s will run without any additional sandboxing features in a /bin/sh shell\n", command); | 277 | "%s will run without any additional sandboxing features\n", command); |
210 | int rv = system(command); | 278 | |
211 | (void) rv; | 279 | start_application(); |
212 | if (allocated) | ||
213 | free(command); | ||
214 | exit(1); | ||
215 | } | 280 | } |