Skip to content

Commit

Permalink
Merge pull request #4229 from smitsohu/whitelist2
Browse files Browse the repository at this point in the history
Whitelist2
  • Loading branch information
netblue30 authored May 18, 2021
2 parents bc2f52d + 9e7cad0 commit ed7db09
Show file tree
Hide file tree
Showing 13 changed files with 540 additions and 976 deletions.
4 changes: 4 additions & 0 deletions etc/firejail.config
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@
# Enable or disable whitelisting support, default enabled.
# whitelist yes

# Disable whitelist top level directories, in addition to those
# that are disabled out of the box. None by default; this is an example.
# whitelist-disable-topdir /etc,/usr/etc

# Enable or disable X11 sandboxing support, default enabled.
# x11 yes

Expand Down
26 changes: 26 additions & 0 deletions src/firejail/checkcfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ char *xvfb_extra_params = "";
char *netfilter_default = NULL;
unsigned long join_timeout = 5000000; // microseconds
char *config_seccomp_error_action_str = "EPERM";
char **whitelist_reject_topdirs = NULL;

int checkcfg(int val) {
assert(val < CFG_MAX);
Expand Down Expand Up @@ -238,6 +239,31 @@ int checkcfg(int val) {
errExit("strdup");
}

else if (strncmp(ptr, "whitelist-disable-topdir ", 25) == 0) {
char *str = strdup(ptr + 25);
if (!str)
errExit("strdup");

size_t cnt = 0;
size_t sz = 4;
whitelist_reject_topdirs = malloc(sz * sizeof(char *));
if (!whitelist_reject_topdirs)
errExit("malloc");

char *tok = strtok(str, ",");
while (tok) {
whitelist_reject_topdirs[cnt++] = tok;
if (cnt >= sz) {
sz *= 2;
whitelist_reject_topdirs = realloc(whitelist_reject_topdirs, sz * sizeof(char *));
if (!whitelist_reject_topdirs)
errExit("realloc");
}
tok = strtok(NULL, ",");
}
whitelist_reject_topdirs[cnt] = NULL;
}

else
goto errout;

Expand Down
8 changes: 4 additions & 4 deletions src/firejail/chroot.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,9 @@ void fs_chroot(const char *rootdir) {
assert(rootdir);

// fails if there is any symlink or if rootdir is not a directory
int parentfd = safe_fd(rootdir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
int parentfd = safer_openat(-1, rootdir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
if (parentfd == -1)
errExit("safe_fd");
errExit("safer_openat");
// rootdir has to be owned by root and is not allowed to be generally writable,
// this also excludes /tmp and friends
struct stat s;
Expand Down Expand Up @@ -215,12 +215,12 @@ void fs_chroot(const char *rootdir) {

if (arg_debug)
printf("Mounting %s on chroot %s\n", orig_pulse, orig_pulse);
int src = safe_fd(orig_pulse, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
int src = safer_openat(-1, orig_pulse, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
if (src == -1) {
fprintf(stderr, "Error: cannot open %s\n", orig_pulse);
exit(1);
}
int dst = safe_fd(pulse, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
int dst = safer_openat(-1, pulse, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
if (dst == -1) {
fprintf(stderr, "Error: cannot open %s\n", pulse);
exit(1);
Expand Down
2 changes: 1 addition & 1 deletion src/firejail/dbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ void dbus_proxy_stop(void) {
}

static void socket_overlay(char *socket_path, char *proxy_path) {
int fd = safe_fd(proxy_path, O_PATH | O_NOFOLLOW | O_CLOEXEC);
int fd = safer_openat(-1, proxy_path, O_PATH | O_NOFOLLOW | O_CLOEXEC);
if (fd == -1)
errExit("opening DBus proxy socket");
struct stat s;
Expand Down
29 changes: 13 additions & 16 deletions src/firejail/firejail.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,26 +122,22 @@ typedef struct interface_t {
uint8_t configured;
} Interface;

typedef struct topdir_t {
char *path;
int fd;
} TopDir;

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
enum {
WLDIR_HOME = 1, // whitelist in home directory
WLDIR_TMP, // whitelist in /tmp directory
WLDIR_MEDIA, // whitelist in /media directory
WLDIR_MNT, // whitelist in /mnt directory
WLDIR_VAR, // whitelist in /var directory
WLDIR_DEV, // whitelist in /dev directory
WLDIR_OPT, // whitelist in /opt directory
WLDIR_SRV, // whitelist in /srv directory
WLDIR_ETC, // whitelist in /etc directory
WLDIR_SHARE, // whitelist in /usr/share directory
WLDIR_MODULE, // whitelist in /sys/module directory
WLDIR_RUN // whitelist in /run/user/$uid directory
} wldir;
struct wparam_t {
char *file; // resolved file path
char *link; // link path
TopDir *top; // top level directory
} *wparam;

} ProfileEntry;

typedef struct config_t {
Expand Down Expand Up @@ -529,7 +525,7 @@ void mkdir_attr(const char *fname, mode_t mode, uid_t uid, gid_t gid);
unsigned extract_timeout(const char *str);
void disable_file_or_dir(const char *fname);
void disable_file_path(const char *path, const char *file);
int safe_fd(const char *path, int flags);
int safer_openat(int dirfd, const char *path, int flags);
int has_handler(pid_t pid, int signal);
void enter_network_namespace(pid_t pid);
int read_pid(const char *name, pid_t *pid);
Expand Down Expand Up @@ -794,6 +790,7 @@ extern char *xvfb_extra_params;
extern char *netfilter_default;
extern unsigned long join_timeout;
extern char *config_seccomp_error_action_str;
extern char **whitelist_reject_topdirs;

int checkcfg(int val);
void print_compiletime_support(void);
Expand Down
10 changes: 5 additions & 5 deletions src/firejail/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ void fs_tmpfs(const char *dir, unsigned check_owner) {
if (arg_debug)
printf("Mounting tmpfs on %s, check owner: %s\n", dir, (check_owner)? "yes": "no");
// get a file descriptor for dir, fails if there is any symlink
int fd = safe_fd(dir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
int fd = safer_openat(-1, dir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
if (fd == -1)
errExit("while opening directory");
struct stat s;
Expand Down Expand Up @@ -493,7 +493,7 @@ static void fs_remount_simple(const char *path, OPERATION op) {
assert(path);

// open path without following symbolic links
int fd1 = safe_fd(path, O_PATH|O_NOFOLLOW|O_CLOEXEC);
int fd1 = safer_openat(-1, path, O_PATH|O_NOFOLLOW|O_CLOEXEC);
if (fd1 == -1)
goto out;
struct stat s1;
Expand Down Expand Up @@ -559,7 +559,7 @@ static void fs_remount_simple(const char *path, OPERATION op) {

// mount --bind -o remount,ro path
// need to open path again without following symbolic links
int fd2 = safe_fd(path, O_PATH|O_NOFOLLOW|O_CLOEXEC);
int fd2 = safer_openat(-1, path, O_PATH|O_NOFOLLOW|O_CLOEXEC);
if (fd2 == -1)
errExit("open");
struct stat s2;
Expand Down Expand Up @@ -992,9 +992,9 @@ void fs_overlayfs(void) {
char *firejail;
if (asprintf(&firejail, "%s/.firejail", cfg.homedir) == -1)
errExit("asprintf");
int fd = safe_fd(firejail, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
int fd = safer_openat(-1, firejail, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
if (fd == -1)
errExit("safe_fd");
errExit("safer_openat");
free(firejail);
// create basedir if it doesn't exist
// the new directory will be owned by root
Expand Down
6 changes: 3 additions & 3 deletions src/firejail/fs_home.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,10 +262,10 @@ void fs_private_homedir(void) {
if (arg_debug)
printf("Mount-bind %s on top of %s\n", private_homedir, homedir);
// get file descriptors for homedir and private_homedir, fails if there is any symlink
int src = safe_fd(private_homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
int src = safer_openat(-1, private_homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
if (src == -1)
errExit("opening private directory");
int dst = safe_fd(homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
int dst = safer_openat(-1, homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
if (dst == -1)
errExit("opening home directory");
// both mount source and target should be owned by the user
Expand Down Expand Up @@ -576,7 +576,7 @@ void fs_private_home_list(void) {
if (arg_debug)
printf("Mount-bind %s on top of %s\n", RUN_HOME_DIR, homedir);

int fd = safe_fd(homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
int fd = safer_openat(-1, homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
if (fd == -1)
errExit("opening home directory");
// home directory should be owned by the user
Expand Down
Loading

0 comments on commit ed7db09

Please sign in to comment.