diff options
author | netblue30 <netblue30@yahoo.com> | 2016-06-05 10:38:02 -0400 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2016-06-05 10:38:02 -0400 |
commit | a4444baae73f99dc57b6eb337182f26c553b0094 (patch) | |
tree | 78af4aa55c16b6db787ddddb59714829e99fdded /src | |
parent | networking fixes (diff) | |
download | firejail-a4444baae73f99dc57b6eb337182f26c553b0094.tar.gz firejail-a4444baae73f99dc57b6eb337182f26c553b0094.tar.zst firejail-a4444baae73f99dc57b6eb337182f26c553b0094.zip |
appimage support
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/appimage.c | 94 | ||||
-rw-r--r-- | src/firejail/firejail.h | 2 | ||||
-rw-r--r-- | src/firejail/main.c | 29 | ||||
-rw-r--r-- | src/firejail/usage.c | 1 | ||||
-rw-r--r-- | src/man/firejail.txt | 13 |
5 files changed, 136 insertions, 3 deletions
diff --git a/src/firejail/appimage.c b/src/firejail/appimage.c new file mode 100644 index 000000000..e25d50a2d --- /dev/null +++ b/src/firejail/appimage.c | |||
@@ -0,0 +1,94 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014-2016 Firejail Authors | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | // http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=770fe30a46a12b6fb6b63fbe1737654d28e84844 | ||
21 | // sudo mount -o loop krita-3.0-x86_64.appimage mnt | ||
22 | |||
23 | #include "firejail.h" | ||
24 | #include <sys/types.h> | ||
25 | #include <sys/stat.h> | ||
26 | #include <sys/mount.h> | ||
27 | #include <fcntl.h> | ||
28 | #include <linux/loop.h> | ||
29 | |||
30 | |||
31 | |||
32 | char *appimage_set(const char *appimage_path) { | ||
33 | assert(appimage_path); | ||
34 | EUID_ASSERT(); | ||
35 | |||
36 | // check appimage_path | ||
37 | if (access(appimage_path, R_OK) == -1) { | ||
38 | fprintf(stderr, "Error: cannot access AppImage file\n"); | ||
39 | exit(1); | ||
40 | } | ||
41 | |||
42 | EUID_ROOT(); | ||
43 | |||
44 | // find or allocate a free loop device to use | ||
45 | int cfd = open("/dev/loop-control", O_RDWR); | ||
46 | int devnr = ioctl(cfd, LOOP_CTL_GET_FREE); | ||
47 | if (devnr == -1) { | ||
48 | fprintf(stderr, "Error: cannot allocate a new loopback device\n"); | ||
49 | exit(1); | ||
50 | } | ||
51 | close(cfd); | ||
52 | char *devloop; | ||
53 | if (asprintf(&devloop, "/dev/loop%d", devnr) == -1) | ||
54 | errExit("asprintf"); | ||
55 | |||
56 | int ffd = open(appimage_path, O_RDONLY|O_CLOEXEC); | ||
57 | int lfd = open(devloop, O_RDONLY); | ||
58 | if (ioctl(lfd, LOOP_SET_FD, ffd) == -1) { | ||
59 | fprintf(stderr, "Error: cannot configure the loopback device\n"); | ||
60 | exit(1); | ||
61 | } | ||
62 | close(lfd); | ||
63 | close(ffd); | ||
64 | |||
65 | char dirname[] = "/tmp/firejail-mnt-XXXXXX"; | ||
66 | char *mntdir = strdup(mkdtemp(dirname)); | ||
67 | if (mntdir == NULL) { | ||
68 | fprintf(stderr, "Error: cannot create temporary directory\n"); | ||
69 | exit(1); | ||
70 | } | ||
71 | mkdir(mntdir, 755); | ||
72 | chown(mntdir, getuid(), getgid()); | ||
73 | chmod(mntdir, 755); | ||
74 | |||
75 | char *mode; | ||
76 | if (asprintf(&mode, "mode=755,uid=%d,gid=%d", getuid(), getgid()) == -1) | ||
77 | errExit("asprintf"); | ||
78 | |||
79 | if (mount(devloop, mntdir, "iso9660",MS_MGC_VAL|MS_RDONLY, mode) < 0) | ||
80 | errExit("mounting appimage"); | ||
81 | |||
82 | if (arg_debug) | ||
83 | printf("appimage mounted on %s\n", mntdir); | ||
84 | EUID_USER(); | ||
85 | |||
86 | // build new command line | ||
87 | if (asprintf(&cfg.command_line, "%s/AppRun", mntdir) == -1) | ||
88 | errExit("asprintf"); | ||
89 | |||
90 | free(devloop); | ||
91 | free(mode); | ||
92 | |||
93 | return mntdir; | ||
94 | } | ||
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index b0a3ac90d..00674c047 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -575,6 +575,8 @@ int checkcfg(int val); | |||
575 | void fs_rdwr_add(const char *path); | 575 | void fs_rdwr_add(const char *path); |
576 | void fs_rdwr(void); | 576 | void fs_rdwr(void); |
577 | 577 | ||
578 | // appimage.c | ||
579 | char *appimage_set(const char *appimage_path); | ||
578 | 580 | ||
579 | #endif | 581 | #endif |
580 | 582 | ||
diff --git a/src/firejail/main.c b/src/firejail/main.c index 0c843de9c..c2ac4a3fa 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -107,6 +107,7 @@ char *fullargv[MAX_ARGS]; // expanded argv for restricted shell | |||
107 | int fullargc = 0; | 107 | int fullargc = 0; |
108 | static pid_t child = 0; | 108 | static pid_t child = 0; |
109 | pid_t sandbox_pid; | 109 | pid_t sandbox_pid; |
110 | static char *appimage_mntdir = NULL; | ||
110 | 111 | ||
111 | static void set_name_file(pid_t pid); | 112 | static void set_name_file(pid_t pid); |
112 | static void delete_name_file(pid_t pid); | 113 | static void delete_name_file(pid_t pid); |
@@ -129,7 +130,12 @@ static void myexit(int rv) { | |||
129 | // delete sandbox files in shared memory | 130 | // delete sandbox files in shared memory |
130 | EUID_ROOT(); | 131 | EUID_ROOT(); |
131 | clear_run_files(sandbox_pid); | 132 | clear_run_files(sandbox_pid); |
132 | 133 | if (appimage_mntdir) { | |
134 | umount2(appimage_mntdir, MNT_FORCE); | ||
135 | rmdir(appimage_mntdir); | ||
136 | free(appimage_mntdir); | ||
137 | } | ||
138 | |||
133 | exit(rv); | 139 | exit(rv); |
134 | } | 140 | } |
135 | 141 | ||
@@ -701,6 +707,7 @@ int main(int argc, char **argv) { | |||
701 | #ifdef HAVE_SECCOMP | 707 | #ifdef HAVE_SECCOMP |
702 | int highest_errno = errno_highest_nr(); | 708 | int highest_errno = errno_highest_nr(); |
703 | #endif | 709 | #endif |
710 | int arg_appimage = 0; | ||
704 | 711 | ||
705 | // drop permissions by default and rise them when required | 712 | // drop permissions by default and rise them when required |
706 | EUID_INIT(); | 713 | EUID_INIT(); |
@@ -1400,7 +1407,7 @@ int main(int argc, char **argv) { | |||
1400 | } | 1407 | } |
1401 | else if (strncmp(argv[i], "--env=", 6) == 0) | 1408 | else if (strncmp(argv[i], "--env=", 6) == 0) |
1402 | env_store(argv[i] + 6); | 1409 | env_store(argv[i] + 6); |
1403 | else if (strncmp(argv[i], "--nosound", 9) == 0) { | 1410 | else if (strcmp(argv[i], "--nosound") == 0) { |
1404 | arg_nosound = 1; | 1411 | arg_nosound = 1; |
1405 | arg_private_dev = 1; | 1412 | arg_private_dev = 1; |
1406 | } | 1413 | } |
@@ -1766,6 +1773,8 @@ int main(int argc, char **argv) { | |||
1766 | //************************************* | 1773 | //************************************* |
1767 | // command | 1774 | // command |
1768 | //************************************* | 1775 | //************************************* |
1776 | else if (strcmp(argv[i], "--appimage") == 0) | ||
1777 | arg_appimage = 1; | ||
1769 | else if (strcmp(argv[i], "--csh") == 0) { | 1778 | else if (strcmp(argv[i], "--csh") == 0) { |
1770 | if (arg_shell_none) { | 1779 | if (arg_shell_none) { |
1771 | 1780 | ||
@@ -1847,7 +1856,13 @@ int main(int argc, char **argv) { | |||
1847 | } | 1856 | } |
1848 | 1857 | ||
1849 | // we have a program name coming | 1858 | // we have a program name coming |
1850 | extract_command_name(i, argv); | 1859 | if (arg_appimage) { |
1860 | cfg.command_name = strdup(argv[i]); | ||
1861 | if (!cfg.command_name) | ||
1862 | errExit("strdup"); | ||
1863 | } | ||
1864 | else | ||
1865 | extract_command_name(i, argv); | ||
1851 | prog_index = i; | 1866 | prog_index = i; |
1852 | break; | 1867 | break; |
1853 | } | 1868 | } |
@@ -1900,6 +1915,13 @@ int main(int argc, char **argv) { | |||
1900 | cfg.window_title = "/bin/bash"; | 1915 | cfg.window_title = "/bin/bash"; |
1901 | cfg.command_name = "bash"; | 1916 | cfg.command_name = "bash"; |
1902 | } | 1917 | } |
1918 | else if (arg_appimage) { | ||
1919 | if (arg_debug) | ||
1920 | printf("Configuring appimage environment\n"); | ||
1921 | appimage_mntdir = appimage_set(cfg.command_name); | ||
1922 | cfg.window_title = "appimage"; | ||
1923 | //todo: set window title | ||
1924 | } | ||
1903 | else { | 1925 | else { |
1904 | // calculate the length of the command | 1926 | // calculate the length of the command |
1905 | int i; | 1927 | int i; |
@@ -1939,6 +1961,7 @@ int main(int argc, char **argv) { | |||
1939 | assert(cfg.command_name); | 1961 | assert(cfg.command_name); |
1940 | if (arg_debug) | 1962 | if (arg_debug) |
1941 | printf("Command name #%s#\n", cfg.command_name); | 1963 | printf("Command name #%s#\n", cfg.command_name); |
1964 | |||
1942 | 1965 | ||
1943 | // load the profile | 1966 | // load the profile |
1944 | if (!arg_noprofile) { | 1967 | if (!arg_noprofile) { |
diff --git a/src/firejail/usage.c b/src/firejail/usage.c index 45bf2e3b1..d2f7d9460 100644 --- a/src/firejail/usage.c +++ b/src/firejail/usage.c | |||
@@ -34,6 +34,7 @@ void usage(void) { | |||
34 | printf("\n"); | 34 | printf("\n"); |
35 | printf("Options:\n\n"); | 35 | printf("Options:\n\n"); |
36 | printf(" -- - signal the end of options and disables further option processing.\n\n"); | 36 | printf(" -- - signal the end of options and disables further option processing.\n\n"); |
37 | printf(" --appimage - sandbox an AppImage application\n\n"); | ||
37 | #ifdef HAVE_NETWORK | 38 | #ifdef HAVE_NETWORK |
38 | printf(" --bandwidth=name|pid - set bandwidth limits for the sandbox identified\n"); | 39 | printf(" --bandwidth=name|pid - set bandwidth limits for the sandbox identified\n"); |
39 | printf("\tby name or PID, see Traffic Shaping section fo more details.\n\n"); | 40 | printf("\tby name or PID, see Traffic Shaping section fo more details.\n\n"); |
diff --git a/src/man/firejail.txt b/src/man/firejail.txt index 3c4de9ed5..e57b8fb93 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt | |||
@@ -75,6 +75,19 @@ $ firejail [OPTIONS] firefox # starting Mozilla Firefox | |||
75 | \fB\-\- | 75 | \fB\-\- |
76 | Signal the end of options and disables further option processing. | 76 | Signal the end of options and disables further option processing. |
77 | .TP | 77 | .TP |
78 | \fB\-\-appimage | ||
79 | Sandbox an AppImage (http://appimage.org/) application. | ||
80 | .br | ||
81 | |||
82 | .br | ||
83 | Example: | ||
84 | .br | ||
85 | $ firejail --appimage krita-3.0-x86_64.appimage | ||
86 | .br | ||
87 | $ firejail --appimage --private krita-3.0-x86_64.appimage | ||
88 | .br | ||
89 | $ firejail --appimage --net=none --x11 krita-3.0-x86_64.appimage | ||
90 | .TP | ||
78 | \fB\-\-bandwidth=name|pid | 91 | \fB\-\-bandwidth=name|pid |
79 | Set bandwidth limits for the sandbox identified by name or PID, see \fBTRAFFIC SHAPING\fR section for more details. | 92 | Set bandwidth limits for the sandbox identified by name or PID, see \fBTRAFFIC SHAPING\fR section for more details. |
80 | .TP | 93 | .TP |