more --build

This commit is contained in:
netblue30 2021-05-06 15:39:36 -04:00
parent 9adeaf0c6f
commit 43e47483ff
6 changed files with 134 additions and 157 deletions

View file

@ -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");
}
}

View file

@ -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",

View file

@ -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());

View file

@ -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);

View file

@ -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

View file

@ -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;
}