mirror of
https://github.com/netblue30/firejail.git
synced 2026-05-15 14:16:14 -06:00
more --build
This commit is contained in:
parent
9adeaf0c6f
commit
43e47483ff
6 changed files with 134 additions and 157 deletions
|
|
@ -83,11 +83,9 @@ static void process_bin(const char *fname) {
|
|||
continue;
|
||||
*ptr2 = '\0';
|
||||
|
||||
// skip strace
|
||||
if (strcmp(ptr, "strace") == 0)
|
||||
continue;
|
||||
|
||||
bin_out = filedb_add(bin_out, ptr);
|
||||
// skip strace and firejail (in case we hit a symlink in /usr/local/bin)
|
||||
if (strcmp(ptr, "strace") && strcmp(ptr, "firejail"))
|
||||
bin_out = filedb_add(bin_out, ptr);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
|
@ -121,6 +119,5 @@ void build_bin(const char *fname, FILE *fp) {
|
|||
ptr = ptr->next;
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
fprintf(fp, "#private-lib\n");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -146,106 +146,57 @@ void build_etc(const char *fname, FILE *fp) {
|
|||
//*******************************************
|
||||
// var directory
|
||||
//*******************************************
|
||||
#if 0
|
||||
// todo: load the list from whitelist-var-common.inc
|
||||
static char *var_skip[] = {
|
||||
"/var/lib/ca-certificates",
|
||||
"/var/lib/dbus",
|
||||
"/var/lib/menu-xdg",
|
||||
"/var/lib/uim",
|
||||
"/var/cache/fontconfig",
|
||||
"/var/tmp",
|
||||
"/var/run",
|
||||
"/var/lock",
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
static FileDB *var_out = NULL;
|
||||
static FileDB *var_skip = NULL;
|
||||
static void var_callback(char *ptr) {
|
||||
if (strcmp(ptr, "/var/lib") == 0)
|
||||
;
|
||||
else if (strcmp(ptr, "/var/cache") == 0)
|
||||
;
|
||||
else if (strncmp(ptr, "/var/lib/menu-xdg", 17) == 0)
|
||||
var_out = filedb_add(var_out, "/var/lib/menu-xdg");
|
||||
else if (strncmp(ptr, "/var/cache/fontconfig", 21) == 0)
|
||||
var_out = filedb_add(var_out, "/var/cache/fontconfig");
|
||||
else
|
||||
var_out = filedb_add(var_out, ptr);
|
||||
// extract the directory:
|
||||
assert(strncmp(ptr, "/var", 4) == 0);
|
||||
char *p1 = ptr + 4;
|
||||
if (*p1 != '/')
|
||||
return;
|
||||
p1++;
|
||||
|
||||
if (*p1 == '/') // double '/'
|
||||
p1++;
|
||||
if (*p1 == '\0')
|
||||
return;
|
||||
|
||||
if (!filedb_find(var_skip, p1))
|
||||
var_out = filedb_add(var_out, p1);
|
||||
}
|
||||
|
||||
void build_var(const char *fname, FILE *fp) {
|
||||
assert(fname);
|
||||
|
||||
var_skip = filedb_load_whitelist(var_skip, "whitelist-var-common.inc", "whitelist /var/");
|
||||
process_files(fname, "/var", var_callback);
|
||||
|
||||
if (var_out == NULL) {
|
||||
fprintf(fp, "blacklist /var\n");
|
||||
} else {
|
||||
filedb_print(var_out, "whitelist ", fp);
|
||||
fprintf(fp, "include whitelist-var-common.inc\n");
|
||||
}
|
||||
// always whitelist /var
|
||||
if (var_out)
|
||||
filedb_print(var_out, "whitelist /var/", fp);
|
||||
fprintf(fp, "include whitelist-var-common.inc\n");
|
||||
}
|
||||
|
||||
|
||||
//*******************************************
|
||||
// usr/share directory
|
||||
//*******************************************
|
||||
// todo: load the list from whitelist-usr-share-common.inc
|
||||
static char *share_skip[] = {
|
||||
"/usr/share/alsa",
|
||||
"/usr/share/applications",
|
||||
"/usr/share/ca-certificates",
|
||||
"/usr/share/crypto-policies",
|
||||
"/usr/share/cursors",
|
||||
"/usr/share/dconf",
|
||||
"/usr/share/distro-info",
|
||||
"/usr/share/drirc.d",
|
||||
"/usr/share/enchant",
|
||||
"/usr/share/enchant-2",
|
||||
"/usr/share/file",
|
||||
"/usr/share/fontconfig",
|
||||
"/usr/share/fonts",
|
||||
"/usr/share/fonts-config",
|
||||
"/usr/share/gir-1.0",
|
||||
"/usr/share/gjs-1.0",
|
||||
"/usr/share/glib-2.0",
|
||||
"/usr/share/glvnd",
|
||||
"/usr/share/gtk-2.0",
|
||||
"/usr/share/gtk-3.0",
|
||||
"/usr/share/gtk-engines",
|
||||
"/usr/share/gtksourceview-3.0",
|
||||
"/usr/share/gtksourceview-4",
|
||||
"/usr/share/hunspell",
|
||||
"/usr/share/hwdata",
|
||||
"/usr/share/icons",
|
||||
"/usr/share/icu",
|
||||
"/usr/share/knotifications5",
|
||||
"/usr/share/kservices5",
|
||||
"/usr/share/Kvantum",
|
||||
"/usr/share/kxmlgui5",
|
||||
"/usr/share/libdrm",
|
||||
"/usr/share/libthai",
|
||||
"/usr/share/locale",
|
||||
"/usr/share/mime",
|
||||
"/usr/share/misc",
|
||||
"/usr/share/Modules",
|
||||
"/usr/share/myspell",
|
||||
"/usr/share/p11-kit",
|
||||
"/usr/share/perl",
|
||||
"/usr/share/perl5",
|
||||
"/usr/share/pixmaps",
|
||||
"/usr/share/pki",
|
||||
"/usr/share/plasma",
|
||||
"/usr/share/publicsuffix",
|
||||
"/usr/share/qt",
|
||||
"/usr/share/qt4",
|
||||
"/usr/share/qt5",
|
||||
"/usr/share/qt5ct",
|
||||
"/usr/share/sounds",
|
||||
"/usr/share/tcl8.6",
|
||||
"/usr/share/tcltk",
|
||||
"/usr/share/terminfo",
|
||||
"/usr/share/texlive",
|
||||
"/usr/share/texmf",
|
||||
"/usr/share/themes",
|
||||
"/usr/share/thumbnail.so",
|
||||
"/usr/share/uim",
|
||||
"/usr/share/vulkan",
|
||||
"/usr/share/X11",
|
||||
"/usr/share/xml",
|
||||
"/usr/share/zenity",
|
||||
"/usr/share/zoneinfo",
|
||||
NULL
|
||||
};
|
||||
|
||||
static FileDB *share_out = NULL;
|
||||
static FileDB *share_skip = NULL;
|
||||
static void share_callback(char *ptr) {
|
||||
// extract the directory:
|
||||
assert(strncmp(ptr, "/usr/share", 10) == 0);
|
||||
|
|
@ -263,30 +214,21 @@ static void share_callback(char *ptr) {
|
|||
if (p2)
|
||||
*p2 = '\0';
|
||||
|
||||
int i = 0;
|
||||
int found = 0;
|
||||
while (share_skip[i]) {
|
||||
if (strncmp(ptr, share_skip[i], strlen(share_skip[i])) == 0) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (!found)
|
||||
share_out = filedb_add(share_out, ptr);
|
||||
|
||||
if (!filedb_find(share_skip, p1))
|
||||
share_out = filedb_add(share_out, p1);
|
||||
}
|
||||
|
||||
void build_share(const char *fname, FILE *fp) {
|
||||
assert(fname);
|
||||
|
||||
share_skip = filedb_load_whitelist(share_skip, "whitelist-usr-share-common.inc", "whitelist /usr/share/");
|
||||
process_files(fname, "/usr/share", share_callback);
|
||||
|
||||
if (share_out == NULL) {
|
||||
fprintf(fp, "blacklist /usr/share\n");
|
||||
} else {
|
||||
filedb_print(share_out, "whitelist ", fp);
|
||||
fprintf(fp, "include whitelist-usr-share-common.inc\n");
|
||||
}
|
||||
// always whitelist /usr/share
|
||||
if (share_out)
|
||||
filedb_print(share_out, "whitelist /usr/share/", fp);
|
||||
fprintf(fp, "include whitelist-usr-share-common.inc\n");
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
|
|
@ -336,6 +278,7 @@ static char *dev_skip[] = {
|
|||
"/dev/null",
|
||||
"/dev/full",
|
||||
"/dev/random",
|
||||
"/dev/srandom",
|
||||
"/dev/urandom",
|
||||
"/dev/sr0",
|
||||
"/dev/cdrom",
|
||||
|
|
|
|||
|
|
@ -23,30 +23,6 @@
|
|||
static FileDB *db_skip = NULL;
|
||||
static FileDB *db_out = NULL;
|
||||
|
||||
static void load_whitelist_common(void) {
|
||||
FILE *fp = fopen(SYSCONFDIR "/whitelist-common.inc", "r");
|
||||
if (!fp) {
|
||||
fprintf(stderr, "Error: cannot open whitelist-common.inc\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char buf[MAX_BUF];
|
||||
while (fgets(buf, MAX_BUF, fp)) {
|
||||
if (strncmp(buf, "whitelist ${HOME}/", 18) != 0)
|
||||
continue;
|
||||
char *fn = buf + 18;
|
||||
char *ptr = strchr(buf, '\n');
|
||||
if (!ptr)
|
||||
continue;
|
||||
*ptr = '\0';
|
||||
|
||||
// add the file to skip list
|
||||
db_skip = filedb_add(db_skip, fn);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void process_home(const char *fname, char *home, int home_len) {
|
||||
assert(fname);
|
||||
assert(home);
|
||||
|
|
@ -162,7 +138,7 @@ void build_home(const char *fname, FILE *fp) {
|
|||
assert(fname);
|
||||
|
||||
// load whitelist common
|
||||
load_whitelist_common();
|
||||
db_skip = filedb_load_whitelist(db_skip, "whitelist-common.inc", "whitelist ${HOME}/");
|
||||
|
||||
// find user home directory
|
||||
struct passwd *pw = getpwuid(getuid());
|
||||
|
|
|
|||
|
|
@ -141,57 +141,70 @@ void build_profile(int argc, char **argv, int index, FILE *fp) {
|
|||
if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
|
||||
if (fp == stdout)
|
||||
printf("--- Built profile beings after this line ---\n");
|
||||
fprintf(fp, "# Firejail profile for %s\n", argv[index]);
|
||||
fprintf(fp, "# Save this file as \"application.profile\" (change \"application\" with the\n");
|
||||
fprintf(fp, "# program name) in ~/.config/firejail directory. Firejail will find it\n");
|
||||
fprintf(fp, "# automatically every time you sandbox your application.\n#\n");
|
||||
fprintf(fp, "# Run \"firejail application\" to test it. In the file there are\n");
|
||||
fprintf(fp, "# some other commands you can try. Enable them by removing the \"#\".\n");
|
||||
|
||||
fprintf(fp, "\n# Firejail profile for %s\n", argv[index]);
|
||||
fprintf(fp, "# Persistent local customizations\n");
|
||||
fprintf(fp, "#include %s.local\n", argv[index]);
|
||||
fprintf(fp, "# Persistent global definitions\n");
|
||||
fprintf(fp, "#include globals.local\n");
|
||||
fprintf(fp, "\n");
|
||||
|
||||
fprintf(fp, "### basic blacklisting\n");
|
||||
fprintf(fp, "### Basic Blacklisting ###\n");
|
||||
fprintf(fp, "### Enable as many of them as you can! A very important one is\n");
|
||||
fprintf(fp, "### \"disable-exec.inc\". This will make among other things your home\n");
|
||||
fprintf(fp, "### and /tmp directories non-executable.\n");
|
||||
fprintf(fp, "include disable-common.inc\n");
|
||||
fprintf(fp, "#include disable-devel.inc\n");
|
||||
fprintf(fp, "#include disable-exec.inc\n");
|
||||
fprintf(fp, "#include disable-interpreters.inc\n");
|
||||
fprintf(fp, "include disable-passwdmgr.inc\n");
|
||||
fprintf(fp, "#include disable-programs.inc\n");
|
||||
fprintf(fp, "include disable-programs.inc\n");
|
||||
fprintf(fp, "#include disable-xdg.inc\n");
|
||||
fprintf(fp, "\n");
|
||||
|
||||
fprintf(fp, "### home directory whitelisting\n");
|
||||
fprintf(fp, "### Home Directory Whitelisting ###\n");
|
||||
fprintf(fp, "### If something goes wrong, this section is the first one to comment out.\n");
|
||||
fprintf(fp, "### Instead, you'll have to relay on the basic blacklisting above.\n");
|
||||
build_home(trace_output, fp);
|
||||
|
||||
fprintf(fp, "\n### /usr/share:\n");
|
||||
fprintf(fp, "\n### The Rest of the Filesystem ###\n");
|
||||
build_share(trace_output, fp);
|
||||
fprintf(fp, "\n### /var:\n");
|
||||
build_var(trace_output, fp);
|
||||
fprintf(fp, "\n### /bin:\n");
|
||||
build_bin(trace_output, fp);
|
||||
fprintf(fp, "\n### /dev:\n");
|
||||
build_dev(trace_output, fp);
|
||||
fprintf(fp, "\n### /etc:\n");
|
||||
fprintf(fp, "#nodvd\n");
|
||||
fprintf(fp, "#noinput\n");
|
||||
fprintf(fp, "#notv\n");
|
||||
fprintf(fp, "#nou2f\n");
|
||||
fprintf(fp, "#novideo\n");
|
||||
build_etc(trace_output, fp);
|
||||
fprintf(fp, "\n### /tmp:\n");
|
||||
build_tmp(trace_output, fp);
|
||||
|
||||
fprintf(fp, "\n### security filters\n");
|
||||
fprintf(fp, "\n### Security Filters ###\n");
|
||||
fprintf(fp, "#apparmor\n");
|
||||
fprintf(fp, "caps.drop all\n");
|
||||
fprintf(fp, "netfilter\n");
|
||||
fprintf(fp, "#nogroups\n");
|
||||
fprintf(fp, "#noroot\n");
|
||||
fprintf(fp, "nonewprivs\n");
|
||||
fprintf(fp, "seccomp\n");
|
||||
if (!have_strace) {
|
||||
fprintf(fp, "# If you install strace on your system, Firejail will also create a\n");
|
||||
fprintf(fp, "# whitelisted seccomp filter.\n");
|
||||
}
|
||||
else if (!have_yama_permission)
|
||||
fprintf(fp, "# Yama security module prevents creation of a whitelisted seccomp filter\n");
|
||||
else
|
||||
build_seccomp(strace_output, fp);
|
||||
|
||||
fprintf(fp, "\n### network\n");
|
||||
build_protocol(trace_output, fp);
|
||||
|
||||
fprintf(fp, "\n### environment\n");
|
||||
fprintf(fp, "shell none\n");
|
||||
fprintf(fp, "seccomp\n");
|
||||
if (!have_strace) {
|
||||
fprintf(fp, "### If you install strace on your system, Firejail will also create a\n");
|
||||
fprintf(fp, "### whitelisted seccomp filter.\n");
|
||||
}
|
||||
else if (!have_yama_permission)
|
||||
fprintf(fp, "### Yama security module prevents creation of a whitelisted seccomp filter\n");
|
||||
else
|
||||
build_seccomp(strace_output, fp);
|
||||
fprintf(fp, "#shell none\n");
|
||||
fprintf(fp, "#tracelog\n");
|
||||
|
||||
if (!arg_debug) {
|
||||
unlink(trace_output);
|
||||
|
|
|
|||
|
|
@ -66,5 +66,6 @@ typedef struct filedb_t {
|
|||
FileDB *filedb_add(FileDB *head, const char *fname);
|
||||
FileDB *filedb_find(FileDB *head, const char *fname);
|
||||
void filedb_print(FileDB *head, const char *prefix, FILE *fp);
|
||||
FileDB *filedb_load_whitelist(FileDB *head, const char *fname, const char *prefix);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -20,7 +20,9 @@
|
|||
|
||||
#include "fbuilder.h"
|
||||
|
||||
// find exact name or an exact name in a parent directory
|
||||
FileDB *filedb_find(FileDB *head, const char *fname) {
|
||||
assert(fname);
|
||||
FileDB *ptr = head;
|
||||
int found = 0;
|
||||
int len = strlen(fname);
|
||||
|
|
@ -52,6 +54,8 @@ FileDB *filedb_find(FileDB *head, const char *fname) {
|
|||
FileDB *filedb_add(FileDB *head, const char *fname) {
|
||||
assert(fname);
|
||||
|
||||
// todo: support fnames such as ${RUNUSER}/.mutter-Xwaylandauth.*
|
||||
|
||||
// don't add it if it is already there or if the parent directory is already in the list
|
||||
if (filedb_find(head, fname))
|
||||
return head;
|
||||
|
|
@ -70,9 +74,52 @@ FileDB *filedb_add(FileDB *head, const char *fname) {
|
|||
};
|
||||
|
||||
void filedb_print(FileDB *head, const char *prefix, FILE *fp) {
|
||||
assert(head);
|
||||
assert(prefix);
|
||||
|
||||
FileDB *ptr = head;
|
||||
while (ptr) {
|
||||
fprintf(fp, "%s%s\n", prefix, ptr->fname);
|
||||
if (fp)
|
||||
fprintf(fp, "%s%s\n", prefix, ptr->fname);
|
||||
else
|
||||
printf("%s%s\n", prefix, ptr->fname);
|
||||
ptr = ptr->next;
|
||||
}
|
||||
}
|
||||
|
||||
FileDB *filedb_load_whitelist(FileDB *head, const char *fname, const char *prefix) {
|
||||
assert(fname);
|
||||
assert(prefix);
|
||||
int len = strlen(prefix);
|
||||
char *f;
|
||||
if (asprintf(&f, "%s/%s", SYSCONFDIR, fname) == -1)
|
||||
errExit("asprintf");
|
||||
FILE *fp = fopen(f, "r");
|
||||
if (!fp) {
|
||||
fprintf(stderr, "Error: cannot open whitelist-common.inc\n");
|
||||
free(f);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char buf[MAX_BUF];
|
||||
while (fgets(buf, MAX_BUF, fp)) {
|
||||
if (strncmp(buf, prefix, len) != 0)
|
||||
continue;
|
||||
|
||||
char *fn = buf + len;
|
||||
char *ptr = strchr(buf, '\n');
|
||||
if (!ptr)
|
||||
continue;
|
||||
*ptr = '\0';
|
||||
|
||||
// add the file to skip list
|
||||
head = filedb_add(head, fn);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
free(f);
|
||||
//printf("***************************************************\n");
|
||||
//filedb_print(head, prefix, NULL);
|
||||
//printf("***************************************************\n");
|
||||
return head;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue