diff options
-rw-r--r-- | src/firejail/appimage.c | 24 | ||||
-rw-r--r-- | src/firejail/firejail.h | 23 |
2 files changed, 36 insertions, 11 deletions
diff --git a/src/firejail/appimage.c b/src/firejail/appimage.c index db9382dc3..513a5a8a2 100644 --- a/src/firejail/appimage.c +++ b/src/firejail/appimage.c | |||
@@ -39,15 +39,20 @@ void appimage_set(const char *appimage_path) { | |||
39 | assert(appimage_path); | 39 | assert(appimage_path); |
40 | assert(devloop == NULL); // don't call this twice! | 40 | assert(devloop == NULL); // don't call this twice! |
41 | EUID_ASSERT(); | 41 | EUID_ASSERT(); |
42 | 42 | ||
43 | // check appimage_path | 43 | // check appimage_path |
44 | if (access(appimage_path, R_OK) == -1) { | 44 | if (access(appimage_path, R_OK) == -1) { |
45 | fprintf(stderr, "Error: cannot access AppImage file\n"); | 45 | fprintf(stderr, "Error: cannot access AppImage file\n"); |
46 | exit(1); | 46 | exit(1); |
47 | } | 47 | } |
48 | 48 | ||
49 | // open as user to prevent race condition | ||
50 | int ffd = open(appimage_path, O_RDONLY|O_CLOEXEC); | ||
51 | if (ffd == -1) | ||
52 | errExit("open"); | ||
53 | |||
49 | EUID_ROOT(); | 54 | EUID_ROOT(); |
50 | 55 | ||
51 | // find or allocate a free loop device to use | 56 | // find or allocate a free loop device to use |
52 | int cfd = open("/dev/loop-control", O_RDWR); | 57 | int cfd = open("/dev/loop-control", O_RDWR); |
53 | int devnr = ioctl(cfd, LOOP_CTL_GET_FREE); | 58 | int devnr = ioctl(cfd, LOOP_CTL_GET_FREE); |
@@ -59,7 +64,6 @@ void appimage_set(const char *appimage_path) { | |||
59 | if (asprintf(&devloop, "/dev/loop%d", devnr) == -1) | 64 | if (asprintf(&devloop, "/dev/loop%d", devnr) == -1) |
60 | errExit("asprintf"); | 65 | errExit("asprintf"); |
61 | 66 | ||
62 | int ffd = open(appimage_path, O_RDONLY|O_CLOEXEC); | ||
63 | int lfd = open(devloop, O_RDONLY); | 67 | int lfd = open(devloop, O_RDONLY); |
64 | if (ioctl(lfd, LOOP_SET_FD, ffd) == -1) { | 68 | if (ioctl(lfd, LOOP_SET_FD, ffd) == -1) { |
65 | fprintf(stderr, "Error: cannot configure the loopback device\n"); | 69 | fprintf(stderr, "Error: cannot configure the loopback device\n"); |
@@ -68,22 +72,22 @@ void appimage_set(const char *appimage_path) { | |||
68 | close(lfd); | 72 | close(lfd); |
69 | close(ffd); | 73 | close(ffd); |
70 | 74 | ||
75 | EUID_USER(); | ||
76 | |||
77 | // creates directory with perms 0700 | ||
71 | char dirname[] = "/tmp/firejail-mnt-XXXXXX"; | 78 | char dirname[] = "/tmp/firejail-mnt-XXXXXX"; |
72 | mntdir = strdup(mkdtemp(dirname)); | 79 | mntdir = strdup(mkdtemp(dirname)); |
73 | if (mntdir == NULL) { | 80 | if (mntdir == NULL) { |
74 | fprintf(stderr, "Error: cannot create temporary directory\n"); | 81 | fprintf(stderr, "Error: cannot create temporary directory\n"); |
75 | exit(1); | 82 | exit(1); |
76 | } | 83 | } |
77 | mkdir(mntdir, 755); | 84 | ASSERT_PERMS(mntdir, getuid(), getgid(), 0700); |
78 | if (chown(mntdir, getuid(), getgid()) == -1) | ||
79 | errExit("chown"); | ||
80 | if (chmod(mntdir, 755) == -1) | ||
81 | errExit("chmod"); | ||
82 | 85 | ||
83 | char *mode; | 86 | char *mode; |
84 | if (asprintf(&mode, "mode=755,uid=%d,gid=%d", getuid(), getgid()) == -1) | 87 | if (asprintf(&mode, "mode=700,uid=%d,gid=%d", getuid(), getgid()) == -1) |
85 | errExit("asprintf"); | 88 | errExit("asprintf"); |
86 | 89 | ||
90 | EUID_ROOT(); | ||
87 | if (mount(devloop, mntdir, "iso9660",MS_MGC_VAL|MS_RDONLY, mode) < 0) | 91 | if (mount(devloop, mntdir, "iso9660",MS_MGC_VAL|MS_RDONLY, mode) < 0) |
88 | errExit("mounting appimage"); | 92 | errExit("mounting appimage"); |
89 | 93 | ||
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index abbaa807c..a3b573acc 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -75,6 +75,27 @@ | |||
75 | #define DEFAULT_ROOT_PROFILE "server" | 75 | #define DEFAULT_ROOT_PROFILE "server" |
76 | #define MAX_INCLUDE_LEVEL 6 // include levels in profile files | 76 | #define MAX_INCLUDE_LEVEL 6 // include levels in profile files |
77 | 77 | ||
78 | |||
79 | #define ASSERT_PERMS(file, uid, gid, mode) \ | ||
80 | do { \ | ||
81 | assert(file);\ | ||
82 | struct stat s;\ | ||
83 | if (stat(file, &s) == -1) errExit("stat");\ | ||
84 | assert(s.st_uid == uid && s.st_gid == gid && (s.st_mode & 07777) == mode);\ | ||
85 | } while (0) | ||
86 | #define ASSERT_PERMS_FD(fd, uid, gid, mode) \ | ||
87 | do { \ | ||
88 | struct stat s;\ | ||
89 | if (stat(fd, &s) == -1) errExit("stat");\ | ||
90 | assert(s.st_uid == uid && s.st_gid == gid && (s.st_mode & 07777) == mode);\ | ||
91 | } while (0) | ||
92 | #define ASSERT_PERMS_STREAM(file, uid, gid, mode) \ | ||
93 | do { \ | ||
94 | int fd = fileno(file);\ | ||
95 | if (fd == -1) errExit("fileno");\ | ||
96 | ASSERT_PERMS_FD(fd, uid, gid, mode);\ | ||
97 | } while (0) | ||
98 | |||
78 | // main.c | 99 | // main.c |
79 | typedef struct bridge_t { | 100 | typedef struct bridge_t { |
80 | // on the host | 101 | // on the host |
@@ -386,7 +407,7 @@ void logsignal(int s); | |||
386 | void logmsg(const char *msg); | 407 | void logmsg(const char *msg); |
387 | void logargs(int argc, char **argv) ; | 408 | void logargs(int argc, char **argv) ; |
388 | void logerr(const char *msg); | 409 | void logerr(const char *msg); |
389 | int copy_file(const char *srcname, const char *destname); | 410 | int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode); |
390 | int is_dir(const char *fname); | 411 | int is_dir(const char *fname); |
391 | int is_link(const char *fname); | 412 | int is_link(const char *fname); |
392 | char *line_remove_spaces(const char *buf); | 413 | char *line_remove_spaces(const char *buf); |