Merge pull request #1296 from Fred-Barclay/novideo

WIP: --novideo option
This commit is contained in:
netblue30 2017-05-23 09:25:03 -04:00 committed by GitHub
commit e0e910e4be
8 changed files with 389 additions and 361 deletions

View file

@ -147,9 +147,9 @@ typedef struct bridge_t {
uint32_t mask; // interface device mask
uint8_t mac[6]; // interface mac address
int mtu; // interface mtu
char *veth_name; // veth name for the device connected to the bridge
// inside the sandbox
char *devsandbox; // name of the device inside the sandbox
uint32_t ipsandbox; // ip address inside the sandbox
@ -157,7 +157,7 @@ typedef struct bridge_t {
uint8_t macsandbox[6]; // mac address inside the sandbox
uint32_t iprange_start;// iprange arp scan start range
uint32_t iprange_end; // iprange arp scan end range
// flags
uint8_t arg_ip_none; // --ip=none
uint8_t macvlan; // set by --net=eth0 (or eth1, ...); reset by --net=br0 (or br1, ...)
@ -171,14 +171,14 @@ typedef struct interface_t {
uint32_t mask;
uint8_t mac[6];
int mtu;
uint8_t configured;
} Interface;
typedef struct profile_entry_t {
struct profile_entry_t *next;
char *data; // command
// whitelist command parameters
char *link; // link name - set if the file is a link
unsigned home_dir:1; // whitelist in /home/user directory
@ -195,10 +195,10 @@ typedef struct config_t {
// user data
char *username;
char *homedir;
// filesystem
ProfileEntry *profile;
#define MAX_PROFILE_IGNORE 32
#define MAX_PROFILE_IGNORE 32
char *profile_ignore[MAX_PROFILE_IGNORE];
char *chrootdir; // chroot directory
char *home_private; // private home directory
@ -239,12 +239,12 @@ typedef struct config_t {
long long unsigned rlimit_nproc;
long long unsigned rlimit_fsize;
long long unsigned rlimit_sigpending;
// cpu affinity, nice and control groups
uint32_t cpus;
int nice;
char *cgroup;
// command line
char *command_line;
@ -331,6 +331,7 @@ extern int arg_private_tmp; // private tmp directory
extern int arg_scan; // arp-scan all interfaces
extern int arg_whitelist; // whitelist commad
extern int arg_nosound; // disable sound
extern int arg_novideo; //disable video devices in /dev
extern int arg_no3d; // disable 3d hardware acceleration
extern int arg_quiet; // no output for scripting
extern int arg_join_network; // join only the network namespace
@ -724,7 +725,7 @@ void build_appimage_cmdline(char **command_line, char **window_title, int argc,
// bitmapped filters for sbox_run
#define SBOX_ROOT (1 << 0) // run the sandbox as root
#define SBOX_USER (1 << 1) // run the sandbox as a regular user
#define SBOX_SECCOMP (1 << 2) // install seccomp
#define SBOX_SECCOMP (1 << 2) // install seccomp
#define SBOX_CAPS_NONE (1 << 3) // drop all capabilities
#define SBOX_CAPS_NETWORK (1 << 4) // caps filter for programs running network programs
#define SBOX_ALLOW_STDIN (1 << 5) // don't close stdin
@ -739,4 +740,3 @@ void git_install();
void git_uninstall();
#endif

View file

@ -26,7 +26,7 @@
#include <fcntl.h>
#include <pwd.h>
#ifndef _BSD_SOURCE
#define _BSD_SOURCE
#define _BSD_SOURCE
#endif
#include <sys/sysmacros.h>
#include <sys/types.h>
@ -35,6 +35,7 @@ typedef struct {
const char *dev_fname;
const char *run_fname;
int sound;
int video;
int hw3d;
} DevEntry;
@ -93,16 +94,16 @@ static void deventry_mount(void) {
fclose(fp);
}
}
if (mount(dev[i].run_fname, dev[i].dev_fname, NULL, MS_BIND|MS_REC, NULL) < 0)
errExit("mounting dev file");
fs_logger2("whitelist", dev[i].dev_fname);
}
i++;
i++;
}
}
static void create_char_dev(const char *path, mode_t mode, int major, int minor) {
dev_t dev = makedev(major, minor);
if (mknod(path, S_IFCHR | mode, dev) == -1)
@ -112,7 +113,7 @@ static void create_char_dev(const char *path, mode_t mode, int major, int minor)
ASSERT_PERMS(path, 0, 0, mode);
return;
errexit:
fprintf(stderr, "Error: cannot create %s device\n", path);
exit(1);
@ -161,7 +162,7 @@ void fs_private_dev(void){
if (mount("tmpfs", "/dev", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
errExit("mounting /dev");
fs_logger("tmpfs /dev");
deventry_mount();
// bring back /dev/log
@ -174,11 +175,11 @@ void fs_private_dev(void){
errExit("mounting /dev/log");
fs_logger("clone /dev/log");
}
}
}
if (mount(RUN_RO_DIR, RUN_DEV_DIR, "none", MS_BIND, "mode=400,gid=0") < 0)
errExit("disable /dev/snd");
// create /dev/shm
if (arg_debug)
printf("Create /dev/shm directory\n");
@ -267,24 +268,24 @@ void fs_dev_shm(void) {
fwarning("/dev/shm not mounted\n");
dbg_test_dir("/dev/shm");
}
}
}
#endif
#endif
static void disable_file_or_dir(const char *fname) {
if (arg_debug)
printf("disable %s\n", fname);
struct stat s;
if (stat(fname, &s) != -1) {
if (is_dir(fname)) {
if (is_dir(fname)) {
if (mount(RUN_RO_DIR, fname, "none", MS_BIND, "mode=400,gid=0") < 0)
errExit("disable directory");
}
else {
if (mount(RUN_RO_FILE, fname, "none", MS_BIND, "mode=400,gid=0") < 0)
errExit("disable file");
}
}
}
fs_logger2("blacklist", fname);
@ -299,6 +300,15 @@ void fs_dev_disable_sound(void) {
}
}
void fs_dev_disable_video(void) {
int i = 0;
while (dev[i].dev_fname != NULL) {
if (dev[i].video)
disable_file_or_dir(dev[i].dev_fname);
i++;
}
}
void fs_dev_disable_3d(void) {
int i = 0;
while (dev[i].dev_fname != NULL) {

File diff suppressed because it is too large Load diff

View file

@ -28,8 +28,8 @@ int profile_find(const char *name, const char *dir) {
EUID_ASSERT();
assert(name);
assert(dir);
int rv = 0;
int rv = 0;
DIR *dp;
char *pname;
if (asprintf(&pname, "%s.profile", name) == -1)
@ -74,17 +74,17 @@ static void warning_feature_disabled(const char *feature) {
// return 0 if the command was already executed inside the function
int profile_check_line(char *ptr, int lineno, const char *fname) {
EUID_ASSERT();
// check ignore list
int i;
for (i = 0; i < MAX_PROFILE_IGNORE; i++) {
if (cfg.profile_ignore[i] == NULL)
break;
if (strncmp(ptr, cfg.profile_ignore[i], strlen(cfg.profile_ignore[i])) == 0)
return 0; // ignore line
}
if (strncmp(ptr, "ignore ", 7) == 0) {
char *str = strdup(ptr + 7);
if (*str == '\0') {
@ -94,7 +94,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
// find an empty entry in profile_ignore array
int j;
for (j = 0; j < MAX_PROFILE_IGNORE; j++) {
if (cfg.profile_ignore[j] == NULL)
if (cfg.profile_ignore[j] == NULL)
break;
}
if (j >= MAX_PROFILE_IGNORE) {
@ -102,18 +102,18 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
exit(1);
}
// ... and configure it
else
else
cfg.profile_ignore[j] = str;
return 0;
}
// mkdir
// mkdir
if (strncmp(ptr, "mkdir ", 6) == 0) {
fs_mkdir(ptr + 6);
return 1; // process mkdir again while applying blacklists
}
// mkfile
// mkfile
if (strncmp(ptr, "mkfile ", 7) == 0) {
fs_mkfile(ptr + 7);
return 1; // process mkfile again while applying blacklists
@ -166,7 +166,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
else if (strcmp(ptr, "shell none") == 0) {
arg_shell_none = 1;
return 0;
}
}
else if (strcmp(ptr, "tracelog") == 0) {
arg_tracelog = 1;
return 0;
@ -210,6 +210,10 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
arg_nosound = 1;
return 0;
}
else if (strcmp(ptr, "novideo") == 0) {
arg_novideo = 1;
return 0;
}
else if (strcmp(ptr, "no3d") == 0) {
arg_no3d = 1;
return 0;
@ -217,7 +221,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
else if (strcmp(ptr, "allow-private-blacklist") == 0) {
arg_allow_private_blacklist = 1;
return 0;
}
}
else if (strcmp(ptr, "netfilter") == 0) {
#ifdef HAVE_NETWORK
if (checkcfg(CFG_NETWORK))
@ -288,7 +292,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
fprintf(stderr, "Error: only \"net none\" is allowed to non-root users\n");
exit(1);
}
if (strcmp(ptr + 4, "lo") == 0) {
fprintf(stderr, "Error: cannot attach to lo device\n");
exit(1);
@ -314,7 +318,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
#endif
return 0;
}
else if (strncmp(ptr, "veth-name ", 10) == 0) {
#ifdef HAVE_NETWORK
if (checkcfg(CFG_NETWORK)) {
@ -365,7 +369,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
}
*secondip = '\0';
secondip++;
// check addresses
if (atoip(firstip, &br->iprange_start) || atoip(secondip, &br->iprange_end) ||
br->iprange_start >= br->iprange_end) {
@ -392,7 +396,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
fprintf(stderr, "Error: no network device configured\n");
exit(1);
}
if (mac_not_zero(br->macsandbox)) {
fprintf(stderr, "Error: cannot configure the MAC address twice for the same interface\n");
exit(1);
@ -418,7 +422,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
fprintf(stderr, "Error: no network device configured\n");
exit(1);
}
if (sscanf(ptr + 4, "%d", &br->mtu) != 1 || br->mtu < 576 || br->mtu > 9198) {
fprintf(stderr, "Error: invalid mtu value\n");
exit(1);
@ -479,7 +483,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
// fprintf(stderr, "Error: invalid IP address\n");
// exit(1);
// }
}
else
warning_feature_disabled("networking");
@ -502,7 +506,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
}
if (strcmp(ptr, "apparmor") == 0) {
#ifdef HAVE_APPARMOR
#ifdef HAVE_APPARMOR
arg_apparmor = 1;
#endif
return 0;
@ -515,7 +519,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
fwarning("a protocol list is present, the new list \"%s\" will not be installed\n", ptr + 9);
return 0;
}
// store list
cfg.protocol = strdup(ptr + 9);
if (!cfg.protocol)
@ -526,7 +530,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
#endif
return 0;
}
if (strncmp(ptr, "env ", 4) == 0) {
env_store(ptr + 4, SETENV);
return 0;
@ -535,7 +539,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
env_store(ptr + 6, RMENV);
return 0;
}
// seccomp drop list on top of default list
if (strncmp(ptr, "seccomp ", 8) == 0) {
#ifdef HAVE_SECCOMP
@ -549,7 +553,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
return 0;
}
// seccomp drop list without default list
if (strncmp(ptr, "seccomp.drop ", 13) == 0) {
#ifdef HAVE_SECCOMP
@ -559,7 +563,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
}
else
warning_feature_disabled("seccomp");
#endif
#endif
return 0;
}
@ -572,10 +576,10 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
}
else
warning_feature_disabled("seccomp");
#endif
#endif
return 0;
}
// caps drop list
if (strncmp(ptr, "caps.drop ", 10) == 0) {
arg_caps_drop = 1;
@ -586,7 +590,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
caps_check_list(arg_caps_list, NULL);
return 0;
}
// caps keep list
if (strncmp(ptr, "caps.keep ", 10) == 0) {
arg_caps_keep = 1;
@ -603,13 +607,13 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
cfg.hostname = ptr + 9;
return 0;
}
// hosts-file
if (strncmp(ptr, "hosts-file ", 11) == 0) {
cfg.hosts_file = fs_check_hosts_file(ptr + 11);
return 0;
}
// dns
if (strncmp(ptr, "dns ", 4) == 0) {
uint32_t dns;
@ -617,7 +621,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
fprintf(stderr, "Error: invalid DNS server IP address\n");
return 1;
}
if (cfg.dns1 == 0)
cfg.dns1 = dns;
else if (cfg.dns2 == 0)
@ -630,13 +634,13 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
}
return 0;
}
// cpu affinity
if (strncmp(ptr, "cpu ", 4) == 0) {
read_cpu_list(ptr + 4);
return 0;
}
// nice value
if (strncmp(ptr, "nice ", 4) == 0) {
cfg.nice = atoi(ptr + 5);
@ -651,7 +655,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
set_cgroup(ptr + 7);
return 0;
}
// writable-etc
if (strcmp(ptr, "writable-etc") == 0) {
if (cfg.etc_private_keep) {
@ -661,7 +665,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
arg_writable_etc = 1;
return 0;
}
if (strcmp(ptr, "machine-id") == 0) {
arg_machineid = 1;
return 0;
@ -675,7 +679,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
arg_writable_var_log = 1;
return 0;
}
// private directory
if (strncmp(ptr, "private ", 8) == 0) {
cfg.home_private = ptr + 8;
@ -717,7 +721,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
#endif
return 0;
}
if (strcmp(ptr, "x11 xpra") == 0) {
#ifdef HAVE_X11
if (checkcfg(CFG_X11)) {
@ -736,7 +740,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
#endif
return 0;
}
if (strcmp(ptr, "x11 xvfb") == 0) {
#ifdef HAVE_X11
if (checkcfg(CFG_X11)) {
@ -766,15 +770,15 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
else {
// start x11
x11_start(cfg.original_argc, cfg.original_argv);
exit(0);
exit(0);
}
}
else
warning_feature_disabled("x11");
#endif
#endif
return 0;
}
// private /etc list of files and directories
if (strncmp(ptr, "private-etc ", 12) == 0) {
if (arg_writable_etc) {
@ -788,7 +792,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
cfg.etc_private_keep = ptr + 12;
}
arg_private_etc = 1;
return 0;
}
@ -801,7 +805,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
cfg.opt_private_keep = ptr + 12;
}
arg_private_opt = 1;
return 0;
}
@ -814,7 +818,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
cfg.srv_private_keep = ptr + 12;
}
arg_private_srv = 1;
return 0;
}
@ -906,13 +910,13 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
// filesystem bind
if (strncmp(ptr, "bind ", 5) == 0) {
#ifdef HAVE_BIND
#ifdef HAVE_BIND
if (checkcfg(CFG_BIND)) {
if (getuid() != 0) {
fprintf(stderr, "Error: --bind option is available only if running as root\n");
exit(1);
}
// extract two directories
char *dname1 = ptr + 5;
char *dname2 = split_comma(dname1); // this inserts a '0 to separate the two dierctories
@ -920,7 +924,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
fprintf(stderr, "Error: missing second directory for bind\n");
exit(1);
}
// check directories
invalid_filename(dname1);
invalid_filename(dname2);
@ -932,14 +936,14 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
fprintf(stderr, "Symbolic links are not allowed for bind command\n");
exit(1);
}
// insert comma back
*(dname2 - 1) = ',';
return 1;
}
else
warning_feature_disabled("bind");
#endif
#endif
return 0;
}
@ -969,8 +973,8 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
fprintf(stderr, "Invalid rlimit option on line %d\n", lineno);
exit(1);
}
return 0;
return 0;
}
if (strncmp(ptr, "join-or-start ", 14) == 0) {
@ -1005,14 +1009,14 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
else if (strncmp(ptr, "noblacklist ", 12) == 0)
ptr += 12;
else if (strncmp(ptr, "whitelist ", 10) == 0) {
#ifdef HAVE_WHITELIST
#ifdef HAVE_WHITELIST
if (checkcfg(CFG_WHITELIST)) {
arg_whitelist = 1;
ptr += 10;
}
else
return 0;
#else
#else
return 0;
#endif
}
@ -1058,13 +1062,13 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
// add a profile entry in cfg.profile list; use str to populate the list
void profile_add(char *str) {
EUID_ASSERT();
ProfileEntry *prf = malloc(sizeof(ProfileEntry));
if (!prf)
errExit("malloc");
memset(prf, 0, sizeof(ProfileEntry));
prf->next = NULL;
prf->data = str;
prf->data = str;
// add prf to the list
if (cfg.profile == NULL) {
@ -1081,11 +1085,11 @@ void profile_add(char *str) {
static int include_level = 0;
void profile_read(const char *fname) {
EUID_ASSERT();
// exit program if maximum include level was reached
if (include_level > MAX_INCLUDE_LEVEL) {
fprintf(stderr, "Error: maximum profile include level was reached\n");
exit(1);
exit(1);
}
// check file
@ -1100,7 +1104,7 @@ void profile_read(const char *fname) {
char *ptr = strstr(base, ".local");
if (ptr && strlen(ptr) == 6)
return;
fprintf(stderr, "Error: cannot access profile file\n");
exit(1);
}
@ -1114,7 +1118,7 @@ void profile_read(const char *fname) {
return;
}
}
// open profile file:
FILE *fp = fopen(fname, "r");
if (fp == NULL) {
@ -1133,13 +1137,13 @@ void profile_read(const char *fname) {
char *ptr = line_remove_spaces(buf);
if (ptr == NULL)
continue;
// comments
if (*ptr == '#' || *ptr == '\0') {
free(ptr);
continue;
}
// process quiet
if (strcmp(ptr, "quiet") == 0) {
arg_quiet = 1;
@ -1155,13 +1159,13 @@ void profile_read(const char *fname) {
// process include
if (strncmp(ptr, "include ", 8) == 0) {
include_level++;
// extract profile filename and new skip params
char *newprofile = ptr + 8; // profile name
// expand ${HOME}/ in front of the new profile file
char *newprofile2 = expand_home(newprofile, cfg.homedir);
// recursivity
profile_read((newprofile2)? newprofile2:newprofile);
include_level--;
@ -1170,7 +1174,7 @@ void profile_read(const char *fname) {
free(ptr);
continue;
}
// verify syntax, exit in case of error
if (profile_check_line(ptr, lineno, fname))
profile_add(ptr);

View file

@ -17,7 +17,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "firejail.h"
#include <sys/mount.h>
#include <sys/wait.h>
@ -65,7 +65,7 @@ static void sandbox_handler(int sig){
FILE *fp = fopen(monfile, "r");
if (!fp)
break;
char c;
size_t count = fread(&c, 1, 1, fp);
fclose(fp);
@ -78,7 +78,7 @@ static void sandbox_handler(int sig){
monsec--;
}
free(monfile);
}
@ -115,7 +115,7 @@ void save_nogroups(void) {
fprintf(stderr, "Error: cannot save nogroups state\n");
exit(1);
}
}
static void sandbox_if_up(Bridge *br) {
@ -132,7 +132,7 @@ static void sandbox_if_up(Bridge *br) {
fprintf(stderr, "Error: %d.%d.%d.%d is interface %s address.\n", PRINT_IP(br->ipsandbox), br->dev);
exit(1);
}
// just assign the address
assert(br->ipsandbox);
if (arg_debug)
@ -149,19 +149,19 @@ static void sandbox_if_up(Bridge *br) {
fprintf(stderr, "Error: %d.%d.%d.%d is interface %s address.\n", PRINT_IP(br->ipsandbox), br->dev);
exit(1);
}
uint32_t rv = arp_check(dev, br->ipsandbox, br->ip);
if (rv) {
fprintf(stderr, "Error: the address %d.%d.%d.%d is already in use.\n", PRINT_IP(br->ipsandbox));
exit(1);
}
}
if (arg_debug)
printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(br->ipsandbox), dev);
net_config_interface(dev, br->ipsandbox, br->mask, br->mtu);
}
if (br->ip6sandbox)
net_if_ip6(dev, br->ip6sandbox);
}
@ -171,14 +171,14 @@ static void chk_chroot(void) {
char *mycont = getenv("container");
if (mycont)
return;
// check if this is a regular chroot
struct stat s;
if (stat("/", &s) == 0) {
if (s.st_ino != 2)
return;
}
fprintf(stderr, "Error: cannot mount filesystem as slave\n");
exit(1);
}
@ -238,7 +238,7 @@ static int monitor_application(pid_t app_pid) {
continue;
if (pid == 1)
continue;
// todo: make this generic
// Dillo browser leaves a dpid process running, we need to shut it down
int found = 0;
@ -268,7 +268,7 @@ void start_audit(void) {
char *audit_prog;
if (asprintf(&audit_prog, "%s/firejail/faudit", LIBDIR) == -1)
errExit("asprintf");
assert(getenv("LD_PRELOAD") == NULL);
assert(getenv("LD_PRELOAD") == NULL);
execl(audit_prog, audit_prog, NULL);
perror("execl");
exit(1);
@ -281,7 +281,7 @@ static void print_time(void) {
usleep(1000);
unsigned long long onems = getticks() - end_timestamp;
if (onems) {
printf("Child process initialized in %.02f ms\n",
printf("Child process initialized in %.02f ms\n",
(float) (end_timestamp - start_timestamp) / (float) onems);
return;
}
@ -301,7 +301,7 @@ void start_application(void) {
printf("starting application\n");
printf("LD_PRELOAD=%s\n", getenv("LD_PRELOAD"));
}
//****************************************
// audit
//****************************************
@ -405,12 +405,12 @@ static void enforce_filters(void) {
free(cfg.seccomp_list_keep);
cfg.seccomp_list_keep = NULL;
}
// disable all capabilities
if (arg_caps_default_filter || arg_caps_list)
fwarning("all capabilities disabled for a regular user in chroot\n");
arg_caps_drop_all = 1;
// drop all supplementary groups; /etc/group file inside chroot
// is controlled by a regular usr
arg_nogroups = 1;
@ -424,12 +424,12 @@ int sandbox(void* sandbox_arg) {
pid_t child_pid = getpid();
if (arg_debug)
printf("Initializing child process\n");
printf("Initializing child process\n");
// close each end of the unused pipes
close(parent_to_child_fds[1]);
close(child_to_parent_fds[0]);
// wait for parent to do base setup
wait_for_other(parent_to_child_fds[0]);
@ -454,7 +454,7 @@ int sandbox(void* sandbox_arg) {
}
// ... and mount a tmpfs on top of /run/firejail/mnt directory
preproc_mount_mnt_dir();
//****************************
// log sandbox data
//****************************
@ -463,12 +463,12 @@ int sandbox(void* sandbox_arg) {
fs_logger2int("sandbox pid:", (int) sandbox_pid);
if (cfg.chrootdir)
fs_logger("sandbox filesystem: chroot");
else if (arg_overlay)
else if (arg_overlay)
fs_logger("sandbox filesystem: overlay");
else
fs_logger("sandbox filesystem: local");
fs_logger("install mount namespace");
//****************************
// netfilter
//****************************
@ -496,23 +496,23 @@ int sandbox(void* sandbox_arg) {
else if (any_bridge_configured() || any_interface_configured()) {
// configure lo and eth0...eth3
net_if_up("lo");
if (mac_not_zero(cfg.bridge0.macsandbox))
net_config_mac(cfg.bridge0.devsandbox, cfg.bridge0.macsandbox);
sandbox_if_up(&cfg.bridge0);
if (mac_not_zero(cfg.bridge1.macsandbox))
net_config_mac(cfg.bridge1.devsandbox, cfg.bridge1.macsandbox);
sandbox_if_up(&cfg.bridge1);
if (mac_not_zero(cfg.bridge2.macsandbox))
net_config_mac(cfg.bridge2.devsandbox, cfg.bridge2.macsandbox);
sandbox_if_up(&cfg.bridge2);
if (mac_not_zero(cfg.bridge3.macsandbox))
net_config_mac(cfg.bridge3.devsandbox, cfg.bridge3.macsandbox);
sandbox_if_up(&cfg.bridge3);
// moving an interface in a namespace using --interface will reset the interface configuration;
// we need to put the configuration back
@ -520,23 +520,23 @@ int sandbox(void* sandbox_arg) {
if (arg_debug)
printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface0.ip), cfg.interface0.dev);
net_config_interface(cfg.interface0.dev, cfg.interface0.ip, cfg.interface0.mask, cfg.interface0.mtu);
}
}
if (cfg.interface1.configured && cfg.interface1.ip) {
if (arg_debug)
printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface1.ip), cfg.interface1.dev);
net_config_interface(cfg.interface1.dev, cfg.interface1.ip, cfg.interface1.mask, cfg.interface1.mtu);
}
}
if (cfg.interface2.configured && cfg.interface2.ip) {
if (arg_debug)
printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface2.ip), cfg.interface2.dev);
net_config_interface(cfg.interface2.dev, cfg.interface2.ip, cfg.interface2.mask, cfg.interface2.mtu);
}
}
if (cfg.interface3.configured && cfg.interface3.ip) {
if (arg_debug)
printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface3.ip), cfg.interface3.dev);
net_config_interface(cfg.interface3.dev, cfg.interface3.ip, cfg.interface3.mask, cfg.interface3.mtu);
}
}
// add a default route
if (cfg.defaultgw) {
// set the default route
@ -549,7 +549,7 @@ int sandbox(void* sandbox_arg) {
if (arg_debug)
printf("Network namespace enabled\n");
}
// print network configuration
if (!arg_quiet) {
@ -561,7 +561,7 @@ int sandbox(void* sandbox_arg) {
sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 3, PATH_FNET, "printif", "scan");
else
sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 2, PATH_FNET, "printif", "scan");
}
if (cfg.defaultgw != 0) {
if (gw_cfg_failed)
@ -585,7 +585,7 @@ int sandbox(void* sandbox_arg) {
}
else
env_ibus_load();
//****************************
// fs pre-processing:
// - build seccomp filters
@ -602,7 +602,7 @@ int sandbox(void* sandbox_arg) {
if (rv)
exit(rv);
}
#endif
#endif
// trace pre-install
if (arg_trace || arg_tracelog)
@ -622,13 +622,13 @@ int sandbox(void* sandbox_arg) {
enforce_filters();
#ifdef HAVE_SECCOMP
enforce_seccomp = 1;
#endif
#endif
}
#ifdef HAVE_CHROOT
#ifdef HAVE_CHROOT
if (cfg.chrootdir) {
fs_chroot(cfg.chrootdir);
// force caps and seccomp if not started as root
if (getuid() != 0) {
enforce_filters();
@ -638,14 +638,14 @@ int sandbox(void* sandbox_arg) {
}
else
arg_seccomp = 1;
//****************************
// trace pre-install, this time inside chroot
//****************************
if (arg_trace || arg_tracelog)
fs_trace_preload();
}
else
else
#endif
#ifdef HAVE_OVERLAYFS
if (arg_overlay) {
@ -663,7 +663,7 @@ int sandbox(void* sandbox_arg) {
else
#endif
fs_basic_fs();
//****************************
// private mode
//****************************
@ -696,7 +696,7 @@ int sandbox(void* sandbox_arg) {
else
fs_private_dev();
}
if (arg_private_etc) {
if (cfg.chrootdir)
fwarning("private-etc feature is disabled in chroot\n");
@ -709,7 +709,7 @@ int sandbox(void* sandbox_arg) {
fs_trace_preload();
}
}
if (arg_private_opt) {
if (cfg.chrootdir)
fwarning("private-opt feature is disabled in chroot\n");
@ -719,7 +719,7 @@ int sandbox(void* sandbox_arg) {
fs_private_dir_list("/opt", RUN_OPT_DIR, cfg.opt_private_keep);
}
}
if (arg_private_srv) {
if (cfg.chrootdir)
fwarning("private-srv feature is disabled in chroot\n");
@ -729,7 +729,7 @@ int sandbox(void* sandbox_arg) {
fs_private_dir_list("/srv", RUN_SRV_DIR, cfg.srv_private_keep);
}
}
if (arg_private_bin) {
if (cfg.chrootdir)
fwarning("private-bin feature is disabled in chroot\n");
@ -748,7 +748,7 @@ int sandbox(void* sandbox_arg) {
fs_private_bin_list();
}
}
if (arg_private_tmp) {
if (cfg.chrootdir)
fwarning("private-tmp feature is disabled in chroot\n");
@ -762,7 +762,7 @@ int sandbox(void* sandbox_arg) {
}
}
//****************************
// hosts and hostname
//****************************
@ -777,19 +777,19 @@ int sandbox(void* sandbox_arg) {
//****************************
if (arg_netns)
netns_mounts(arg_netns);
//****************************
// update /proc, /sys, /dev, /boot directory
//****************************
if (checkcfg(CFG_REMOUNT_PROC_SYS))
fs_proc_sys_dev_boot();
//****************************
// handle /mnt and /media
//****************************
if (checkcfg(CFG_DISABLE_MNT))
fs_mnt();
//****************************
// nosound/no3d and fix for pulseaudio 7.0
//****************************
@ -802,35 +802,43 @@ int sandbox(void* sandbox_arg) {
}
else
pulseaudio_init();
if (arg_no3d)
fs_dev_disable_3d();
//****************************
// novideo
//****************************
if (arg_novideo) {
// disable /dev/video*
fs_dev_disable_video();
}
//****************************
// apply the profile file
//****************************
// apply all whitelist commands ...
// apply all whitelist commands ...
if (cfg.chrootdir)
fwarning("whitelist feature is disabled in chroot\n");
else if (arg_overlay)
fwarning("whitelist feature is disabled in overlay\n");
else
fs_whitelist();
// ... followed by blacklist commands
fs_blacklist(); // mkdir and mkfile are processed all over again
//****************************
// install trace
//****************************
if (arg_trace || arg_tracelog)
fs_trace();
//****************************
// set dns
//****************************
fs_resolvconf();
//****************************
// fs post-processing
//****************************
@ -846,7 +854,7 @@ int sandbox(void* sandbox_arg) {
if (chdir(cfg.cwd) == 0)
cwd = 1;
}
if (!cwd) {
if (chdir("/") < 0)
errExit("chdir");
@ -866,8 +874,8 @@ int sandbox(void* sandbox_arg) {
free(cpath);
}
}
// set nice
if (arg_nice) {
errno = 0;
@ -878,12 +886,12 @@ int sandbox(void* sandbox_arg) {
errno = 0;
}
}
// clean /tmp/.X11-unix sockets
fs_x11();
if (arg_x11_xorg)
x11_xorg();
//****************************
// set security filters
//****************************
@ -899,7 +907,7 @@ int sandbox(void* sandbox_arg) {
save_cpu(); // save cpu affinity mask to CPU_CFG file
set_cpu_affinity();
}
// save cgroup in CGROUP_CFG file
if (cfg.cgroup)
save_cgroup();
@ -911,7 +919,7 @@ int sandbox(void* sandbox_arg) {
if (cfg.protocol) {
if (arg_debug)
printf("Install protocol filter: %s\n", cfg.protocol);
seccomp_load(RUN_SECCOMP_PROTOCOL); // install filter
seccomp_load(RUN_SECCOMP_PROTOCOL); // install filter
protocol_filter_save(); // save filter in RUN_PROTOCOL_CFG
}
#endif
@ -939,12 +947,12 @@ int sandbox(void* sandbox_arg) {
}
else
drop_privs(arg_nogroups);
// notify parent that new user namespace has been created so a proper
// UID/GID map can be setup
notify_other(child_to_parent_fds[1]);
close(child_to_parent_fds[1]);
// wait for parent to finish setting up a proper UID/GID map
wait_for_other(parent_to_child_fds[0]);
close(parent_to_child_fds[0]);
@ -956,7 +964,7 @@ int sandbox(void* sandbox_arg) {
printf("noroot user namespace installed\n");
set_caps();
}
//****************************************
// Set NO_NEW_PRIVS if desired
//****************************************
@ -989,7 +997,7 @@ int sandbox(void* sandbox_arg) {
else if (arg_debug)
printf("AppArmor enabled\n");
}
#endif
#endif
prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // kill the child in case the parent died
start_application(); // start app
}

View file

@ -36,10 +36,10 @@ void usage(void) {
printf(" --apparmor - enable AppArmor confinement.\n");
printf(" --appimage - sandbox an AppImage application.\n");
printf(" --audit[=test-program] - audit the sandbox.\n");
#ifdef HAVE_NETWORK
#ifdef HAVE_NETWORK
printf(" --bandwidth=name|pid - set bandwidth limits.\n");
#endif
#ifdef HAVE_BIND
#ifdef HAVE_BIND
printf(" --bind=dirname1,dirname2 - mount-bind dirname1 on top of dirname2.\n");
printf(" --bind=filename1,filename2 - mount-bind filename1 on top of filename2.\n");
#endif
@ -51,7 +51,7 @@ void usage(void) {
printf(" --caps.keep=capability,capability - whitelist capabilities filter.\n");
printf(" --caps.print=name|pid - print the caps filter.\n");
printf(" --cgroup=tasks-file - place the sandbox in the specified control group.\n");
#ifdef HAVE_CHROOT
#ifdef HAVE_CHROOT
printf(" --chroot=dirname - chroot into directory.\n");
#endif
printf(" --cpu=cpu-number,cpu-number - set cpu affinity.\n");
@ -64,15 +64,15 @@ void usage(void) {
printf(" --debug-errnos - print all recognized error numbers.\n");
printf(" --debug-protocols - print all recognized protocols.\n");
printf(" --debug-syscalls - print all recognized system calls.\n");
#ifdef HAVE_WHITELIST
#ifdef HAVE_WHITELIST
printf(" --debug-whitelists - debug whitelisting.\n");
#endif
#ifdef HAVE_NETWORK
#ifdef HAVE_NETWORK
printf(" --defaultgw=address - configure default gateway.\n");
#endif
printf(" --dns=address - set DNS server.\n");
printf(" --dns.print=name|pid - print DNS configuration.\n");
printf(" --env=name=value - set environment variable.\n");
printf(" --force - attempt to start a new sandbox inside the existing sandbox.\n");
printf(" --fs.print=name|pid - print the filesystem log.\n");
@ -86,7 +86,7 @@ void usage(void) {
printf(" --hostname=name - set sandbox hostname.\n");
printf(" --hosts-file=file - use file as /etc/hosts.\n");
printf(" --ignore=command - ignore command in profile files.\n");
#ifdef HAVE_NETWORK
#ifdef HAVE_NETWORK
printf(" --interface=name - move interface in sandbox.\n");
printf(" --ip=address - set interface IP address.\n");
printf(" --ip=none - no IP address and no default gateway are configured.\n");
@ -96,21 +96,21 @@ void usage(void) {
printf(" --ipc-namespace - enable a new IPC namespace.\n");
printf(" --join=name|pid - join the sandbox.\n");
printf(" --join-filesystem=name|pid - join the mount namespace.\n");
#ifdef HAVE_NETWORK
#ifdef HAVE_NETWORK
printf(" --join-network=name|pid - join the network namespace.\n");
#endif
printf(" --join-or-start=name|pid - join the sandbox or start a new one.\n");
printf(" --list - list all sandboxes.\n");
printf(" --ls=name|pid dir_or_filename - list files in sandbox container.\n");
#ifdef HAVE_NETWORK
#ifdef HAVE_NETWORK
printf(" --mac=xx:xx:xx:xx:xx:xx - set interface MAC address.\n");
#endif
printf(" --machine-id - preserve /etc/machine-id\n");
#ifdef HAVE_NETWORK
#ifdef HAVE_NETWORK
printf(" --mtu=number - set interface MTU.\n");
#endif
printf(" --name=name - set sandbox name.\n");
#ifdef HAVE_NETWORK
#ifdef HAVE_NETWORK
printf(" --net=bridgename - enable network namespaces and connect to this bridge.\n");
printf(" --net=ethernet_interface - enable network namespaces and connect to this\n");
printf("\tEthernet interface.\n");
@ -127,17 +127,18 @@ void usage(void) {
printf(" --nogroups - disable supplementary groups.\n");
printf(" --nonewprivs - sets the NO_NEW_PRIVS prctl.\n");
printf(" --noprofile - do not use a security profile.\n");
#ifdef HAVE_USERNS
#ifdef HAVE_USERNS
printf(" --noroot - install a user namespace with only the current user.\n");
#endif
printf(" --nosound - disable sound system.\n");
printf(" --novideo - disable video devices.\n");
printf(" --nowhitelist=filename - disable whitelist for file or directory .\n");
printf(" --output=logfile - stdout logging and log rotation.\n");
printf(" --overlay - mount a filesystem overlay on top of the current filesystem.\n");
printf(" --overlay-named=name - mount a filesystem overlay on top of the current\n");
printf("\tfilesystem, and store it in name directory.\n");
printf(" --overlay-tmpfs - mount a temporary filesystem overlay on top of the current\n");
printf("\tfilesystem.\n");
printf("\tfilesystem.\n");
printf(" --overlay-clean - clean all overlays stored in $HOME/.firejail directory.\n");
printf(" --private - temporary home directory.\n");
printf(" --private=directory - use directory as user home.\n");
@ -169,9 +170,9 @@ void usage(void) {
printf(" --rlimit-sigpending=number - set the maximum number of pending signals\n");
printf("\tfor a process.\n");
printf(" --rmenv=name - remove environment variable in the new sandbox.\n");
#ifdef HAVE_NETWORK
#ifdef HAVE_NETWORK
printf(" --scan - ARP-scan all the networks from inside a network namespace.\n");
#endif
#endif
#ifdef HAVE_SECCOMP
printf(" --seccomp - enable seccomp filter and apply the default blacklist.\n");
printf(" --seccomp=syscall,syscall,syscall - enable seccomp filter, blacklist the\n");
@ -195,12 +196,12 @@ void usage(void) {
printf("\tdirectoires blacklisted by the security profile.\n");
printf(" --tree - print a tree of all sandboxed processes.\n");
printf(" --version - print program version and exit.\n");
#ifdef HAVE_NETWORK
printf(" --veth-name=name - use this name for the interface connected to the bridge.\n");
#endif
#ifdef HAVE_WHITELIST
#ifdef HAVE_NETWORK
printf(" --veth-name=name - use this name for the interface connected to the bridge.\n");
#endif
#ifdef HAVE_WHITELIST
printf(" --whitelist=filename - whitelist directory or file.\n");
#endif
#endif
printf(" --writable-etc - /etc directory is mounted read-write.\n");
printf(" --writable-var - /var directory is mounted read-write.\n");
printf(" --writable-var-log - use the real /var/log directory, not a clone.\n");

View file

@ -50,7 +50,7 @@ Parent pid 8553, child pid 8554
.br
Child process initialized
.br
[...]
[...]
.br
.br
@ -92,7 +92,7 @@ Example: "include ${CFG}/firefox.profile" will load "/etc/firejail/firefox.profi
System configuration files in ${CFG} are overwritten during software installation.
Persistent configuration at system level is handled in ".local" files. For every
profile file in ${CFG} directory, the user can create a corresponding .local file
profile file in ${CFG} directory, the user can create a corresponding .local file
storing modifications to the persistent configuration. Persistent .local files
are included at the start of regular profile files.
@ -255,7 +255,7 @@ Blacklist violations logged to syslog.
\fBwhitelist file_or_directory
Whitelist directory or file. A temporary file system is mounted on the top directory, and the
whitelisted files are mount-binded inside. Modifications to whitelisted files are persistent,
everything else is discarded when the sandbox is closed. The top directory could be
everything else is discarded when the sandbox is closed. The top directory could be
user home, /dev, /media, /mnt, /opt, /srv, /var, and /tmp.
.br
@ -405,6 +405,8 @@ Enable IPC namespace.
\fBnosound
Disable sound system.
.TP
\fBnovideo
Disable video devices.
\fBno3d
Disable 3D hardware acceleration.
@ -533,7 +535,7 @@ really need network access.
.TP
\fBveth-name name
Use this name for the interface connected to the bridge for --net=bridge_interface commands,
Use this name for the interface connected to the bridge for --net=bridge_interface commands,
instead of the default one.
.SH Other
@ -585,6 +587,3 @@ Homepage: http://firejail.wordpress.com
\&\flfiremon\fR\|(1),
\&\flfirecfg\fR\|(1),
\&\flfirejail-login\fR\|(5)

View file

@ -42,7 +42,7 @@ and it is integrated with Linux Control Groups.
.PP
Written in C with virtually no dependencies, the software runs on any Linux computer with a 3.x kernel version
or newer.
It can sandbox any type of processes: servers, graphical applications, and even user login sessions.
It can sandbox any type of processes: servers, graphical applications, and even user login sessions.
.PP
Firejail allows the user to manage application security using security profiles.
Each profile defines a set of permissions for a specific application or group
@ -52,13 +52,13 @@ Linux programs, such as Mozilla Firefox, Chromium, VLC, Transmission etc.
.SH USAGE
Without any options, the sandbox consists of a filesystem build in a new mount namespace,
and new PID and UTS namespaces. IPC, network and user namespaces can be added using the
command line options. The default Firejail filesystem is based on the host filesystem with the main
system directories mounted read-only. These directories are /etc, /var, /usr, /bin, /sbin, /lib, /lib32,
command line options. The default Firejail filesystem is based on the host filesystem with the main
system directories mounted read-only. These directories are /etc, /var, /usr, /bin, /sbin, /lib, /lib32,
/libx32 and /lib64. Only /home and /tmp are writable.
.PP
As it starts up, Firejail tries to find a security profile based on the name of the application.
If an appropriate profile is not found, Firejail will use a default profile.
The default profile is quite restrictive. In case the application doesn't work, use --noprofile option
The default profile is quite restrictive. In case the application doesn't work, use --noprofile option
to disable it. For more information, please see \fBSECURITY PROFILES\fR section below.
.PP
If a program argument is not specified, Firejail starts /bin/bash shell.
@ -657,7 +657,7 @@ $ sudo firejail --join-network=browser ip addr
.br
Switching to pid 1932, the first child process inside the sandbox
.br
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
.br
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
.br
@ -665,11 +665,11 @@ Switching to pid 1932, the first child process inside the sandbox
.br
valid_lft forever preferred_lft forever
.br
inet6 ::1/128 scope host
inet6 ::1/128 scope host
.br
valid_lft forever preferred_lft forever
.br
2: eth0-1931: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
2: eth0-1931: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
.br
link/ether 76:58:14:42:78:e4 brd ff:ff:ff:ff:ff:ff
.br
@ -677,7 +677,7 @@ Switching to pid 1932, the first child process inside the sandbox
.br
valid_lft forever preferred_lft forever
.br
inet6 fe80::7458:14ff:fe42:78e4/64 scope link
inet6 fe80::7458:14ff:fe42:78e4/64 scope link
.br
valid_lft forever preferred_lft forever
@ -702,13 +702,13 @@ Example:
.br
$ firejail \-\-list
.br
7015:netblue:firejail firefox
7015:netblue:firejail firefox
.br
7056:netblue:firejail \-\-net=eth0 transmission-gtk
7056:netblue:firejail \-\-net=eth0 transmission-gtk
.br
7064:netblue:firejail \-\-noroot xterm
7064:netblue:firejail \-\-noroot xterm
.br
$
$
.TP
\fB\-\-mac=address
Assign MAC addresses to the last network interface defined by a \-\-net option.
@ -998,7 +998,7 @@ $
.TP
\fB\-\-noprofile
Do not use a security profile.
Do not use a security profile.
.br
.br
@ -1012,7 +1012,7 @@ Parent pid 8553, child pid 8554
.br
Child process initialized
.br
[...]
[...]
.br
.br
@ -1066,6 +1066,11 @@ Example:
.br
$ firejail \-\-nosound firefox
.TP
\fB\-\-novideo
Disable video devices.
.br
.TP
\fB\-\-nowhitelist=dirname_or_filename
Disable whitelist for this directory or file.
@ -1200,7 +1205,7 @@ $ firejail \-\-private-home=.mozilla firefox
Build a new /bin in a temporary filesystem, and copy the programs in the list.
If no listed file is found, /bin directory will be empty.
The same directory is also bind-mounted over /sbin, /usr/bin, /usr/sbin and /usr/local/bin.
All modifications are discarded when the sandbox is closed.
All modifications are discarded when the sandbox is closed.
.br
.br
@ -1240,7 +1245,7 @@ $
Build a new /etc in a temporary
filesystem, and copy the files and directories in the list.
If no listed file is found, /etc directory will be empty.
All modifications are discarded when the sandbox is closed.
All modifications are discarded when the sandbox is closed.
.br
.br
@ -1255,7 +1260,7 @@ nsswitch.conf,passwd,resolv.conf
Build a new /opt in a temporary
filesystem, and copy the files and directories in the list.
If no listed file is found, /opt directory will be empty.
All modifications are discarded when the sandbox is closed.
All modifications are discarded when the sandbox is closed.
.br
.br
@ -1268,7 +1273,7 @@ $ firejail --private-opt=firefox /opt/firefox/firefox
Build a new /srv in a temporary
filesystem, and copy the files and directories in the list.
If no listed file is found, /srv directory will be empty.
All modifications are discarded when the sandbox is closed.
All modifications are discarded when the sandbox is closed.
.br
.br
@ -1573,7 +1578,7 @@ SECCOMP Filter:
.br
RETURN_ALLOW
.br
$
$
.TP
\fB\-\-shell=none
Run the program directly, without a user shell.
@ -1665,7 +1670,7 @@ parent is shutting down, bye...
.TP
\fB\-\-tracelog
This option enables auditing blacklisted files and directories. A message
is sent to syslog in case the file or the directory is accessed.
is sent to syslog in case the file or the directory is accessed.
.br
.br
@ -1698,13 +1703,13 @@ $ firejail \-\-tree
.br
11903:netblue:firejail iceweasel
.br
11904:netblue:iceweasel
11904:netblue:iceweasel
.br
11957:netblue:/usr/lib/iceweasel/plugin-container
.br
11969:netblue:firejail \-\-net=eth0 transmission-gtk
11969:netblue:firejail \-\-net=eth0 transmission-gtk
.br
11970:netblue:transmission-gtk
11970:netblue:transmission-gtk
.TP
\fB\-\-version
@ -1720,7 +1725,7 @@ firejail version 0.9.27
.TP
\fB\-\-veth-name=name
Use this name for the interface connected to the bridge for --net=bridge_interface commands,
Use this name for the interface connected to the bridge for --net=bridge_interface commands,
instead of the default one.
.br
@ -1733,7 +1738,7 @@ $ firejail \-\-net=br0 --veth-name=if0
\fB\-\-whitelist=dirname_or_filename
Whitelist directory or file. A temporary file system is mounted on the top directory, and the
whitelisted files are mount-binded inside. Modifications to whitelisted files are persistent,
everything else is discarded when the sandbox is closed. The top directory could be
everything else is discarded when the sandbox is closed. The top directory could be
user home, /dev, /media, /mnt, /opt, /srv, /var, and /tmp.
.br
@ -1789,7 +1794,7 @@ Sandbox the application using Xpra, Xephyr, Xvfb or Xorg security extension.
The sandbox will prevents screenshot and keylogger applications started inside the sandbox from accessing
clients running outside the sandbox.
Firejail will try first Xpra, and if Xpra is not installed on the system, it will try to find Xephyr.
If all fails, Firejail will not attempt to use Xvfb or X11 security extension.
If all fails, Firejail will not attempt to use Xvfb or X11 security extension.
.br
.br
@ -1828,7 +1833,7 @@ A security profile for OpenBox is provided.
.br
Xephyr is developed by Xorg project. On Debian platforms it is installed with the command \fBsudo apt-get install xserver-xephyr\fR.
This feature is not available when running as root.
This feature is not available when running as root.
.br
.br
@ -1838,9 +1843,9 @@ $ firejail \-\-x11=xephyr --net=eth0 openbox
.TP
\fB\-\-x11=xorg
Sandbox the application using the untrusted mode implemented by X11 security extension.
Sandbox the application using the untrusted mode implemented by X11 security extension.
The extension is available in Xorg package
and it is installed by default on most Linux distributions. It provides support for a simple trusted/untrusted
and it is installed by default on most Linux distributions. It provides support for a simple trusted/untrusted
connection model. Untrusted clients are restricted in certain ways to prevent them from reading window
contents of other clients, stealing input events, etc.
@ -1875,9 +1880,9 @@ $ firejail \-\-x11=xpra --net=eth0 firefox
.TP
\fB\-\-x11=xvfb
Start Xvfb X11 server and attach the sandbox to this server.
Xvfb, short for X virtual framebuffer, performs all graphical operations in memory
without showing any screen output. Xvfb is mainly used for remote access and software
Start Xvfb X11 server and attach the sandbox to this server.
Xvfb, short for X virtual framebuffer, performs all graphical operations in memory
without showing any screen output. Xvfb is mainly used for remote access and software
testing on headless servers.
.br
@ -1992,7 +1997,7 @@ $ firejail --tree
.br
1190:netblue:firejail firefox
.br
1220:netblue:/bin/sh -c "/usr/lib/firefox/firefox"
1220:netblue:/bin/sh -c "/usr/lib/firefox/firefox"
.br
1221:netblue:/usr/lib/firefox/firefox
.RE
@ -2246,7 +2251,7 @@ Parent pid 8553, child pid 8554
.br
Child process initialized
.br
[...]
[...]
.br
.br
@ -2260,7 +2265,7 @@ Child process initialized
.RE
See man 5 firejail-profile for profile file syntax information.
.SH RESTRICTED SHELL
To configure a restricted shell, replace /bin/bash with /usr/bin/firejail in
/etc/passwd file for each user that needs to be restricted. Alternatively,
@ -2307,6 +2312,3 @@ Homepage: http://firejail.wordpress.com
\&\flfirecfg\fR\|(1),
\&\flfirejail-profile\fR\|(5),
\&\flfirejail-login\fR\|(5)