From 43e47483ff94753655ade1e633e973725d8fb505 Mon Sep 17 00:00:00 2001 From: netblue30 Date: Thu, 6 May 2021 15:39:36 -0400 Subject: more --build --- src/fbuilder/build_bin.c | 9 +-- src/fbuilder/build_fs.c | 145 +++++++++++++------------------------------ src/fbuilder/build_home.c | 26 +------- src/fbuilder/build_profile.c | 53 ++++++++++------ src/fbuilder/fbuilder.h | 1 + src/fbuilder/filedb.c | 49 ++++++++++++++- 6 files changed, 130 insertions(+), 153 deletions(-) (limited to 'src/fbuilder') diff --git a/src/fbuilder/build_bin.c b/src/fbuilder/build_bin.c index 431aebee6..9577042c4 100644 --- a/src/fbuilder/build_bin.c +++ b/src/fbuilder/build_bin.c @@ -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"); } } diff --git a/src/fbuilder/build_fs.c b/src/fbuilder/build_fs.c index b35380b96..8700e0ba1 100644 --- a/src/fbuilder/build_fs.c +++ b/src/fbuilder/build_fs.c @@ -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", diff --git a/src/fbuilder/build_home.c b/src/fbuilder/build_home.c index d7706282a..b3ec6cffd 100644 --- a/src/fbuilder/build_home.c +++ b/src/fbuilder/build_home.c @@ -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()); diff --git a/src/fbuilder/build_profile.c b/src/fbuilder/build_profile.c index 100630eb9..fb53f70a6 100644 --- a/src/fbuilder/build_profile.c +++ b/src/fbuilder/build_profile.c @@ -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"); + build_protocol(trace_output, fp); + 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"); + 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"); + 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, "#shell none\n"); + fprintf(fp, "#tracelog\n"); if (!arg_debug) { unlink(trace_output); diff --git a/src/fbuilder/fbuilder.h b/src/fbuilder/fbuilder.h index 8d3621c02..08dd35e10 100644 --- a/src/fbuilder/fbuilder.h +++ b/src/fbuilder/fbuilder.h @@ -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 diff --git a/src/fbuilder/filedb.c b/src/fbuilder/filedb.c index 6e302a606..94a226cb7 100644 --- a/src/fbuilder/filedb.c +++ b/src/fbuilder/filedb.c @@ -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; +} -- cgit v1.2.3-70-g09d2