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