From 7aaf184b257ee29de6d638d7d4d16c4ce81eddc6 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Dec 16 2021 10:22:22 +0000 Subject: import fapolicyd-1.0.4-2.el8 --- diff --git a/.fapolicyd.metadata b/.fapolicyd.metadata index e4598df..5404cab 100644 --- a/.fapolicyd.metadata +++ b/.fapolicyd.metadata @@ -1,2 +1,2 @@ -f3b2418bcbea4b2208de429e5fa449666af84b6e SOURCES/fapolicyd-1.0.2.tar.gz -30a587d8d696846ac05fbae206a8f563b2945189 SOURCES/fapolicyd-selinux-0.3.tar.gz +d0dd45121bf4a9ffa9f4d3e5c5bcdf89f5efa87a SOURCES/fapolicyd-1.0.4.tar.gz +bdbe20a4db2cd58073abf17a537e3a6766cdea21 SOURCES/fapolicyd-selinux-0.4.tar.gz diff --git a/.gitignore b/.gitignore index ed23384..3a38121 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -SOURCES/fapolicyd-1.0.2.tar.gz -SOURCES/fapolicyd-selinux-0.3.tar.gz +SOURCES/fapolicyd-1.0.4.tar.gz +SOURCES/fapolicyd-selinux-0.4.tar.gz diff --git a/SOURCES/fapolicyd-cli-hang.patch b/SOURCES/fapolicyd-cli-hang.patch deleted file mode 100644 index 52e7801..0000000 --- a/SOURCES/fapolicyd-cli-hang.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 3f43b262b1c5b9841fd0f387cac442aefeb84da9 Mon Sep 17 00:00:00 2001 -From: Radovan Sroka -Date: Sun, 31 Jan 2021 18:49:10 +0100 -Subject: [PATCH] Added MDB_NOLOCK to cli mdb_env_open() (#114) - -- MDB_NOLOCK option resolves the issue with --dump-db hang - -Signed-off-by: Radovan Sroka ---- - src/cli/fapolicyd-cli.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/cli/fapolicyd-cli.c b/src/cli/fapolicyd-cli.c -index fe47948..befb8ce 100644 ---- a/src/cli/fapolicyd-cli.c -+++ b/src/cli/fapolicyd-cli.c -@@ -114,7 +114,7 @@ static int do_dump_db(void) - return 1; - } - mdb_env_set_maxdbs(env, 2); -- rc = mdb_env_open(env, DB_DIR, MDB_RDONLY, 0660); -+ rc = mdb_env_open(env, DB_DIR, MDB_RDONLY|MDB_NOLOCK, 0660); - if (rc) { - fprintf(stderr, "mdb_env_open failed, error %d %s\n", rc, - mdb_strerror(rc)); diff --git a/SOURCES/fapolicyd-dnf-plugin.patch b/SOURCES/fapolicyd-dnf-plugin.patch index f56763e..e0cfce3 100644 --- a/SOURCES/fapolicyd-dnf-plugin.patch +++ b/SOURCES/fapolicyd-dnf-plugin.patch @@ -1,14 +1,13 @@ -diff -up ./dnf/fapolicyd-dnf-plugin.py.plugin ./dnf/fapolicyd-dnf-plugin.py ---- ./dnf/fapolicyd-dnf-plugin.py.plugin 2021-02-11 13:41:27.837534982 +0100 -+++ ./dnf/fapolicyd-dnf-plugin.py 2021-02-11 13:41:50.750225335 +0100 -@@ -7,30 +7,8 @@ import sys - +diff --color -ru a/dnf/fapolicyd-dnf-plugin.py b/dnf/fapolicyd-dnf-plugin.py +--- a/dnf/fapolicyd-dnf-plugin.py 2021-11-12 20:21:54.000000000 +0100 ++++ b/dnf/fapolicyd-dnf-plugin.py 2021-11-18 16:29:03.919237116 +0100 +@@ -8,29 +8,9 @@ class Fapolicyd(dnf.Plugin): -- name = "fapolicyd" + name = "fapolicyd" - pipe = "/var/run/fapolicyd/fapolicyd.fifo" - file = None -- + def __init__(self, base, cli): pass @@ -33,3 +32,4 @@ diff -up ./dnf/fapolicyd-dnf-plugin.py.plugin ./dnf/fapolicyd-dnf-plugin.py - self.file.write("1") - self.file.close() + pass +Only in b/dnf: fapolicyd-dnf-plugin.py.plugin diff --git a/SOURCES/fapolicyd-do-manage-files.patch b/SOURCES/fapolicyd-do-manage-files.patch new file mode 100644 index 0000000..ce98850 --- /dev/null +++ b/SOURCES/fapolicyd-do-manage-files.patch @@ -0,0 +1,190 @@ +From 95ec2f9577abe98a73d8dcb9112043aa743fa7ad Mon Sep 17 00:00:00 2001 +From: Zoltan Fridrich +Date: Fri, 19 Nov 2021 18:15:33 +0100 +Subject: [PATCH] cli do_manage_file function refactoring and fix + +--- + src/cli/fapolicyd-cli.c | 159 ++++++++++++++++++++++------------------ + 1 file changed, 89 insertions(+), 70 deletions(-) + +diff --git a/src/cli/fapolicyd-cli.c b/src/cli/fapolicyd-cli.c +index ee5d5bd..30b92be 100644 +--- a/src/cli/fapolicyd-cli.c ++++ b/src/cli/fapolicyd-cli.c +@@ -207,87 +207,106 @@ static int do_dump_db(void) + return rc; + } + +- +-/* +- * This function always requires at least one option, the command. We can +- * guarantee that argv[2] is the command because getopt_long would have +- * printed an error otherwise. argv[3] would be an optional parameter based +- * on which command is being run. If argv[4] == "--trust-file" then argv[5] +- * specifies a trust file to operate on. +- * +- * The function returns 0 on success and 1 on failure +- */ +-static int do_manage_files(int argc, char * const argv[]) ++static int do_file_add(int argc, char * const argv[]) + { +- int rc = 0; ++ char full_path[PATH_MAX] = { 0 }; + +- if (argc > 0) { +- if ( (strcmp("add", argv[0]) != 0) +- && (strcmp("delete", argv[0]) != 0) +- && (strcmp("update", argv[0]) != 0) ) { +- fprintf(stderr, "%s is not valid option, choose from add|delete|update\n", argv[0]); +- goto args_err; +- } ++ if (argc == 1) { ++ if (!realpath(argv[0], full_path)) ++ return 3; ++ return file_append(full_path, NULL); + } ++ if (argc == 3) { ++ if (!realpath(argv[0], full_path)) ++ return 3; ++ if (strcmp("--trust-file", argv[1])) ++ return 2; ++ return file_append(full_path, argv[2]); ++ } ++ return 2; ++} + +- if (argc < 2) +- goto args_err; +- +- char full_path[PATH_MAX] = {0}; ++static int do_file_delete(int argc, char * const argv[]) ++{ ++ char full_path[PATH_MAX] = { 0 }; + +- if (realpath(argv[1], full_path) == NULL) { +- fprintf(stderr, "Cannot get realpath from: %s\n", argv[1]); +- perror("realpath"); +- goto args_err; ++ if (argc == 1) { ++ if (!realpath(argv[0], full_path)) ++ return 3; ++ return file_delete(full_path, NULL); + } ++ if (argc == 3) { ++ if (!realpath(argv[0], full_path)) ++ return 3; ++ if (strcmp("--trust-file", argv[1])) ++ return 2; ++ return file_delete(full_path, argv[2]); ++ } ++ return 2; ++} + +- if (strcmp("add", argv[0]) == 0) { +- switch (argc) { +- case 2: +- rc = file_append(full_path, NULL); +- break; +- case 4: +- if (strcmp("--trust-file", argv[2])) +- goto args_err; +- rc = file_append(full_path, argv[3]); +- break; +- default: +- goto args_err; +- } +- } else if (strcmp("delete", argv[0]) == 0) { +- switch (argc) { +- case 2: +- rc = file_delete(full_path, NULL); +- break; +- case 4: +- if (strcmp("--trust-file", argv[2])) +- goto args_err; +- rc = file_delete(full_path, argv[3]); +- break; +- default: +- goto args_err; +- } +- } else if (strcmp("update", argv[0]) == 0) { +- switch (argc) { +- case 2: +- rc = file_update(full_path, NULL); +- break; +- case 4: +- if (strcmp("--trust-file", argv[2])) +- goto args_err; +- rc = file_update(full_path, argv[3]); +- break; +- default: +- goto args_err; +- } ++static int do_file_update(int argc, char * const argv[]) ++{ ++ char full_path[PATH_MAX] = { 0 }; ++ ++ if (argc == 0) ++ return file_update("/", NULL); ++ if (argc == 1) { ++ if (!realpath(argv[0], full_path)) ++ return 3; ++ return file_update(full_path, NULL); ++ } ++ if (argc == 2) { ++ if (strcmp("--trust-file", argv[0])) ++ return 2; ++ return file_update("/", argv[1]); ++ } ++ if (argc == 3) { ++ if (!realpath(argv[0], full_path)) ++ return 3; ++ if (strcmp("--trust-file", argv[1])) ++ return 2; ++ return file_update(full_path, argv[2]); + } ++ return 2; ++} + +- return rc ? 1 : 0; ++static int do_manage_files(int argc, char * const argv[]) ++{ ++ int rc = 0; + +-args_err: +- fprintf(stderr, "Wrong number of arguments\n\n"); +- fprintf(stderr, "%s", usage); ++ if (argc < 1 || argc > 4) { ++ fprintf(stderr, "Wrong number of arguments\n"); ++ fprintf(stderr, "\n%s", usage); ++ return 1; ++ } ++ ++ if (!strcmp("add", argv[0])) ++ rc = do_file_add(argc - 1, argv + 1); ++ else if (!strcmp("delete", argv[0])) ++ rc = do_file_delete(argc - 1, argv + 1); ++ else if (!strcmp("update", argv[0])) ++ rc = do_file_update(argc - 1, argv + 1); ++ else { ++ fprintf(stderr, "%s is not a valid option, choose one of add|delete|update\n", argv[0]); ++ fprintf(stderr, "\n%s", usage); ++ return 1; ++ } + ++ switch (rc) { ++ case 0: // no error ++ return 0; ++ case 2: // args error ++ fprintf(stderr, "Wrong number of arguments\n"); ++ fprintf(stderr, "\n%s", usage); ++ break; ++ case 3: // realpath error ++ fprintf(stderr, "Can't obtain realpath from: %s\n", argv[1]); ++ fprintf(stderr, "\n%s", usage); ++ break; ++ default: // file function errors ++ break; ++ } + return 1; + } + diff --git a/SOURCES/fapolicyd-documentation.patch b/SOURCES/fapolicyd-documentation.patch new file mode 100644 index 0000000..0915497 --- /dev/null +++ b/SOURCES/fapolicyd-documentation.patch @@ -0,0 +1,16 @@ +diff --color -ru a/doc/fapolicyd.trust.5 b/doc/fapolicyd.trust.5 +--- a/doc/fapolicyd.trust.5 2021-11-12 20:21:54.000000000 +0100 ++++ b/doc/fapolicyd.trust.5 2021-12-07 13:28:18.358213561 +0100 +@@ -7,6 +7,12 @@ + contains list of trusted files/binaries for the application whitelisting daemon. You may add comments to the file by starting the line with a '#' character. + Each line has to contain three columns and space is a valid separator. The first column contains full path to the file, the second is size of the file in bytes + and the third is valid sha256 hash. ++.sp ++The directory \fI/etc/fapolicyd/trust\&.d\fR can be used to store multiple trust files\&. ++This way a privileged user can split the trust database into multiple files and manage them separately through \fBfapolicyd\-cli\fR\&. ++Functionally, the fapolicy daemon will behave the same way as if the whole trust database has been defined inside \fBfapolicyd\&.trust\fR file\&. ++Syntax and semantics of trust files inside \fBtrust\&.d\fR directory are the same as for \fBfapolicyd\&.trust\fR file (described above)\&. ++Trust files can either be created manually inside \fBtrust\&.d\fR directory or via \fBfapolicyd\-cli\fR\& (the latter option is recommended). + + .SH EXAMPLE + .PP diff --git a/SOURCES/fapolicyd-fanotify-read-error.patch b/SOURCES/fapolicyd-fanotify-read-error.patch deleted file mode 100644 index 7023449..0000000 --- a/SOURCES/fapolicyd-fanotify-read-error.patch +++ /dev/null @@ -1,30 +0,0 @@ -From d12dde7f3fdeb82a9fb064e26d260f40fb2036c0 Mon Sep 17 00:00:00 2001 -From: Steve Grubb -Date: Mon, 22 Mar 2021 10:38:31 -0400 -Subject: [PATCH] Do not exit on fanotify_event read failure - ---- - ChangeLog | 1 + - src/daemon/notify.c | 11 ++++++++--- - 2 files changed, 9 insertions(+), 3 deletions(-) - -diff --git a/src/daemon/notify.c b/src/daemon/notify.c -index 3e42b92..a83db39 100644 ---- a/src/daemon/notify.c -+++ b/src/daemon/notify.c -@@ -337,8 +337,13 @@ void handle_events(void) - len = read(fd, (void *) buf, sizeof(buf)); - } while (len == -1 && errno == EINTR && stop == 0); - if (len == -1 && errno != EAGAIN) { -- msg(LOG_ERR,"Error reading (%s)", strerror(errno)); -- exit(1); -+ // If we get this, we have no access to the file. We -+ // cannot formulate a reply either to deny it because -+ // we have nothing to work with. -+ msg(LOG_ERR, -+ "Error receiving fanotify_event (%s)", -+ strerror(errno)); -+ return; - } - if (stop) - return; diff --git a/SOURCES/fapolicyd-fix-escaping.patch b/SOURCES/fapolicyd-fix-escaping.patch new file mode 100644 index 0000000..8b32b05 --- /dev/null +++ b/SOURCES/fapolicyd-fix-escaping.patch @@ -0,0 +1,209 @@ +diff --color -ru a/init/fapolicyd.trust b/init/fapolicyd.trust +--- a/init/fapolicyd.trust 2021-11-12 20:21:54.000000000 +0100 ++++ b/init/fapolicyd.trust 2021-12-08 13:25:43.441187113 +0100 +@@ -1,3 +1,4 @@ ++# AUTOGENERATED FILE VERSION 2 + # This file contains a list of trusted files + # + # FULL PATH SIZE SHA256 +diff --color -ru a/src/cli/file-cli.c b/src/cli/file-cli.c +--- a/src/cli/file-cli.c 2021-11-12 20:21:54.000000000 +0100 ++++ b/src/cli/file-cli.c 2021-12-08 13:25:43.441187113 +0100 +@@ -89,9 +89,6 @@ + return 0; + } + +- +- +- + int file_append(const char *path, const char *fname) + { + set_message_mode(MSG_STDERR, DBG_NO); +@@ -110,11 +107,14 @@ + + char *dest = fname ? fapolicyd_strcat(TRUST_DIR_PATH, fname) : + TRUST_FILE_PATH; ++ + int rc = trust_file_append(dest, &add_list); + ++ list_empty(&add_list); ++ + if (fname) + free(dest); +- list_empty(&add_list); ++ + return rc ? -1 : 0; + } + +diff --color -ru a/src/library/trust-file.c b/src/library/trust-file.c +--- a/src/library/trust-file.c 2021-11-12 20:21:54.000000000 +0100 ++++ b/src/library/trust-file.c 2021-12-08 15:42:15.787206923 +0100 +@@ -51,6 +51,7 @@ + #define FTW_NOPENFD 1024 + #define FTW_FLAGS (FTW_ACTIONRETVAL | FTW_PHYS) + ++#define HEADER0 "# AUTOGENERATED FILE VERSION 2\n" + #define HEADER1 "# This file contains a list of trusted files\n" + #define HEADER2 "#\n" + #define HEADER3 "# FULL PATH SIZE SHA256\n" +@@ -137,12 +138,19 @@ + return 1; + } + +- size_t hlen = strlen(HEADER1); ++ size_t hlen; ++ hlen = strlen(HEADER0); ++ fwrite(HEADER0, hlen, 1, f); ++ ++ hlen = strlen(HEADER1); + fwrite(HEADER1, hlen, 1, f); ++ + hlen = strlen(HEADER2); + fwrite(HEADER2, hlen, 1, f); ++ + hlen = strlen(HEADER3); + fwrite(HEADER3, hlen, 1, f); ++ + hlen = strlen(HEADER4); + fwrite(HEADER4, hlen, 1, f); + +@@ -163,50 +171,49 @@ + return 0; + } + +- +- +-int trust_file_append(const char *fpath, const list_t *list) { +- int fd = open(fpath, O_CREAT | O_WRONLY | O_APPEND, 0600); +- if (fd == -1) { +- msg(LOG_ERR, "Cannot open %s", fpath); ++int trust_file_append(const char *fpath, list_t *list) ++{ ++ list_t content; ++ list_init(&content); ++ int rc = trust_file_load(fpath, &content); ++ if (rc) + return 1; +- } + + for (list_item_t *lptr = list->first; lptr; lptr = lptr->next) { +- int count = 1; +- char *line = make_path_string(lptr->index, &count); +- if (!line) +- continue; +- +- if (write(fd, line, count) == -1) { +- msg(LOG_ERR, "failed writing to %s\n", fpath); +- free(line); +- close(fd); +- return 2; +- } +- free(line); ++ int i = 0; ++ lptr->data = make_path_string(lptr->index, &i); + } + +- close(fd); +- return 0; ++ list_merge(&content, list); ++ write_out_list(&content, fpath); ++ list_empty(&content); ++ return rc ? 1 : 0; + } + + int trust_file_load(const char *fpath, list_t *list) + { ++ char buffer[BUFFER_SIZE]; ++ int escaped = 0; ++ long line = 0; ++ + FILE *file = fopen(fpath, "r"); + if (!file) { + msg(LOG_ERR, "Cannot open %s", fpath); + return 1; + } + +- char buffer[BUFFER_SIZE]; + while (fgets(buffer, BUFFER_SIZE, file)) { +- char name[4097], sha[65], *index, *data; ++ char name[4097], sha[65], *index = NULL, *data = NULL; + unsigned long sz; + unsigned int tsource = SRC_FILE_DB; + +- if (iscntrl(buffer[0]) || buffer[0] == '#') ++ line++; ++ ++ if (iscntrl(buffer[0]) || buffer[0] == '#') { ++ if (line == 1 && strncmp(buffer, HEADER0, strlen(HEADER0)) == 0) ++ escaped = 1; + continue; ++ } + + if (sscanf(buffer, FILE_READ_FORMAT, name, &sz, sha) != 3) { + msg(LOG_WARNING, "Can't parse %s", buffer); +@@ -217,7 +224,7 @@ + if (asprintf(&data, DATA_FORMAT, tsource, sz, sha) == -1) + data = NULL; + +- index = unescape(name); ++ index = escaped ? unescape(name) : strdup(name); + if (index == NULL) { + msg(LOG_ERR, "Could not unescape %s from %s", name, fpath); + free(data); +@@ -311,33 +318,22 @@ + + int trust_file_rm_duplicates(const char *fpath, list_t *list) + { +- FILE *file = fopen(fpath, "r"); +- if (!file) { +- msg(LOG_ERR, "Cannot open %s", fpath); +- return 1; +- } +- +- char buffer[BUFFER_SIZE]; +- while (fgets(buffer, BUFFER_SIZE, file)) { +- char thash[65], tpath[4097]; +- long unsigned size; ++ list_t trust_file; ++ list_init(&trust_file); + +- if (iscntrl(buffer[0]) || buffer[0] == '#') +- continue; ++ int rc = trust_file_load(fpath, &trust_file); ++ if (rc) ++ goto cleanup; + +- if (sscanf(buffer, FILE_READ_FORMAT, tpath, &size, thash) != 3) { +- msg(LOG_WARNING, "Can't parse %s", buffer); +- fclose(file); +- return 2; +- } +- +- list_remove(list, tpath); ++ for (list_item_t *lptr = trust_file.first; lptr; lptr = lptr->next) { ++ list_remove(list, lptr->index); + if (list->count == 0) + break; + } + +- fclose(file); +- return 0; ++cleanup: ++ list_empty(&trust_file); ++ return rc; + } + + +diff --color -ru a/src/library/trust-file.h b/src/library/trust-file.h +--- a/src/library/trust-file.h 2021-11-12 20:21:54.000000000 +0100 ++++ b/src/library/trust-file.h 2021-12-08 13:25:43.441187113 +0100 +@@ -30,8 +30,7 @@ + #define TRUST_FILE_PATH "/etc/fapolicyd/fapolicyd.trust" + #define TRUST_DIR_PATH "/etc/fapolicyd/trust.d/" + +-int trust_file_append(const char *fpath, const list_t *list); +- ++int trust_file_append(const char *fpath, list_t *list); + int trust_file_load(const char *fpath, list_t *list); + int trust_file_update_path(const char *fpath, const char *path); + int trust_file_delete_path(const char *fpath, const char *path); diff --git a/SOURCES/fapolicyd-magic-override.patch b/SOURCES/fapolicyd-magic-override.patch index 80ecd50..456f220 100644 --- a/SOURCES/fapolicyd-magic-override.patch +++ b/SOURCES/fapolicyd-magic-override.patch @@ -1,44 +1,50 @@ -diff -up ./init/fapolicyd-magic.magic ./init/fapolicyd-magic ---- ./init/fapolicyd-magic.magic 2021-01-05 16:27:53.000000000 +0100 -+++ ./init/fapolicyd-magic 2021-02-17 15:51:41.420604805 +0100 -@@ -1,9 +1,17 @@ - 0 string/w #!\ /usr/bin/bash Bourne-Again shell script text executable +diff --color -ru a/init/fapolicyd-magic b/init/fapolicyd-magic +--- a/init/fapolicyd-magic 2021-11-12 20:21:54.000000000 +0100 ++++ b/init/fapolicyd-magic 2021-11-18 16:20:01.123624990 +0100 +@@ -4,12 +4,20 @@ + 0 string/w #!\ /usr/bin/env\ bash Bourne-Again shell script text executable !:mime text/x-shellscript -+0 search/1/w #!\ /usr/bin/env\ bash Bourne-Again shell script text executable ++0 search/1/w #!\ /usr/bin/env\ bash Bourne-Again shell script text executable +!:strength + 15 +!:mime text/x-shellscript + 0 string/w #!\ /usr/bin/sh Shell script text executable !:mime text/x-shellscript -+0 search/1/w #!\ /usr/bin/env\ sh Shell script text executable + 0 string/w #!\ /usr/bin/env\ sh Shell script text executable + !:mime text/x-shellscript + ++0 search/1/w #!\ /usr/bin/env\ sh Shell script text executable +!:strength + 15 +!:mime text/x-shellscript + 0 string/wt #!\ /bin/rc Plan 9 shell script text executable !:mime text/x-plan9-shellscript -@@ -47,10 +55,18 @@ +@@ -57,6 +65,10 @@ !:strength + 15 !:mime text/x-python -+0 search/1/w #!\ /usr/bin/env\ python3 Python script text executable ++0 search/1/w #!\ /usr/bin/env\ python3 Python script text executable +!:strength + 15 +!:mime text/x-python + 0 search/1/wt #!\ /usr/bin/python2 Python script text executable !:strength + 15 !:mime text/x-python +@@ -65,6 +77,10 @@ + !:strength + 15 + !:mime text/x-python -+0 search/1/w #!\ /usr/bin/env\ python2 Python script text executable ++0 search/1/w #!\ /usr/bin/env\ python2 Python script text executable +!:strength + 15 +!:mime text/x-python + 0 search/1/wt #!\ /usr/bin/python Python script text executable !:strength + 15 !:mime text/x-python -@@ -72,6 +88,5 @@ +@@ -86,6 +102,5 @@ 0 search/1/wt #!\ /usr/bin/tclsh Tcl/Tk script text executable !:mime text/x-tcl diff --git a/SOURCES/fapolicyd-selinux.patch b/SOURCES/fapolicyd-selinux.patch new file mode 100644 index 0000000..26fafeb --- /dev/null +++ b/SOURCES/fapolicyd-selinux.patch @@ -0,0 +1,28 @@ +diff --color -ru a/fapolicyd-selinux-0.4/fapolicyd.te b/fapolicyd-selinux-0.4/fapolicyd.te +--- a/fapolicyd-selinux-0.4/fapolicyd.te 2021-03-23 10:21:31.000000000 +0100 ++++ b/fapolicyd-selinux-0.4/fapolicyd.te 2021-11-19 10:24:20.000002248 +0100 +@@ -63,23 +63,13 @@ + + files_mmap_usr_files(fapolicyd_t) + files_read_all_files(fapolicyd_t) +-files_watch_mount_generic_tmp_dirs(fapolicyd_t) +-files_watch_with_perm_generic_tmp_dirs(fapolicyd_t) +-files_watch_mount_root_dirs(fapolicyd_t) +-files_watch_with_perm_root_dirs(fapolicyd_t) + + fs_getattr_xattr_fs(fapolicyd_t) +-fs_watch_mount_tmpfs_dirs(fapolicyd_t) +-fs_watch_with_perm_tmpfs_dirs(fapolicyd_t) + + logging_send_syslog_msg(fapolicyd_t) + dbus_system_bus_client(fapolicyd_t) + +-userdom_watch_mount_tmp_dirs(fapolicyd_t) +-userdom_watch_with_perm_tmp_dirs(fapolicyd_t) +- + optional_policy(` + rpm_read_db(fapolicyd_t) +- allow fapolicyd_t rpm_var_lib_t:file { create }; +- allow fapolicyd_t rpm_var_lib_t:dir { add_name write }; ++ rpm_manage_db(fapolicyd_t) + ') diff --git a/SOURCES/fapolicyd-startup-message.patch b/SOURCES/fapolicyd-startup-message.patch deleted file mode 100644 index 4b0b078..0000000 --- a/SOURCES/fapolicyd-startup-message.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 54b0679719bf82e25b2b007a32f26b1654912fa2 Mon Sep 17 00:00:00 2001 -From: Steve Grubb -Date: Tue, 26 Jan 2021 15:07:05 -0500 -Subject: [PATCH] Add startup and shutdown syslog message - ---- - ChangeLog | 1 + - src/daemon/fapolicyd.c | 4 ++-- - 2 files changed, 3 insertions(+), 2 deletions(-) - -diff --git a/src/daemon/fapolicyd.c b/src/daemon/fapolicyd.c -index e0e01ae..55e085d 100644 ---- a/src/daemon/fapolicyd.c -+++ b/src/daemon/fapolicyd.c -@@ -491,7 +491,7 @@ int main(int argc, const char *argv[]) - pfd[1].fd = init_fanotify(&config, m); - pfd[1].events = POLLIN; - -- msg(LOG_DEBUG, "Starting to listen for events"); -+ msg(LOG_INFO, "Starting to listen for events"); - while (!stop) { - rc = poll(pfd, 2, -1); - -@@ -526,7 +526,7 @@ int main(int argc, const char *argv[]) - #endif - } - } -- msg(LOG_DEBUG, "shutting down..."); -+ msg(LOG_INFO, "shutting down..."); - shutdown_fanotify(m); - close(pfd[0].fd); - mlist_clear(m); diff --git a/SOURCES/fapolicyd-trust-file-append.patch b/SOURCES/fapolicyd-trust-file-append.patch new file mode 100644 index 0000000..99fb854 --- /dev/null +++ b/SOURCES/fapolicyd-trust-file-append.patch @@ -0,0 +1,117 @@ +diff --color -ru a/src/library/trust-file.c b/src/library/trust-file.c +--- a/src/library/trust-file.c 2021-12-13 09:37:56.633741747 +0100 ++++ b/src/library/trust-file.c 2021-12-13 13:44:13.689151921 +0100 +@@ -176,8 +176,11 @@ + list_t content; + list_init(&content); + int rc = trust_file_load(fpath, &content); +- if (rc) ++ // if trust file does not exist, we ignore it as it will be created while writing ++ if (rc == 2) { ++ // exit on parse error, we dont want invalid entries to be removed + return 1; ++ } + + for (list_item_t *lptr = list->first; lptr; lptr = lptr->next) { + int i = 0; +@@ -187,9 +190,16 @@ + list_merge(&content, list); + write_out_list(&content, fpath); + list_empty(&content); +- return rc ? 1 : 0; ++ return 0; + } + ++/** ++ * @brief Load trust file into list ++ * ++ * @param fpath Full path to trust file ++ * @param list Trust file will be loaded into this list ++ * @return 0 on success, 1 if file can't be open, 2 on parsing error ++ */ + int trust_file_load(const char *fpath, list_t *list) + { + char buffer[BUFFER_SIZE]; +@@ -197,10 +207,8 @@ + long line = 0; + + FILE *file = fopen(fpath, "r"); +- if (!file) { +- msg(LOG_ERR, "Cannot open %s", fpath); ++ if (!file) + return 1; +- } + + while (fgets(buffer, BUFFER_SIZE, file)) { + char name[4097], sha[65], *index = NULL, *data = NULL; +@@ -257,7 +265,17 @@ + { + list_t list; + list_init(&list); +- trust_file_load(fpath, &list); ++ int rc = trust_file_load(fpath, &list); ++ switch (rc) { ++ case 1: ++ msg(LOG_ERR, "Cannot open %s", fpath); ++ return 0; ++ case 2: ++ list_empty(&list); ++ return -1; ++ default: ++ break; ++ } + + int count = 0; + size_t path_len = strlen(path); +@@ -295,7 +313,17 @@ + { + list_t list; + list_init(&list); +- trust_file_load(fpath, &list); ++ int rc = trust_file_load(fpath, &list); ++ switch (rc) { ++ case 1: ++ msg(LOG_ERR, "Cannot open %s", fpath); ++ return 0; ++ case 2: ++ list_empty(&list); ++ return -1; ++ default: ++ break; ++ } + + int count = 0; + size_t path_len = strlen(path); +@@ -320,20 +348,26 @@ + { + list_t trust_file; + list_init(&trust_file); +- + int rc = trust_file_load(fpath, &trust_file); +- if (rc) +- goto cleanup; +- ++ switch (rc) { ++ case 1: ++ msg(LOG_ERR, "Cannot open %s", fpath); ++ return -1; ++ case 2: ++ list_empty(&trust_file); ++ return -1; ++ default: ++ break; ++ } ++ + for (list_item_t *lptr = trust_file.first; lptr; lptr = lptr->next) { + list_remove(list, lptr->index); + if (list->count == 0) + break; + } + +-cleanup: + list_empty(&trust_file); +- return rc; ++ return 0; + } + + diff --git a/SOURCES/fapolicyd-unlink-fifo1.patch b/SOURCES/fapolicyd-unlink-fifo1.patch deleted file mode 100644 index e92f3b6..0000000 --- a/SOURCES/fapolicyd-unlink-fifo1.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 8cf74e7f147836e81c3583a046e4dc2b4673a14c Mon Sep 17 00:00:00 2001 -From: Radovan Sroka -Date: Thu, 11 Mar 2021 14:45:50 +0100 -Subject: [PATCH] Ensure that fifo will be removed after termination - -- unlink_fifo() will be called after every succesful termination -because dnf/yum can hang if the pipe exists after daemon termination - -- move preconstruct_fifo() out of the scope because it is needed also -when the daemon is configured to run as root - -Signed-off-by: Radovan Sroka ---- - src/daemon/fapolicyd.c | 13 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - -diff --git a/src/daemon/fapolicyd.c b/src/daemon/fapolicyd.c -index 5dce666..c29611c 100644 ---- a/src/daemon/fapolicyd.c -+++ b/src/daemon/fapolicyd.c -@@ -446,6 +446,17 @@ int main(int argc, const char *argv[]) - openlog("fapolicyd", LOG_PID, LOG_DAEMON); - } - -+ // Set the exit function so there is always a fifo cleanup -+ if (atexit(unlink_fifo)) { -+ msg(LOG_ERR, "Cannot set exit function"); -+ exit(1); -+ } -+ -+ if (preconstruct_fifo(&config)) { -+ msg(LOG_ERR, "Cannot contruct a pipe"); -+ exit(1); -+ } -+ - // Setup filesystem to watch list - init_fs_list(config.watch_fs); - -@@ -454,8 +465,6 @@ int main(int argc, const char *argv[]) - - // If we are not going to be root, then setup necessary capabilities - if (config.uid != 0) { -- if (preconstruct_fifo(&config)) -- exit(1); - capng_clear(CAPNG_SELECT_BOTH); - capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, - CAP_DAC_OVERRIDE, CAP_SYS_ADMIN, CAP_SYS_PTRACE, --- -2.26.2 - diff --git a/SOURCES/fapolicyd-unlink-fifo2.patch b/SOURCES/fapolicyd-unlink-fifo2.patch deleted file mode 100644 index ea1f6f1..0000000 --- a/SOURCES/fapolicyd-unlink-fifo2.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 7c2726e8d9c3aa5f8f6710a7ea147bf99877e1a5 Mon Sep 17 00:00:00 2001 -From: Radovan Sroka -Date: Tue, 16 Mar 2021 12:49:48 +0100 -Subject: [PATCH] Fixed problem with startup failed on unlink() (#120) - -- introduced in 128e22d0c638aed81337a6dbbfa664e5bfc9ea06 - -- daemon does not start when unlinking non existing db -- fapolicyd-cli returned error when there is no db to unlink - -Signed-off-by: Radovan Sroka ---- - src/library/database.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/library/database.c b/src/library/database.c -index a010923..59816cb 100644 ---- a/src/library/database.c -+++ b/src/library/database.c -@@ -718,13 +718,13 @@ int unlink_db(void) - - snprintf(path, sizeof(path), "%s/data.mdb", data_dir); - rc = unlink(path); -- if (rc) { -+ if (rc == -1 && errno != ENOENT) { - msg(LOG_ERR, "Could not unlink %s (%s)", path, strerror(errno)); - ret_val = 1; - } - snprintf(path, sizeof(path), "%s/lock.mdb", data_dir); - rc = unlink(path); -- if (rc) { -+ if (rc == -1 && errno != ENOENT) { - msg(LOG_ERR, "Could not unlink %s (%s)", path, strerror(errno)); - ret_val = 1; - } diff --git a/SOURCES/fapolicyd-unlink1.patch b/SOURCES/fapolicyd-unlink1.patch deleted file mode 100644 index 37dc715..0000000 --- a/SOURCES/fapolicyd-unlink1.patch +++ /dev/null @@ -1,25 +0,0 @@ -From a0d93349003100ec773c3253e515c7162737c4c2 Mon Sep 17 00:00:00 2001 -From: Steve Grubb -Date: Wed, 3 Mar 2021 13:16:07 -0500 -Subject: [PATCH] Add error message for debugging - ---- - src/library/database.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/src/library/database.c b/src/library/database.c -index db52000..9497c06 100644 ---- a/src/library/database.c -+++ b/src/library/database.c -@@ -161,8 +161,10 @@ static int init_db(const conf_t *config) - return 4; - - int rc = mdb_env_open(env, data_dir, flags, 0660); -- if (rc) -+ if (rc) { -+ msg(LOG_ERR, "env_open error: %s", mdb_strerror(rc)); - return 5; -+ } - - MDB_maxkeysize = mdb_env_get_maxkeysize(env); - integrity = config->integrity; diff --git a/SOURCES/fapolicyd-unlink2.patch b/SOURCES/fapolicyd-unlink2.patch deleted file mode 100644 index 0e1fb4a..0000000 --- a/SOURCES/fapolicyd-unlink2.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 1b862f3b7c489928f1861396cebb763ae0654371 Mon Sep 17 00:00:00 2001 -From: Steve Grubb -Date: Wed, 3 Mar 2021 13:22:10 -0500 -Subject: [PATCH] Add error message for debugging - ---- - src/library/database.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -diff --git a/src/library/database.c b/src/library/database.c -index 9497c06..831ec74 100644 ---- a/src/library/database.c -+++ b/src/library/database.c -@@ -713,12 +713,17 @@ static int check_database_copy(void) - */ - void unlink_db(void) - { -+ int rc; - char path[64]; - - snprintf(path, sizeof(path), "%s/data.mdb", data_dir); -- unlink(path); -+ rc = unlink(path); -+ if (rc) -+ msg(LOG_ERR, "Could not unlink %s (%s)", path, strerror(errno)); - snprintf(path, sizeof(path), "%s/lock.mdb", data_dir); -- unlink(path); -+ rc = unlink(path); -+ if (rc) -+ msg(LOG_ERR, "Could not unlink %s (%s)", path, strerror(errno)); - } - - diff --git a/SOURCES/fapolicyd-unlink3.patch b/SOURCES/fapolicyd-unlink3.patch deleted file mode 100644 index 571cab5..0000000 --- a/SOURCES/fapolicyd-unlink3.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 128e22d0c638aed81337a6dbbfa664e5bfc9ea06 Mon Sep 17 00:00:00 2001 -From: Steve Grubb -Date: Wed, 3 Mar 2021 13:34:58 -0500 -Subject: [PATCH] If db migration fails due to unlinking problem, fail startup - ---- - ChangeLog | 1 + - src/cli/fapolicyd-cli.c | 5 +++-- - src/library/database.c | 22 ++++++++++++++++------ - src/library/database.h | 4 ++-- - 4 files changed, 22 insertions(+), 10 deletions(-) - -diff --git a/src/cli/fapolicyd-cli.c b/src/cli/fapolicyd-cli.c -index 994c9a6..fb9081b 100644 ---- a/src/cli/fapolicyd-cli.c -+++ b/src/cli/fapolicyd-cli.c -@@ -1,6 +1,6 @@ - /* - * fapolicy-cli.c - CLI tool for fapolicyd -- * Copyright (c) 2019,2020 Red Hat Inc. -+ * Copyright (c) 2019-2021 Red Hat Inc. - * All Rights Reserved. - * - * This software may be freely redistributed and/or modified under the -@@ -89,7 +89,8 @@ static char *get_line(FILE *f, unsigned *lineno) - - static int do_delete_db(void) - { -- unlink_db(); -+ if (unlink_db()) -+ return 1; - return 0; - } - -diff --git a/src/library/database.c b/src/library/database.c -index 831ec74..a010923 100644 ---- a/src/library/database.c -+++ b/src/library/database.c -@@ -1,6 +1,6 @@ - /* - * database.c - Trust database -- * Copyright (c) 2016,2018-20 Red Hat Inc. -+ * Copyright (c) 2016,2018-21 Red Hat Inc. - * All Rights Reserved. - * - * This software may be freely redistributed and/or modified under the -@@ -711,23 +711,32 @@ static int check_database_copy(void) - /* - * This function removes the trust database files. - */ --void unlink_db(void) -+int unlink_db(void) - { -- int rc; -+ int rc, ret_val = 0; - char path[64]; - - snprintf(path, sizeof(path), "%s/data.mdb", data_dir); - rc = unlink(path); -- if (rc) -+ if (rc) { - msg(LOG_ERR, "Could not unlink %s (%s)", path, strerror(errno)); -+ ret_val = 1; -+ } - snprintf(path, sizeof(path), "%s/lock.mdb", data_dir); - rc = unlink(path); -- if (rc) -+ if (rc) { - msg(LOG_ERR, "Could not unlink %s (%s)", path, strerror(errno)); -+ ret_val = 1; -+ } -+ -+ return ret_val; - } - - - /* -+ * DB version 1 = unique keys (0.8 - 0.9.2) -+ * DB version 2 = allow duplicate keys (0.9.3 - ) -+ * - * This function is used to detect if we are using version1 of the database. - * If so, we have to delete the database and rebuild it. We cannot mix - * database versions because lmdb doesn't do that. -@@ -744,7 +753,8 @@ static int migrate_database(void) - msg(LOG_INFO, "Database migration will be performed."); - - // Then we have a version1 db since it does not track versions -- unlink_db(); -+ if (unlink_db()) -+ return 1; - - // Create the new, db version tracker and write current version - fd = open(vpath, O_CREAT|O_EXCL|O_WRONLY, 0640); -diff --git a/src/library/database.h b/src/library/database.h -index e828503..f4516b2 100644 ---- a/src/library/database.h -+++ b/src/library/database.h -@@ -1,6 +1,6 @@ - /* - * database.h - Header file for trust database -- * Copyright (c) 2018-20 Red Hat Inc. -+ * Copyright (c) 2018-21 Red Hat Inc. - * All Rights Reserved. - * - * This software may be freely redistributed and/or modified under the -@@ -41,7 +41,7 @@ int init_database(conf_t *config); - int check_trust_database(const char *path, struct file_info *info, int fd); - void close_database(void); - void database_report(FILE *f); --void unlink_db(void); -+int unlink_db(void); - void unlink_fifo(void); - - #endif diff --git a/SOURCES/selinux.patch b/SOURCES/selinux.patch deleted file mode 100644 index ebedb50..0000000 --- a/SOURCES/selinux.patch +++ /dev/null @@ -1,19 +0,0 @@ -diff -up ./fapolicyd-selinux-0.3/fapolicyd.te.selinux ./fapolicyd-selinux-0.3/fapolicyd.te ---- ./fapolicyd-selinux-0.3/fapolicyd.te.selinux 2020-06-01 14:41:37.000000000 +0200 -+++ ./fapolicyd-selinux-0.3/fapolicyd.te 2021-03-19 10:50:13.885358270 +0100 -@@ -62,9 +62,14 @@ domain_read_all_domains_state(fapolicyd_ - files_mmap_usr_files(fapolicyd_t) - files_read_all_files(fapolicyd_t) - fs_getattr_xattr_fs(fapolicyd_t) -+kernel_read_all_sysctls(fapolicyd_t) -+kernel_read_all_proc(fapolicyd_t) - - logging_send_syslog_msg(fapolicyd_t) -+dbus_system_bus_client(fapolicyd_t) - - optional_policy(` -- rpm_read_db(fapolicyd_t) -+ rpm_read_db(fapolicyd_t) -+ allow fapolicyd_t rpm_var_lib_t:file { create }; -+ allow fapolicyd_t rpm_var_lib_t:dir { add_name write }; - ') diff --git a/SPECS/fapolicyd.spec b/SPECS/fapolicyd.spec index d14fde9..ed66f61 100644 --- a/SPECS/fapolicyd.spec +++ b/SPECS/fapolicyd.spec @@ -1,12 +1,12 @@ %global selinuxtype targeted %global moduletype contrib -%define semodule_version 0.3 +%define semodule_version 0.4 Summary: Application Whitelisting Daemon Name: fapolicyd -Version: 1.0.2 -Release: 6%{?dist} +Version: 1.0.4 +Release: 2%{?dist} License: GPLv3+ URL: http://people.redhat.com/sgrubb/fapolicyd Source0: https://people.redhat.com/sgrubb/fapolicyd/%{name}-%{version}.tar.gz @@ -28,23 +28,17 @@ Requires(postun): systemd-units Patch1: fapolicyd-magic-override.patch -Patch2: selinux.patch -Patch3: fapolicyd-startup-message.patch -Patch4: fapolicyd-cli-hang.patch # we are making the dnf-plugin completelly dummy because of # https://bugzilla.redhat.com/show_bug.cgi?id=1929163 # we require the rpm-plugin from now on and the dnf-plugin still needs to be part of # the fapolicyd package because it provides safe upgrade path -Patch5: fapolicyd-dnf-plugin.patch - -Patch6: fapolicyd-unlink1.patch -Patch7: fapolicyd-unlink2.patch -Patch8: fapolicyd-unlink3.patch -Patch9: fapolicyd-unlink-fifo1.patch -Patch10: fapolicyd-unlink-fifo2.patch - -Patch11: fapolicyd-fanotify-read-error.patch +Patch2: fapolicyd-dnf-plugin.patch +Patch3: fapolicyd-selinux.patch +Patch4: fapolicyd-do-manage-files.patch +Patch5: fapolicyd-documentation.patch +Patch6: fapolicyd-fix-escaping.patch +Patch7: fapolicyd-trust-file-append.patch %description Fapolicyd (File Access Policy Daemon) implements application whitelisting @@ -72,20 +66,12 @@ The %{name}-selinux package contains selinux policy for the %{name} daemon. %setup -q -D -T -a 1 %patch1 -p1 -b .magic -%patch2 -p1 -b .selinux -%patch3 -p1 -b .startup -%patch4 -p1 -b .cli-hang - -%patch5 -p1 -b .plugin - -%patch6 -p1 -b .unlink1 -%patch7 -p1 -b .unlink2 -%patch8 -p1 -b .unlink3 - -%patch9 -p1 -b .unlink_fifo1 -%patch10 -p1 -b .unlink_fifo2 - -%patch11 -p1 -b .fanotify_read +%patch2 -p1 -b .plugin +%patch3 -p1 -b .selinux +%patch4 -p1 -b .do-manage-files +%patch5 -p1 -b .documentation +%patch6 -p1 -b .fix-escaping +%patch7 -p1 -b .trust-file-append # generate rules for python sed -i "s/%python2_path%/`readlink -f %{__python2} | sed 's/\//\\\\\//g'`/g" init/%{name}.rules.* @@ -121,6 +107,7 @@ install -p -m 644 -D init/%{name}-tmpfiles.conf %{buildroot}/%{_tmpfilesdir}/%{n install -p -m 644 init/%{name}.rules.known-libs %{buildroot}/%{_sysconfdir}/%{name}/%{name}.rules mkdir -p %{buildroot}/%{_localstatedir}/lib/%{name} mkdir -p %{buildroot}/run/%{name} +mkdir -p %{buildroot}%{_sysconfdir}/%{name}/trust.d # selinux install -d %{buildroot}%{_datadir}/selinux/packages/%{selinuxtype} @@ -177,6 +164,7 @@ end %attr(755,root,%{name}) %dir %{_datadir}/%{name} %attr(644,root,%{name}) %{_datadir}/%{name}/%{name}.rules.* %attr(750,root,%{name}) %dir %{_sysconfdir}/%{name} +%attr(750,root,%{name}) %dir %{_sysconfdir}/%{name}/trust.d %config(noreplace) %attr(644,root,%{name}) %{_sysconfdir}/%{name}/%{name}.conf %config(noreplace) %attr(644,root,%{name}) %{_sysconfdir}/%{name}/%{name}.trust %config(noreplace) %attr(644,root,%{name}) %{_sysconfdir}/%{name}/%{name}.rules @@ -201,7 +189,7 @@ end # selinux %files selinux %{_datadir}/selinux/packages/%{selinuxtype}/%{name}.pp.bz2 -%ghost %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{name} +%ghost %verify(not md5 size mode mtime) %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{name} %{_datadir}/selinux/devel/include/%{moduletype}/ipp-%{name}.if %post selinux @@ -217,16 +205,26 @@ fi %selinux_relabel_post -s %{selinuxtype} %changelog -* Tue Mar 23 2021 Radovan Sroka - 1.0.2-6 -RHEL 8.4.0 ERRATUM +* Mon Dec 13 2021 Zoltan Fridrich - 1.0.4-2 +RHEL 8.6.0 ERRATUM +- rebase to 1.0.4 +- added rpm_sha256_only option +- added trust.d directory +- allow file names with whitespace in trust files +- use full paths in trust files +Resolves: rhbz#1939379 +- fix libc.so getting identified as application/x-executable +Resolves: rhbz#1989272 +- fix fapolicyd-dnf-plugin reporting as '' +Resolves: rhbz#1997414 +- fix selinux DSP module definition in spec file +Resolves: rhbz#2014445 + +* Thu Aug 19 2021 Radovan Sroka - 1.0.2-7 - fapolicyd abnormally exits by executing sosreport -Resolves: rhbz#1940289 - -* Thu Mar 18 2021 Radovan Sroka - 1.0.2-5 -RHEL 8.4.0 ERRATUM - fixed multiple problems with unlink() - fapolicyd breaks system upgrade, leaving system in dead state - complete fix -Resolves: rhbz#1896875 +Resolves: rhbz#1943251 * Tue Feb 16 2021 Radovan Sroka - 1.0.2-3 RHEL 8.4.0 ERRATUM