aboutsummaryrefslogtreecommitdiffstats
path: root/src/firejail/ls.c
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2016-09-22 13:40:32 -0400
committerLibravatar netblue30 <netblue30@yahoo.com>2016-09-22 13:40:32 -0400
commit6163ff2a6fd8fa0858ff4f7c57d45dc57c8f39b1 (patch)
tree38ef7124e4706eca260adfca467890f6f6edff44 /src/firejail/ls.c
parent--get fixes (diff)
downloadfirejail-6163ff2a6fd8fa0858ff4f7c57d45dc57c8f39b1.tar.gz
firejail-6163ff2a6fd8fa0858ff4f7c57d45dc57c8f39b1.tar.zst
firejail-6163ff2a6fd8fa0858ff4f7c57d45dc57c8f39b1.zip
add files to sandbox container (--put)
Diffstat (limited to 'src/firejail/ls.c')
-rw-r--r--src/firejail/ls.c187
1 files changed, 152 insertions, 35 deletions
diff --git a/src/firejail/ls.c b/src/firejail/ls.c
index 4c1992278..14991ba94 100644
--- a/src/firejail/ls.c
+++ b/src/firejail/ls.c
@@ -185,7 +185,7 @@ static void print_directory(const char *path) {
185 free(namelist); 185 free(namelist);
186} 186}
187 187
188void sandboxfs_name(int op, const char *name, const char *path) { 188void sandboxfs_name(int op, const char *name, const char *path1, const char *path2) {
189 EUID_ASSERT(); 189 EUID_ASSERT();
190 190
191 if (!name || strlen(name) == 0) { 191 if (!name || strlen(name) == 0) {
@@ -198,10 +198,29 @@ void sandboxfs_name(int op, const char *name, const char *path) {
198 exit(1); 198 exit(1);
199 } 199 }
200 200
201 sandboxfs(op, pid, path); 201 sandboxfs(op, pid, path1, path2);
202} 202}
203 203
204void sandboxfs(int op, pid_t pid, const char *path) { 204char *expand_path(const char *path) {
205 char *fname = NULL;
206 if (*path == '/') {
207 fname = strdup(path);
208 if (!fname)
209 errExit("strdup");
210 }
211 else if (*path == '~') {
212 if (asprintf(&fname, "%s%s", cfg.homedir, path + 1) == -1)
213 errExit("asprintf");
214 }
215 else {
216 // assume the file is in current working directory
217 if (asprintf(&fname, "%s/%s", cfg.cwd, path) == -1)
218 errExit("asprintf");
219 }
220 return fname;
221}
222
223void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) {
205 EUID_ASSERT(); 224 EUID_ASSERT();
206 225
207 // if the pid is that of a firejail process, use the pid of the first child process 226 // if the pid is that of a firejail process, use the pid of the first child process
@@ -228,22 +247,17 @@ void sandboxfs(int op, pid_t pid, const char *path) {
228 } 247 }
229 } 248 }
230 249
231 // full path or file in current directory? 250 // expand paths
232 char *fname; 251 char *fname1 = expand_path(path1);;
233 if (*path == '/') { 252 char *fname2 = NULL;
234 fname = strdup(path); 253 if (path2 != NULL) {
235 if (!fname) 254 fname2 = expand_path(path2);
236 errExit("strdup");
237 } 255 }
238 else if (*path == '~') { 256 if (arg_debug) {
239 if (asprintf(&fname, "%s%s", cfg.homedir, path + 1) == -1) 257 printf("file1 %s\n", fname1);
240 errExit("asprintf"); 258 printf("file2 %s\n", fname2);
241 } 259 }
242 else { 260
243 fprintf(stderr, "Error: Cannot access %s\n", path);
244 exit(1);
245 }
246
247 // sandbox root directory 261 // sandbox root directory
248 char *rootdir; 262 char *rootdir;
249 if (asprintf(&rootdir, "/proc/%d/root", pid) == -1) 263 if (asprintf(&rootdir, "/proc/%d/root", pid) == -1)
@@ -260,21 +274,21 @@ void sandboxfs(int op, pid_t pid, const char *path) {
260 // drop privileges 274 // drop privileges
261 drop_privs(0); 275 drop_privs(0);
262 276
263 if (access(fname, R_OK) == -1) { 277 if (access(fname1, R_OK) == -1) {
264 fprintf(stderr, "Error: Cannot access %s\n", fname); 278 fprintf(stderr, "Error: Cannot access %s\n", fname1);
265 exit(1); 279 exit(1);
266 } 280 }
267 281
268 // list directory contents 282 // list directory contents
269 struct stat s; 283 struct stat s;
270 if (stat(fname, &s) == -1) { 284 if (stat(fname1, &s) == -1) {
271 fprintf(stderr, "Error: Cannot access %s\n", fname); 285 fprintf(stderr, "Error: Cannot access %s\n", fname1);
272 exit(1); 286 exit(1);
273 } 287 }
274 if (S_ISDIR(s.st_mode)) { 288 if (S_ISDIR(s.st_mode)) {
275 char *rp = realpath(fname, NULL); 289 char *rp = realpath(fname1, NULL);
276 if (!rp) { 290 if (!rp) {
277 fprintf(stderr, "Error: Cannot access %s\n", fname); 291 fprintf(stderr, "Error: Cannot access %s\n", fname1);
278 exit(1); 292 exit(1);
279 } 293 }
280 if (arg_debug) 294 if (arg_debug)
@@ -289,9 +303,9 @@ void sandboxfs(int op, pid_t pid, const char *path) {
289 free(dir); 303 free(dir);
290 } 304 }
291 else { 305 else {
292 char *rp = realpath(fname, NULL); 306 char *rp = realpath(fname1, NULL);
293 if (!rp) { 307 if (!rp) {
294 fprintf(stderr, "Error: Cannot access %s\n", fname); 308 fprintf(stderr, "Error: Cannot access %s\n", fname1);
295 exit(1); 309 exit(1);
296 } 310 }
297 if (arg_debug) 311 if (arg_debug)
@@ -312,15 +326,18 @@ void sandboxfs(int op, pid_t pid, const char *path) {
312 else if (op == SANDBOX_FS_GET) { 326 else if (op == SANDBOX_FS_GET) {
313 // check source file (sandbox) 327 // check source file (sandbox)
314 char *src_fname; 328 char *src_fname;
315 if (asprintf(&src_fname, "%s%s", rootdir, fname) == -1) 329 if (asprintf(&src_fname, "%s%s", rootdir, fname1) == -1)
316 errExit("asprintf"); 330 errExit("asprintf");
317 EUID_ROOT(); 331 EUID_ROOT();
318 struct stat s; 332 struct stat s;
319 if (stat(src_fname, &s) == -1) { 333 if (stat(src_fname, &s) == -1) {
320 fprintf(stderr, "Error: Cannot access %s\n", fname); 334 fprintf(stderr, "Error: Cannot access %s\n", fname1);
335 exit(1);
336 }
337 if (is_dir(src_fname)) {
338 fprintf(stderr, "Error: source file name is a directory\n");
321 exit(1); 339 exit(1);
322 } 340 }
323
324 341
325 // try to open the source file - we need to chroot 342 // try to open the source file - we need to chroot
326 pid_t child = fork(); 343 pid_t child = fork();
@@ -337,8 +354,8 @@ void sandboxfs(int op, pid_t pid, const char *path) {
337 drop_privs(0); 354 drop_privs(0);
338 355
339 // try to read the file 356 // try to read the file
340 if (access(fname, R_OK) == -1) { 357 if (access(fname1, R_OK) == -1) {
341 fprintf(stderr, "Error: Cannot read %s\n", fname); 358 fprintf(stderr, "Error: Cannot read %s\n", fname1);
342 exit(1); 359 exit(1);
343 } 360 }
344 exit(0); 361 exit(0);
@@ -353,9 +370,9 @@ void sandboxfs(int op, pid_t pid, const char *path) {
353 EUID_USER(); 370 EUID_USER();
354 371
355 // check destination file (host) 372 // check destination file (host)
356 char *dest_fname = strrchr(fname, '/'); 373 char *dest_fname = strrchr(fname1, '/');
357 if (!dest_fname || *(++dest_fname) == '\0') { 374 if (!dest_fname || *(++dest_fname) == '\0') {
358 fprintf(stderr, "Error: invalid file name %s\n", fname); 375 fprintf(stderr, "Error: invalid file name %s\n", fname1);
359 exit(1); 376 exit(1);
360 } 377 }
361 378
@@ -376,7 +393,7 @@ void sandboxfs(int op, pid_t pid, const char *path) {
376 fclose(fp); 393 fclose(fp);
377 exit(0); 394 exit(0);
378 } 395 }
379 396
380 // wait for the child to finish 397 // wait for the child to finish
381 int status = 0; 398 int status = 0;
382 waitpid(child, &status, 0); 399 waitpid(child, &status, 0);
@@ -392,6 +409,8 @@ void sandboxfs(int op, pid_t pid, const char *path) {
392 } 409 }
393 410
394 // copy file 411 // copy file
412 if (arg_debug)
413 printf("copy %s to %s\n", src_fname, dest_fname);
395 EUID_ROOT(); 414 EUID_ROOT();
396 if (copy_file(src_fname, dest_fname, getuid(), getgid(), 0644)) 415 if (copy_file(src_fname, dest_fname, getuid(), getgid(), 0644))
397 fprintf(stderr, "Error: transfer failed\n"); 416 fprintf(stderr, "Error: transfer failed\n");
@@ -399,8 +418,106 @@ void sandboxfs(int op, pid_t pid, const char *path) {
399 printf("Transfer complete\n"); 418 printf("Transfer complete\n");
400 EUID_USER(); 419 EUID_USER();
401 } 420 }
402 421 // get file from host and store it in the sandbox
403 free(fname); 422 else if (op == SANDBOX_FS_PUT) {
423 // verify the source file
424 const char *src_fname = path1;
425 struct stat s;
426 if (stat(src_fname, &s) == -1) {
427 fprintf(stderr, "Error: Cannot access %s\n", fname1);
428 exit(1);
429 }
430 if (is_dir(src_fname)) {
431 fprintf(stderr, "Error: source file name is a directory\n");
432 exit(1);
433 }
434
435 // try to open the source file
436 pid_t child = fork();
437 if (child < 0)
438 errExit("fork");
439 if (child == 0) {
440 // drop privileges
441 drop_privs(0);
442
443 // try to read the file
444 if (access(src_fname, R_OK) == -1) {
445 fprintf(stderr, "Error: Cannot read %s\n", src_fname);
446 exit(1);
447 }
448 exit(0);
449 }
450
451 // wait for the child to finish
452 int status = 0;
453 waitpid(child, &status, 0);
454 if (WIFEXITED(status) && WEXITSTATUS(status) == 0);
455 else
456 exit(1);
457
458 // check destination file (sandbox)
459 char *dest_fname;
460 if (asprintf(&dest_fname, "%s%s", rootdir, fname2) == -1)
461 errExit("asprintf");
462 EUID_ROOT();
463 if (is_dir(dest_fname)) {
464 fprintf(stderr, "Error: destination file name is a directory inside the sandbox\n");
465 exit(1);
466 }
467
468 // check write access on destination
469 child = fork();
470 if (child < 0)
471 errExit("fork");
472 if (child == 0) {
473 // chroot
474 if (chroot(rootdir) < 0)
475 errExit("chroot");
476 if (chdir("/") < 0)
477 errExit("chdir");
478
479 // drop privileges
480 drop_privs(0);
481
482 if (access(path2, F_OK) == -1) {
483 FILE *fp = fopen(path2, "w");
484 if (!fp) {
485 fprintf(stderr, "Error: cannot create %s\n", path2);
486 exit(1);
487 }
488 fclose(fp);
489 }
490 else {
491 if (access(path2, W_OK) == -1) {
492 fprintf(stderr, "Error: cannot write %s\n", path2);
493 exit(1);
494 }
495 }
496
497 exit(0);
498 }
499
500 // wait for the child to finish
501 status = 0;
502 waitpid(child, &status, 0);
503 if (WIFEXITED(status) && WEXITSTATUS(status) == 0);
504 else
505 exit(1);
506
507 // copy file
508 if (arg_debug)
509 printf("copy %s to %s\n", src_fname, dest_fname);
510 EUID_ROOT();
511 if (copy_file(src_fname, dest_fname, getuid(), getgid(), 0644))
512 fprintf(stderr, "Error: transfer failed\n");
513 else
514 printf("Transfer complete\n");
515 EUID_USER();
516 }
517
518 if (fname2)
519 free(fname2);
520 free(fname1);
404 free(rootdir); 521 free(rootdir);
405 522
406 exit(0); 523 exit(0);