Skip to content

Commit

Permalink
appimage support
Browse files Browse the repository at this point in the history
  • Loading branch information
netblue30 committed Jun 5, 2016
1 parent c8a8d07 commit a4444ba
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 3 deletions.
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,35 @@ FAQ: https://firejail.wordpress.com/support/frequently-asked-questions/
`````
# Current development version: 0.9.41

## AppImage

AppImage (http://appimage.org/) is a distribution-agnostic packaging format.
The package is a regular ISO file containing all binaries, libraries and resources
necessary for the program to run.

We introduce in this release support for sandboxing AppImage applications. Example:
`````
$ firejail --appimage krita-3.0-x86_64.appimage
`````
All Firejail sandboxing options should be available. A private home directory:
`````
$ firejail --appimage --private krita-3.0-x86_64.appimage
`````
or some basic X11 sandboxing:
`````
$ firejail --appimage --net=none --x11 krita-3.0-x86_64.appimage
`````
Major software applications distributing AppImage packages:

..* Krita: https://krita.org/download/krita-desktop/
..* OpenShot: http://www.openshot.org/download/
..* Scribus: https://www.scribus.net/downloads/unstable-branch/
..* MuseScore: https://musescore.org/en/download

More packages build by AppImage developer Simon Peter: https://bintray.com/probono/AppImages

AppImage project home: https://github.com/probonopd/AppImageKit

## New security profiles

Gitter
94 changes: 94 additions & 0 deletions src/firejail/appimage.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright (C) 2014-2016 Firejail Authors
*
* This file is part of firejail project
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
// http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=770fe30a46a12b6fb6b63fbe1737654d28e84844
// sudo mount -o loop krita-3.0-x86_64.appimage mnt

#include "firejail.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mount.h>
#include <fcntl.h>
#include <linux/loop.h>



char *appimage_set(const char *appimage_path) {
assert(appimage_path);
EUID_ASSERT();

// check appimage_path
if (access(appimage_path, R_OK) == -1) {
fprintf(stderr, "Error: cannot access AppImage file\n");
exit(1);
}

EUID_ROOT();

// find or allocate a free loop device to use
int cfd = open("/dev/loop-control", O_RDWR);
int devnr = ioctl(cfd, LOOP_CTL_GET_FREE);
if (devnr == -1) {
fprintf(stderr, "Error: cannot allocate a new loopback device\n");
exit(1);
}
close(cfd);
char *devloop;
if (asprintf(&devloop, "/dev/loop%d", devnr) == -1)
errExit("asprintf");

int ffd = open(appimage_path, O_RDONLY|O_CLOEXEC);
int lfd = open(devloop, O_RDONLY);
if (ioctl(lfd, LOOP_SET_FD, ffd) == -1) {
fprintf(stderr, "Error: cannot configure the loopback device\n");
exit(1);
}
close(lfd);
close(ffd);

char dirname[] = "/tmp/firejail-mnt-XXXXXX";
char *mntdir = strdup(mkdtemp(dirname));
if (mntdir == NULL) {
fprintf(stderr, "Error: cannot create temporary directory\n");
exit(1);
}
mkdir(mntdir, 755);
chown(mntdir, getuid(), getgid());
chmod(mntdir, 755);

char *mode;
if (asprintf(&mode, "mode=755,uid=%d,gid=%d", getuid(), getgid()) == -1)
errExit("asprintf");

if (mount(devloop, mntdir, "iso9660",MS_MGC_VAL|MS_RDONLY, mode) < 0)
errExit("mounting appimage");

if (arg_debug)
printf("appimage mounted on %s\n", mntdir);
EUID_USER();

// build new command line
if (asprintf(&cfg.command_line, "%s/AppRun", mntdir) == -1)
errExit("asprintf");

free(devloop);
free(mode);

return mntdir;
}
2 changes: 2 additions & 0 deletions src/firejail/firejail.h
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,8 @@ int checkcfg(int val);
void fs_rdwr_add(const char *path);
void fs_rdwr(void);

// appimage.c
char *appimage_set(const char *appimage_path);

#endif

29 changes: 26 additions & 3 deletions src/firejail/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ char *fullargv[MAX_ARGS]; // expanded argv for restricted shell
int fullargc = 0;
static pid_t child = 0;
pid_t sandbox_pid;
static char *appimage_mntdir = NULL;

static void set_name_file(pid_t pid);
static void delete_name_file(pid_t pid);
Expand All @@ -129,7 +130,12 @@ static void myexit(int rv) {
// delete sandbox files in shared memory
EUID_ROOT();
clear_run_files(sandbox_pid);

if (appimage_mntdir) {
umount2(appimage_mntdir, MNT_FORCE);
rmdir(appimage_mntdir);
free(appimage_mntdir);
}

exit(rv);
}

Expand Down Expand Up @@ -701,6 +707,7 @@ int main(int argc, char **argv) {
#ifdef HAVE_SECCOMP
int highest_errno = errno_highest_nr();
#endif
int arg_appimage = 0;

// drop permissions by default and rise them when required
EUID_INIT();
Expand Down Expand Up @@ -1400,7 +1407,7 @@ int main(int argc, char **argv) {
}
else if (strncmp(argv[i], "--env=", 6) == 0)
env_store(argv[i] + 6);
else if (strncmp(argv[i], "--nosound", 9) == 0) {
else if (strcmp(argv[i], "--nosound") == 0) {
arg_nosound = 1;
arg_private_dev = 1;
}
Expand Down Expand Up @@ -1766,6 +1773,8 @@ int main(int argc, char **argv) {
//*************************************
// command
//*************************************
else if (strcmp(argv[i], "--appimage") == 0)
arg_appimage = 1;
else if (strcmp(argv[i], "--csh") == 0) {
if (arg_shell_none) {

Expand Down Expand Up @@ -1847,7 +1856,13 @@ int main(int argc, char **argv) {
}

// we have a program name coming
extract_command_name(i, argv);
if (arg_appimage) {
cfg.command_name = strdup(argv[i]);
if (!cfg.command_name)
errExit("strdup");
}
else
extract_command_name(i, argv);
prog_index = i;
break;
}
Expand Down Expand Up @@ -1900,6 +1915,13 @@ int main(int argc, char **argv) {
cfg.window_title = "/bin/bash";
cfg.command_name = "bash";
}
else if (arg_appimage) {
if (arg_debug)
printf("Configuring appimage environment\n");
appimage_mntdir = appimage_set(cfg.command_name);
cfg.window_title = "appimage";
//todo: set window title
}
else {
// calculate the length of the command
int i;
Expand Down Expand Up @@ -1939,6 +1961,7 @@ int main(int argc, char **argv) {
assert(cfg.command_name);
if (arg_debug)
printf("Command name #%s#\n", cfg.command_name);


// load the profile
if (!arg_noprofile) {
Expand Down
1 change: 1 addition & 0 deletions src/firejail/usage.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ void usage(void) {
printf("\n");
printf("Options:\n\n");
printf(" -- - signal the end of options and disables further option processing.\n\n");
printf(" --appimage - sandbox an AppImage application\n\n");
#ifdef HAVE_NETWORK
printf(" --bandwidth=name|pid - set bandwidth limits for the sandbox identified\n");
printf("\tby name or PID, see Traffic Shaping section fo more details.\n\n");
Expand Down
13 changes: 13 additions & 0 deletions src/man/firejail.txt
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,19 @@ $ firejail [OPTIONS] firefox # starting Mozilla Firefox
\fB\-\-
Signal the end of options and disables further option processing.
.TP
\fB\-\-appimage
Sandbox an AppImage (http://appimage.org/) application.
.br

.br
Example:
.br
$ firejail --appimage krita-3.0-x86_64.appimage
.br
$ firejail --appimage --private krita-3.0-x86_64.appimage
.br
$ firejail --appimage --net=none --x11 krita-3.0-x86_64.appimage
.TP
\fB\-\-bandwidth=name|pid
Set bandwidth limits for the sandbox identified by name or PID, see \fBTRAFFIC SHAPING\fR section for more details.
.TP
Expand Down

0 comments on commit a4444ba

Please sign in to comment.