mirror of
https://github.com/netblue30/firejail.git
synced 2026-05-21 06:45:29 -06:00
Merge pull request #1296 from Fred-Barclay/novideo
WIP: --novideo option
This commit is contained in:
commit
e0e910e4be
8 changed files with 389 additions and 361 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue