aboutsummaryrefslogtreecommitdiffstats
path: root/src/firejail/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/firejail/main.c')
-rw-r--r--src/firejail/main.c51
1 files changed, 43 insertions, 8 deletions
diff --git a/src/firejail/main.c b/src/firejail/main.c
index 1e2488062..d00147c74 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -26,7 +26,6 @@
26#include <sys/mount.h> 26#include <sys/mount.h>
27#include <sys/wait.h> 27#include <sys/wait.h>
28#include <sys/stat.h> 28#include <sys/stat.h>
29#include <fcntl.h>
30#include <dirent.h> 29#include <dirent.h>
31#include <pwd.h> 30#include <pwd.h>
32#include <errno.h> 31#include <errno.h>
@@ -38,6 +37,11 @@
38#include <net/if.h> 37#include <net/if.h>
39#include <sys/utsname.h> 38#include <sys/utsname.h>
40 39
40#include <fcntl.h>
41#ifndef O_PATH
42#define O_PATH 010000000
43#endif
44
41#ifdef __ia64__ 45#ifdef __ia64__
42/* clone(2) has a different interface on ia64, as it needs to know 46/* clone(2) has a different interface on ia64, as it needs to know
43 the size of the stack */ 47 the size of the stack */
@@ -242,6 +246,41 @@ static pid_t require_pid(const char *name) {
242 return pid; 246 return pid;
243} 247}
244 248
249// return 1 if there is a link somewhere in path of directory
250static int has_link(const char *dir) {
251 assert(dir);
252 int fd = safe_fd(dir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
253 if (fd == -1) {
254 if (errno == ENOTDIR && is_dir(dir))
255 return 1;
256 }
257 else
258 close(fd);
259 return 0;
260}
261
262static void build_cfg_homedir(const char *dir) {
263 EUID_ASSERT();
264 assert(dir);
265 if (dir[0] != '/') {
266 fprintf(stderr, "Error: invalid user directory \"%s\"\n", dir);
267 exit(1);
268 }
269 // symlinks are rejected in many places, provide a solution for home directories
270 if (checkcfg(CFG_HOMEDIR_SYMLINK)) {
271 cfg.homedir = realpath(dir, NULL);
272 if (cfg.homedir)
273 return;
274 }
275 else if (has_link(dir)) {
276 fprintf(stderr, "Error: path of user directory contains a symbolic link. "
277 "Please provide resolved path in password database (/etc/passwd) "
278 "or enable symbolic link resolution in Firejail configuration file.\n");
279 exit(1);
280 }
281 cfg.homedir = clean_pathname(dir);
282}
283
245// init configuration 284// init configuration
246static void init_cfg(int argc, char **argv) { 285static void init_cfg(int argc, char **argv) {
247 EUID_ASSERT(); 286 EUID_ASSERT();
@@ -265,15 +304,12 @@ static void init_cfg(int argc, char **argv) {
265 errExit("strdup"); 304 errExit("strdup");
266 305
267 // build home directory name 306 // build home directory name
268 cfg.homedir = NULL; 307 if (pw->pw_dir == NULL) {
269 if (pw->pw_dir != NULL) {
270 cfg.homedir = clean_pathname(pw->pw_dir);
271 assert(cfg.homedir);
272 }
273 else {
274 fprintf(stderr, "Error: user %s doesn't have a user directory assigned\n", cfg.username); 308 fprintf(stderr, "Error: user %s doesn't have a user directory assigned\n", cfg.username);
275 exit(1); 309 exit(1);
276 } 310 }
311 build_cfg_homedir(pw->pw_dir);
312 assert(cfg.homedir);
277 313
278 cfg.cwd = getcwd(NULL, 0); 314 cfg.cwd = getcwd(NULL, 0);
279 if (!cfg.cwd && errno != ENOENT) 315 if (!cfg.cwd && errno != ENOENT)
@@ -926,7 +962,6 @@ int main(int argc, char **argv) {
926 962
927 // check if the user is allowed to use firejail 963 // check if the user is allowed to use firejail
928 init_cfg(argc, argv); 964 init_cfg(argc, argv);
929 assert(cfg.homedir);
930 965
931 // get starting timestamp, process --quiet 966 // get starting timestamp, process --quiet
932 start_timestamp = getticks(); 967 start_timestamp = getticks();