summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar Peter Millerchip <pete@millerchipsoftware.com>2015-08-22 15:01:56 +0100
committerLibravatar Peter Millerchip <pete@millerchipsoftware.com>2015-08-22 15:01:56 +0100
commitd798c507fa7c2c212cd0fd6f2f5a46a30bb796c3 (patch)
treee8239bc1b59bc7200b68e0e458e97f4bd1f91a31 /src
parentsupport net none in profile files (diff)
downloadfirejail-d798c507fa7c2c212cd0fd6f2f5a46a30bb796c3.tar.gz
firejail-d798c507fa7c2c212cd0fd6f2f5a46a30bb796c3.tar.zst
firejail-d798c507fa7c2c212cd0fd6f2f5a46a30bb796c3.zip
Implement the expand_home util function
Diffstat (limited to 'src')
-rw-r--r--src/firejail/firejail.h1
-rw-r--r--src/firejail/fs.c13
-rw-r--r--src/firejail/fs_home.c50
-rw-r--r--src/firejail/profile.c10
-rw-r--r--src/firejail/util.c27
5 files changed, 68 insertions, 33 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 3acaeb6fb..83fc7b8d2 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -263,6 +263,7 @@ void check_private_dir(void);
263void update_map(char *mapping, char *map_file); 263void update_map(char *mapping, char *map_file);
264void wait_for_other(int fd); 264void wait_for_other(int fd);
265void notify_other(int fd); 265void notify_other(int fd);
266char *expand_home(const char *path, const char* homedir);
266 267
267// fs_var.c 268// fs_var.c
268void fs_var_log(void); // mounting /var/log 269void fs_var_log(void); // mounting /var/log
diff --git a/src/firejail/fs.c b/src/firejail/fs.c
index 428ea0819..cec170521 100644
--- a/src/firejail/fs.c
+++ b/src/firejail/fs.c
@@ -291,17 +291,8 @@ void fs_blacklist(const char *homedir) {
291 } 291 }
292 292
293 // replace home macro in blacklist array 293 // replace home macro in blacklist array
294 char *new_name = NULL; 294 char *new_name = expand_home(ptr, homedir);
295 if (strncmp(ptr, "${HOME}", 7) == 0) { 295 ptr = new_name;
296 if (asprintf(&new_name, "%s%s", homedir, ptr + 7) == -1)
297 errExit("asprintf");
298 ptr = new_name;
299 }
300 else if (strncmp(ptr, "~/", 2) == 0) {
301 if (asprintf(&new_name, "%s%s", homedir, ptr + 1) == -1)
302 errExit("asprintf");
303 ptr = new_name;
304 }
305 296
306 // expand path macro - look for the file in /bin, /usr/bin, /sbin and /usr/sbin directories 297 // expand path macro - look for the file in /bin, /usr/bin, /sbin and /usr/sbin directories
307 if (strncmp(ptr, "${PATH}", 7) == 0) { 298 if (strncmp(ptr, "${PATH}", 7) == 0) {
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c
index e726d6f10..6f8bef60f 100644
--- a/src/firejail/fs_home.c
+++ b/src/firejail/fs_home.c
@@ -269,9 +269,19 @@ void fs_private(void) {
269static void check_dir_or_file(const char *name) { 269static void check_dir_or_file(const char *name) {
270 assert(name); 270 assert(name);
271 struct stat s; 271 struct stat s;
272 char *fname; 272 char *fname = expand_home(name, cfg.homedir);
273 if (asprintf(&fname, "%s/%s", cfg.homedir, name) == -1) 273 if (!fname) {
274 errExit("asprintf"); 274 fprintf(stderr, "Error: file %s not found.\n", name);
275 exit(1);
276 }
277 if (fname[0] != '/') {
278 // If it doesn't start with '/', it must be relative to homedir
279 char* tmp;
280 if (asprintf(&tmp, "%s/%s", cfg.homedir, fname) == -1)
281 errExit("asprintf");
282 free(fname);
283 fname = tmp;
284 }
275 if (arg_debug) 285 if (arg_debug)
276 printf("Checking %s\n", fname); 286 printf("Checking %s\n", fname);
277 if (stat(fname, &s) == -1) { 287 if (stat(fname, &s) == -1) {
@@ -323,15 +333,15 @@ void fs_check_home_list(void) {
323 333
324// check new private home directory (--private= option) - exit if it fails 334// check new private home directory (--private= option) - exit if it fails
325void fs_check_private_dir(void) { 335void fs_check_private_dir(void) {
326 // if the directory starts with ~, expand the home directory 336 // Expand the home directory
327 if (*cfg.home_private == '~') { 337 char *tmp = expand_home(cfg.home_private, cfg.homedir);
328 char *tmp; 338 cfg.home_private = realpath(tmp, NULL);
329 if (asprintf(&tmp, "%s%s", cfg.homedir, cfg.home_private + 1) == -1) 339 free(tmp);
330 errExit("asprintf");
331 cfg.home_private = tmp;
332 }
333 340
334 if (!is_dir(cfg.home_private) || is_link(cfg.home_private) || strstr(cfg.home_private, "..")) { 341 if (!cfg.home_private
342 || !is_dir(cfg.home_private)
343 || is_link(cfg.home_private)
344 || strstr(cfg.home_private, "..")) {
335 fprintf(stderr, "Error: invalid private directory\n"); 345 fprintf(stderr, "Error: invalid private directory\n");
336 exit(1); 346 exit(1);
337 } 347 }
@@ -371,11 +381,25 @@ static int mkpath(char* file_path, mode_t mode) {
371} 381}
372#endif 382#endif
373 383
374static void duplicate(char *fname) { 384static void duplicate(char *name) {
375 char *cmd; 385 char *cmd;
386
387 char *fname = expand_home(name, cfg.homedir);
388 if (!fname) {
389 fprintf(stderr, "Error: file %s not found.\n", name);
390 exit(1);
391 }
392 if (fname[0] != '/') {
393 // If it doesn't start with '/', it must be relative to homedir
394 char* tmp;
395 if (asprintf(&tmp, "%s/%s", cfg.homedir, fname) == -1)
396 errExit("asprintf");
397 free(fname);
398 fname = tmp;
399 }
376 400
377 // copy the file 401 // copy the file
378 if (asprintf(&cmd, "cp -a --parents %s/%s %s", cfg.homedir, fname, HOME_DIR) == -1) 402 if (asprintf(&cmd, "cp -a --parents %s %s", fname, HOME_DIR) == -1)
379 errExit("asprintf"); 403 errExit("asprintf");
380 if (arg_debug) 404 if (arg_debug)
381 printf("%s\n", cmd); 405 printf("%s\n", cmd);
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index 86db82da0..4341434ac 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -433,15 +433,7 @@ void profile_read(const char *fname, const char *skip1, const char *skip2) {
433 } 433 }
434 434
435 // expand ${HOME}/ in front of the new profile file 435 // expand ${HOME}/ in front of the new profile file
436 char *newprofile2 = NULL; 436 char *newprofile2 = expand_home(newprofile, cfg.homedir);
437 if (strncmp(newprofile, "${HOME}", 7) == 0) {
438 if (asprintf(&newprofile2, "%s%s", cfg.homedir, newprofile + 7) == -1)
439 errExit("asprintf");
440 }
441 else if (strncmp(newprofile, "~/", 2) == 0) {
442 if (asprintf(&newprofile2, "%s%s", cfg.homedir, newprofile + 1) == -1)
443 errExit("asprintf");
444 }
445 437
446 // recursivity 438 // recursivity
447 profile_read((newprofile2)? newprofile2:newprofile, newskip1, newskip2); 439 profile_read((newprofile2)? newprofile2:newprofile, newskip1, newskip2);
diff --git a/src/firejail/util.c b/src/firejail/util.c
index 29eb101fb..59b975b4f 100644
--- a/src/firejail/util.c
+++ b/src/firejail/util.c
@@ -455,3 +455,30 @@ void notify_other(int fd) {
455 fflush(stream); 455 fflush(stream);
456 fclose(stream); 456 fclose(stream);
457} 457}
458
459// This function takes a pathname supplied by the user and expands '~' and
460// '${HOME}' at the start, to refer to a path relative to the user's home
461// directory (supplied).
462// The return value is allocated using malloc and must be freed by the caller.
463// The function returns NULL if there are any errors.
464char *expand_home(const char *path, const char* homedir)
465{
466 assert(path);
467 assert(homedir);
468
469 // Replace home macro
470 char *new_name = NULL;
471 if (strncmp(path, "${HOME}", 7) == 0) {
472 if (asprintf(&new_name, "%s%s", homedir, path + 7) == -1)
473 errExit("asprintf");
474 return new_name;
475 }
476 else if (strncmp(path, "~/", 2) == 0) {
477 if (asprintf(&new_name, "%s%s", homedir, path + 1) == -1)
478 errExit("asprintf");
479 return new_name;
480 }
481
482 return strdup(path);
483}
484