diff options
Diffstat (limited to 'src/firejail/appimage.c')
-rw-r--r-- | src/firejail/appimage.c | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/src/firejail/appimage.c b/src/firejail/appimage.c index 375d6be24..3f03c28bf 100644 --- a/src/firejail/appimage.c +++ b/src/firejail/appimage.c | |||
@@ -39,7 +39,7 @@ 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 | #ifdef LOOP_CTL_GET_FREE // test for older kernels; this definition is found in /usr/include/linux/loop.h | 43 | #ifdef LOOP_CTL_GET_FREE // test for older kernels; this definition is found in /usr/include/linux/loop.h |
44 | // check appimage_path | 44 | // check appimage_path |
45 | if (access(appimage_path, R_OK) == -1) { | 45 | if (access(appimage_path, R_OK) == -1) { |
@@ -47,6 +47,12 @@ void appimage_set(const char *appimage_path) { | |||
47 | exit(1); | 47 | exit(1); |
48 | } | 48 | } |
49 | 49 | ||
50 | // get appimage type and ELF size | ||
51 | // a value of 0 means we are dealing with a type1 appimage | ||
52 | long unsigned int size = appimage2_size(appimage_path); | ||
53 | if (arg_debug) | ||
54 | printf("AppImage ELF size %lu\n", size); | ||
55 | |||
50 | // open as user to prevent race condition | 56 | // open as user to prevent race condition |
51 | int ffd = open(appimage_path, O_RDONLY|O_CLOEXEC); | 57 | int ffd = open(appimage_path, O_RDONLY|O_CLOEXEC); |
52 | if (ffd == -1) { | 58 | if (ffd == -1) { |
@@ -76,6 +82,15 @@ void appimage_set(const char *appimage_path) { | |||
76 | fprintf(stderr, "Error: cannot configure the loopback device\n"); | 82 | fprintf(stderr, "Error: cannot configure the loopback device\n"); |
77 | exit(1); | 83 | exit(1); |
78 | } | 84 | } |
85 | |||
86 | if (size) { | ||
87 | struct loop_info64 info; | ||
88 | memset(&info, 0, sizeof(struct loop_info64)); | ||
89 | info.lo_offset = size; | ||
90 | if (ioctl(lfd, LOOP_SET_STATUS64, &info) == -1) | ||
91 | errExit("configure appimage offset"); | ||
92 | } | ||
93 | |||
79 | close(lfd); | 94 | close(lfd); |
80 | close(ffd); | 95 | close(ffd); |
81 | EUID_USER(); | 96 | EUID_USER(); |
@@ -100,8 +115,16 @@ void appimage_set(const char *appimage_path) { | |||
100 | if (asprintf(&mode, "mode=700,uid=%d,gid=%d", getuid(), getgid()) == -1) | 115 | if (asprintf(&mode, "mode=700,uid=%d,gid=%d", getuid(), getgid()) == -1) |
101 | errExit("asprintf"); | 116 | errExit("asprintf"); |
102 | EUID_ROOT(); | 117 | EUID_ROOT(); |
103 | if (mount(devloop, mntdir, "iso9660",MS_MGC_VAL|MS_RDONLY, mode) < 0) | 118 | |
104 | errExit("mounting appimage"); | 119 | if (size == 0) { |
120 | if (mount(devloop, mntdir, "iso9660",MS_MGC_VAL|MS_RDONLY, mode) < 0) | ||
121 | errExit("mounting appimage"); | ||
122 | } | ||
123 | else { | ||
124 | if (mount(devloop, mntdir, "squashfs",MS_MGC_VAL|MS_RDONLY, mode) < 0) | ||
125 | errExit("mounting appimage"); | ||
126 | } | ||
127 | |||
105 | if (arg_debug) | 128 | if (arg_debug) |
106 | printf("appimage mounted on %s\n", mntdir); | 129 | printf("appimage mounted on %s\n", mntdir); |
107 | EUID_USER(); | 130 | EUID_USER(); |