Import from AlmaLinux stable repository
This commit is contained in:
parent
550d85d191
commit
5f173ec678
@ -1,2 +0,0 @@
|
|||||||
3887d3f97a4f506ad6bf7dcef36b01cc7897a692 SOURCES/fapolicyd-1.1.3.tar.gz
|
|
||||||
bdbe20a4db2cd58073abf17a537e3a6766cdea21 SOURCES/fapolicyd-selinux-0.4.tar.gz
|
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,2 +1,2 @@
|
|||||||
SOURCES/fapolicyd-1.1.3.tar.gz
|
SOURCES/fapolicyd-1.3.2.tar.gz
|
||||||
SOURCES/fapolicyd-selinux-0.4.tar.gz
|
SOURCES/fapolicyd-selinux-0.6.tar.gz
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
diff -up ./init/fagenrules.fix ./init/fagenrules
|
|
||||||
--- ./init/fagenrules.fix 2022-04-01 16:12:50.512164904 +0200
|
|
||||||
+++ ./init/fagenrules 2022-04-01 16:21:07.924712100 +0200
|
|
||||||
@@ -117,7 +117,8 @@ fi
|
|
||||||
|
|
||||||
# We copy the file so that it gets the right selinux label
|
|
||||||
cp ${TmpRules} ${DestinationFile}
|
|
||||||
-chmod 0640 ${DestinationFile}
|
|
||||||
+chmod 0644 ${DestinationFile}
|
|
||||||
+chgrp fapolicyd ${DestinationFile}
|
|
||||||
|
|
||||||
# Restore context on MLS system.
|
|
||||||
# /tmp is SystemLow & fapolicyd.rules is SystemHigh
|
|
@ -1,110 +0,0 @@
|
|||||||
diff -up ./src/daemon/fapolicyd.c.already-started ./src/daemon/fapolicyd.c
|
|
||||||
--- ./src/daemon/fapolicyd.c.already-started 2023-01-12 17:40:45.366909652 +0100
|
|
||||||
+++ ./src/daemon/fapolicyd.c 2023-01-12 17:46:22.458139519 +0100
|
|
||||||
@@ -378,6 +378,58 @@ static void usage(void)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
+int already_running(void)
|
|
||||||
+{
|
|
||||||
+ int pidfd = open(pidfile, O_RDONLY);
|
|
||||||
+ if (pidfd >= 0) {
|
|
||||||
+ char pid_buf[16];
|
|
||||||
+
|
|
||||||
+ if (fd_fgets(pid_buf, sizeof(pid_buf), pidfd)) {
|
|
||||||
+ int pid;
|
|
||||||
+ char exe_buf[80], my_path[80];
|
|
||||||
+
|
|
||||||
+ // Get our path
|
|
||||||
+ if (get_program_from_pid(getpid(),
|
|
||||||
+ sizeof(exe_buf), my_path) == NULL)
|
|
||||||
+ goto err_out; // shouldn't happen, but be safe
|
|
||||||
+
|
|
||||||
+ // convert pidfile to integer
|
|
||||||
+ errno = 0;
|
|
||||||
+ pid = strtoul(pid_buf, NULL, 10);
|
|
||||||
+ if (errno)
|
|
||||||
+ goto err_out; // shouldn't happen, but be safe
|
|
||||||
+
|
|
||||||
+ // verify it really is fapolicyd
|
|
||||||
+ if (get_program_from_pid(pid,
|
|
||||||
+ sizeof(exe_buf), exe_buf) == NULL)
|
|
||||||
+ goto good; //if pid doesn't exist, we're OK
|
|
||||||
+
|
|
||||||
+ // If the path doesn't have fapolicyd in it, we're OK
|
|
||||||
+ if (strstr(exe_buf, "fapolicyd") == NULL)
|
|
||||||
+ goto good;
|
|
||||||
+
|
|
||||||
+ if (strcmp(exe_buf, my_path) == 0)
|
|
||||||
+ goto err_out; // if the same, we need to exit
|
|
||||||
+
|
|
||||||
+ // one last sanity check in case path is unexpected
|
|
||||||
+ // for example: /sbin/fapolicyd & /home/test/fapolicyd
|
|
||||||
+ if (pid != getpid())
|
|
||||||
+ goto err_out;
|
|
||||||
+good:
|
|
||||||
+ close(pidfd);
|
|
||||||
+ unlink(pidfile);
|
|
||||||
+ return 0;
|
|
||||||
+ } else
|
|
||||||
+ msg(LOG_ERR, "fapolicyd pid file found but unreadable");
|
|
||||||
+err_out: // At this point, we have a pid file, let's just assume it's alive
|
|
||||||
+ // because if 2 are running, it deadlocks the machine
|
|
||||||
+ close(pidfd);
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
+ return 0; // pid file doesn't exist, we're good to go
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
int main(int argc, const char *argv[])
|
|
||||||
{
|
|
||||||
struct pollfd pfd[2];
|
|
||||||
@@ -428,6 +480,11 @@ int main(int argc, const char *argv[])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (already_running()) {
|
|
||||||
+ msg(LOG_ERR, "fapolicyd is already running");
|
|
||||||
+ exit(1);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
// Set a couple signal handlers
|
|
||||||
sa.sa_flags = 0;
|
|
||||||
sigemptyset(&sa.sa_mask);
|
|
||||||
@@ -446,9 +503,6 @@ int main(int argc, const char *argv[])
|
|
||||||
setrlimit(RLIMIT_FSIZE, &limit);
|
|
||||||
setrlimit(RLIMIT_NOFILE, &limit);
|
|
||||||
|
|
||||||
- // Set strict umask
|
|
||||||
- (void) umask( 0117 );
|
|
||||||
-
|
|
||||||
// get more time slices because everything is waiting on us
|
|
||||||
rc = nice(-config.nice_val);
|
|
||||||
if (rc == -1)
|
|
||||||
@@ -473,17 +527,20 @@ int main(int argc, const char *argv[])
|
|
||||||
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);
|
|
||||||
|
|
||||||
// Write the pid file for the init system
|
|
||||||
write_pid_file();
|
|
||||||
|
|
||||||
+ // Set strict umask
|
|
||||||
+ (void) umask( 0117 );
|
|
||||||
+
|
|
||||||
+ if (preconstruct_fifo(&config)) {
|
|
||||||
+ msg(LOG_ERR, "Cannot contruct a pipe");
|
|
||||||
+ exit(1);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
// If we are not going to be root, then setup necessary capabilities
|
|
||||||
if (config.uid != 0) {
|
|
||||||
capng_clear(CAPNG_SELECT_BOTH);
|
|
@ -1,11 +0,0 @@
|
|||||||
diff -up ./src/cli/fapolicyd-cli.c.segfault ./src/cli/fapolicyd-cli.c
|
|
||||||
--- ./src/cli/fapolicyd-cli.c.segfault 2022-08-03 17:51:54.903081124 +0200
|
|
||||||
+++ ./src/cli/fapolicyd-cli.c 2022-08-03 17:55:18.256458750 +0200
|
|
||||||
@@ -77,6 +77,7 @@ static struct option long_opts[] =
|
|
||||||
{"ftype", 1, NULL, 't'},
|
|
||||||
{"list", 0, NULL, 'l'},
|
|
||||||
{"update", 0, NULL, 'u'},
|
|
||||||
+ {NULL, 0, NULL, 0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char *_pipe = "/run/fapolicyd/fapolicyd.fifo";
|
|
@ -1,12 +1,12 @@
|
|||||||
diff --color -ru a/dnf/fapolicyd-dnf-plugin.py b/dnf/fapolicyd-dnf-plugin.py
|
diff -up ./dnf/fapolicyd-dnf-plugin.py.fix ./dnf/fapolicyd-dnf-plugin.py
|
||||||
--- a/dnf/fapolicyd-dnf-plugin.py 2021-11-12 20:21:54.000000000 +0100
|
--- ./dnf/fapolicyd-dnf-plugin.py.fix 2023-06-20 13:21:21.098192421 +0200
|
||||||
+++ b/dnf/fapolicyd-dnf-plugin.py 2021-11-18 16:29:03.919237116 +0100
|
+++ ./dnf/fapolicyd-dnf-plugin.py 2023-06-20 13:21:46.287412300 +0200
|
||||||
@@ -8,29 +8,9 @@
|
@@ -8,29 +8,10 @@ import sys
|
||||||
class Fapolicyd(dnf.Plugin):
|
class Fapolicyd(dnf.Plugin):
|
||||||
|
|
||||||
name = "fapolicyd"
|
name = "fapolicyd"
|
||||||
- pipe = "/var/run/fapolicyd/fapolicyd.fifo"
|
- pipe = "/run/fapolicyd/fapolicyd.fifo"
|
||||||
- file = None
|
file = None
|
||||||
|
|
||||||
def __init__(self, base, cli):
|
def __init__(self, base, cli):
|
||||||
pass
|
pass
|
||||||
@ -29,7 +29,6 @@ diff --color -ru a/dnf/fapolicyd-dnf-plugin.py b/dnf/fapolicyd-dnf-plugin.py
|
|||||||
- sys.stderr.write("fapolicy-plugin does not have write permission: " + self.pipe + "\n")
|
- sys.stderr.write("fapolicy-plugin does not have write permission: " + self.pipe + "\n")
|
||||||
- return
|
- return
|
||||||
-
|
-
|
||||||
- self.file.write("1")
|
- self.file.write("1\n")
|
||||||
- self.file.close()
|
- self.file.close()
|
||||||
+ pass
|
+ pass
|
||||||
Only in b/dnf: fapolicyd-dnf-plugin.py.plugin
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,74 +0,0 @@
|
|||||||
diff -up ./src/library/event.c.event ./src/library/event.c
|
|
||||||
--- ./src/library/event.c.event 2022-06-21 16:55:47.000000000 +0200
|
|
||||||
+++ ./src/library/event.c 2022-12-22 13:12:58.226816235 +0100
|
|
||||||
@@ -132,7 +132,15 @@ int new_event(const struct fanotify_even
|
|
||||||
if ((s->info->state == STATE_COLLECTING) &&
|
|
||||||
(e->type & FAN_OPEN_PERM) && !rc) {
|
|
||||||
skip_path = 1;
|
|
||||||
+
|
|
||||||
s->info->state = STATE_REOPEN;
|
|
||||||
+
|
|
||||||
+ // special branch after ld_so exec
|
|
||||||
+ // next opens will go fall trough
|
|
||||||
+ if (s->info->path1 &&
|
|
||||||
+ (strcmp(s->info->path1, SYSTEM_LD_SO) == 0))
|
|
||||||
+ s->info->state = STATE_DEFAULT_REOPEN;
|
|
||||||
+
|
|
||||||
}
|
|
||||||
|
|
||||||
// If not same proc or we detect execution, evict
|
|
||||||
@@ -149,7 +157,6 @@ int new_event(const struct fanotify_even
|
|
||||||
skip_path = 1;
|
|
||||||
}
|
|
||||||
evict = 0;
|
|
||||||
- skip_path = 1;
|
|
||||||
subject_reset(s, EXE);
|
|
||||||
subject_reset(s, COMM);
|
|
||||||
subject_reset(s, EXE_TYPE);
|
|
||||||
@@ -165,6 +172,7 @@ int new_event(const struct fanotify_even
|
|
||||||
skip_path = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
+
|
|
||||||
// If we've seen the reopen and its an execute and process
|
|
||||||
// has an interpreter and we're the same process, don't evict
|
|
||||||
// and don't collect the path since reopen interp will. The
|
|
||||||
@@ -173,14 +181,25 @@ int new_event(const struct fanotify_even
|
|
||||||
if ((s->info->state == STATE_REOPEN) && !skip_path &&
|
|
||||||
(e->type & FAN_OPEN_EXEC_PERM) &&
|
|
||||||
(s->info->elf_info & HAS_INTERP) && !rc) {
|
|
||||||
+ s->info->state = STATE_DEFAULT_REOPEN;
|
|
||||||
evict = 0;
|
|
||||||
skip_path = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
+
|
|
||||||
+ // this is what differs between STATE_REOPEN and
|
|
||||||
+ // STATE_DEFAULT_REOPEN
|
|
||||||
+ // in STATE_REOPEN path is always skipped
|
|
||||||
+ if ((s->info->state == STATE_REOPEN) && !skip_path &&
|
|
||||||
+ (e->type & FAN_OPEN_PERM) && !rc) {
|
|
||||||
+ skip_path = 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if (evict) {
|
|
||||||
lru_evict(subj_cache, key);
|
|
||||||
q_node = check_lru_cache(subj_cache, key);
|
|
||||||
s = (s_array *)q_node->item;
|
|
||||||
+
|
|
||||||
} else if (s->cnt == 0)
|
|
||||||
msg(LOG_DEBUG, "cached subject has cnt of 0");
|
|
||||||
}
|
|
||||||
diff -up ./src/library/process.h.event ./src/library/process.h
|
|
||||||
--- ./src/library/process.h.event 2022-06-21 16:55:47.000000000 +0200
|
|
||||||
+++ ./src/library/process.h 2022-12-22 13:10:23.260996771 +0100
|
|
||||||
@@ -31,7 +31,8 @@
|
|
||||||
#include "gcc-attributes.h"
|
|
||||||
|
|
||||||
typedef enum { STATE_COLLECTING=0, // initial state - execute
|
|
||||||
- STATE_REOPEN, // anticipating open perm next
|
|
||||||
+ STATE_REOPEN, // anticipating open perm next, always skips the path
|
|
||||||
+ STATE_DEFAULT_REOPEN, // reopen after dyn. linker exec, never skips the path
|
|
||||||
STATE_STATIC_REOPEN, // static app aniticipating
|
|
||||||
STATE_PARTIAL, // second path collected
|
|
||||||
STATE_STATIC_PARTIAL, // second path collected
|
|
@ -1,215 +0,0 @@
|
|||||||
diff -up ./src/cli/fapolicyd-cli.c.upgrade-thread ./src/cli/fapolicyd-cli.c
|
|
||||||
--- ./src/cli/fapolicyd-cli.c.upgrade-thread 2022-08-03 18:00:02.374999369 +0200
|
|
||||||
+++ ./src/cli/fapolicyd-cli.c 2022-08-03 18:00:09.802830497 +0200
|
|
||||||
@@ -482,7 +482,7 @@ static int do_update(void)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- ssize_t ret = write(fd, "1", 2);
|
|
||||||
+ ssize_t ret = write(fd, "1\n", 3);
|
|
||||||
|
|
||||||
if (ret == -1) {
|
|
||||||
fprintf(stderr, "Write: %s -> %s\n", _pipe, strerror(errno));
|
|
||||||
diff -up ./src/library/database.c.upgrade-thread ./src/library/database.c
|
|
||||||
--- ./src/library/database.c.upgrade-thread 2022-06-21 16:55:47.000000000 +0200
|
|
||||||
+++ ./src/library/database.c 2022-08-03 17:58:04.034689808 +0200
|
|
||||||
@@ -34,6 +34,7 @@
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
+#include <ctype.h>
|
|
||||||
#include <gcrypt.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
@@ -43,6 +44,7 @@
|
|
||||||
#include "message.h"
|
|
||||||
#include "llist.h"
|
|
||||||
#include "file.h"
|
|
||||||
+#include "fd-fgets.h"
|
|
||||||
|
|
||||||
#include "fapolicyd-backend.h"
|
|
||||||
#include "backend-manager.h"
|
|
||||||
@@ -1181,6 +1183,7 @@ static void *update_thread_main(void *ar
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ fcntl(ffd[0].fd, F_SETFL, O_NONBLOCK);
|
|
||||||
ffd[0].events = POLLIN;
|
|
||||||
|
|
||||||
while (!stop) {
|
|
||||||
@@ -1200,97 +1203,102 @@ static void *update_thread_main(void *ar
|
|
||||||
} else {
|
|
||||||
msg(LOG_ERR, "Update poll error (%s)",
|
|
||||||
strerror_r(errno, err_buff, BUFFER_SIZE));
|
|
||||||
- goto err_out;
|
|
||||||
+ goto finalize;
|
|
||||||
}
|
|
||||||
} else if (rc == 0) {
|
|
||||||
#ifdef DEBUG
|
|
||||||
msg(LOG_DEBUG, "Update poll timeout expired");
|
|
||||||
#endif
|
|
||||||
- if (db_operation != DB_NO_OP)
|
|
||||||
- goto handle_db_ops;
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
if (ffd[0].revents & POLLIN) {
|
|
||||||
- ssize_t count = read(ffd[0].fd, buff,
|
|
||||||
- BUFFER_SIZE-1);
|
|
||||||
|
|
||||||
- if (count == -1) {
|
|
||||||
- msg(LOG_ERR,
|
|
||||||
- "Failed to read from a pipe %s (%s)",
|
|
||||||
- fifo_path,
|
|
||||||
- strerror_r(errno, err_buff,
|
|
||||||
- BUFFER_SIZE));
|
|
||||||
- goto err_out;
|
|
||||||
- }
|
|
||||||
+ do {
|
|
||||||
+ fd_fgets_rewind();
|
|
||||||
+ int res = fd_fgets(buff, sizeof(buff), ffd[0].fd);
|
|
||||||
|
|
||||||
- if (count == 0) {
|
|
||||||
-#ifdef DEBUG
|
|
||||||
- msg(LOG_DEBUG,
|
|
||||||
- "Buffer contains zero bytes!");
|
|
||||||
-#endif
|
|
||||||
- continue;
|
|
||||||
- } else // Manually terminate buff
|
|
||||||
- buff[count] = 0;
|
|
||||||
-#ifdef DEBUG
|
|
||||||
- msg(LOG_DEBUG, "Buffer contains: \"%s\"", buff);
|
|
||||||
-#endif
|
|
||||||
- for (int i = 0 ; i < count ; i++) {
|
|
||||||
- // assume file name
|
|
||||||
- // operation = 0
|
|
||||||
- if (buff[i] == '/') {
|
|
||||||
- db_operation = ONE_FILE;
|
|
||||||
+ // nothing to read
|
|
||||||
+ if (res == -1)
|
|
||||||
break;
|
|
||||||
- }
|
|
||||||
+ else if (res > 0) {
|
|
||||||
+ char* end = strchr(buff, '\n');
|
|
||||||
|
|
||||||
- if (buff[i] == '1') {
|
|
||||||
- db_operation = RELOAD_DB;
|
|
||||||
- break;
|
|
||||||
+ if (end == NULL) {
|
|
||||||
+ msg(LOG_ERR, "Too long line?");
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ int count = end - buff;
|
|
||||||
+
|
|
||||||
+ *end = '\0';
|
|
||||||
+
|
|
||||||
+ for (int i = 0 ; i < count ; i++) {
|
|
||||||
+ // assume file name
|
|
||||||
+ // operation = 0
|
|
||||||
+ if (buff[i] == '/') {
|
|
||||||
+ db_operation = ONE_FILE;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (buff[i] == '1') {
|
|
||||||
+ db_operation = RELOAD_DB;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (buff[i] == '2') {
|
|
||||||
+ db_operation = FLUSH_CACHE;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (isspace(buff[i]))
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
+ msg(LOG_ERR, "Cannot handle data \"%s\" from pipe", buff);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ *end = '\n';
|
|
||||||
+
|
|
||||||
+ // got "1" -> reload db
|
|
||||||
+ if (db_operation == RELOAD_DB) {
|
|
||||||
+ db_operation = DB_NO_OP;
|
|
||||||
+ msg(LOG_INFO,
|
|
||||||
+ "It looks like there was an update of the system... Syncing DB.");
|
|
||||||
+
|
|
||||||
+ backend_close();
|
|
||||||
+ backend_init(config);
|
|
||||||
+ backend_load(config);
|
|
||||||
+
|
|
||||||
+ if ((rc = update_database(config))) {
|
|
||||||
+ msg(LOG_ERR,
|
|
||||||
+ "Cannot update trust database!");
|
|
||||||
+ close(ffd[0].fd);
|
|
||||||
+ backend_close();
|
|
||||||
+ unlink_fifo();
|
|
||||||
+ exit(rc);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ msg(LOG_INFO, "Updated");
|
|
||||||
+
|
|
||||||
+ // Conserve memory
|
|
||||||
+ backend_close();
|
|
||||||
+ // got "2" -> flush cache
|
|
||||||
+ } else if (db_operation == FLUSH_CACHE) {
|
|
||||||
+ db_operation = DB_NO_OP;
|
|
||||||
+ needs_flush = true;
|
|
||||||
+ } else if (db_operation == ONE_FILE) {
|
|
||||||
+ db_operation = DB_NO_OP;
|
|
||||||
+ if (handle_record(buff))
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (buff[i] == '2') {
|
|
||||||
- db_operation = FLUSH_CACHE;
|
|
||||||
- break;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
-handle_db_ops:
|
|
||||||
- // got "1" -> reload db
|
|
||||||
- if (db_operation == RELOAD_DB) {
|
|
||||||
- db_operation = DB_NO_OP;
|
|
||||||
- msg(LOG_INFO,
|
|
||||||
- "It looks like there was an update of the system... Syncing DB.");
|
|
||||||
-
|
|
||||||
- backend_close();
|
|
||||||
- backend_init(config);
|
|
||||||
- backend_load(config);
|
|
||||||
-
|
|
||||||
- if ((rc = update_database(config))) {
|
|
||||||
- msg(LOG_ERR,
|
|
||||||
- "Cannot update trust database!");
|
|
||||||
- close(ffd[0].fd);
|
|
||||||
- backend_close();
|
|
||||||
- unlink_fifo();
|
|
||||||
- exit(rc);
|
|
||||||
- } else
|
|
||||||
- msg(LOG_INFO, "Updated");
|
|
||||||
-
|
|
||||||
- // Conserve memory
|
|
||||||
- backend_close();
|
|
||||||
- // got "2" -> flush cache
|
|
||||||
- } else if (db_operation == FLUSH_CACHE) {
|
|
||||||
- db_operation = DB_NO_OP;
|
|
||||||
- needs_flush = true;
|
|
||||||
- } else if (db_operation == ONE_FILE) {
|
|
||||||
- db_operation = DB_NO_OP;
|
|
||||||
- if (handle_record(buff))
|
|
||||||
- continue;
|
|
||||||
- }
|
|
||||||
+ } while(!fd_fgets_eof());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-
|
|
||||||
}
|
|
||||||
|
|
||||||
-err_out:
|
|
||||||
+finalize:
|
|
||||||
close(ffd[0].fd);
|
|
||||||
unlink_fifo();
|
|
||||||
|
|
78
SOURCES/fapolicyd-leaks.patch
Normal file
78
SOURCES/fapolicyd-leaks.patch
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
From 248219377a034d7da9238e7424c97558395700e3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Radovan Sroka <rsroka@redhat.com>
|
||||||
|
Date: Tue, 18 Jul 2023 17:05:11 +0200
|
||||||
|
Subject: [PATCH] Fix multiple leaks
|
||||||
|
|
||||||
|
Signed-off-by: Radovan Sroka <rsroka@redhat.com>
|
||||||
|
---
|
||||||
|
src/library/filter.c | 3 +++
|
||||||
|
src/library/policy.c | 13 +++++++++++--
|
||||||
|
src/library/rules.c | 3 ---
|
||||||
|
3 files changed, 14 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/library/filter.c b/src/library/filter.c
|
||||||
|
index d5d8cca..eb378ca 100644
|
||||||
|
--- a/src/library/filter.c
|
||||||
|
+++ b/src/library/filter.c
|
||||||
|
@@ -472,9 +472,12 @@ int filter_load_file(void)
|
||||||
|
msg(LOG_ERR, "filter_load_file: paring error line: %ld, \"%s\"", line_number, line);
|
||||||
|
filter_destroy_obj(filter);
|
||||||
|
free(line);
|
||||||
|
+ line = NULL;
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
+ }
|
||||||
|
|
||||||
|
+ if (line) {
|
||||||
|
free(line);
|
||||||
|
line = NULL;
|
||||||
|
}
|
||||||
|
diff --git a/src/library/policy.c b/src/library/policy.c
|
||||||
|
index 7fe1210..31ff6e2 100644
|
||||||
|
--- a/src/library/policy.c
|
||||||
|
+++ b/src/library/policy.c
|
||||||
|
@@ -23,6 +23,7 @@
|
||||||
|
* Radovan Sroka <rsroka@redhat.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
+#include "attr-sets.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
@@ -273,12 +274,20 @@ int load_rules(const conf_t *_config)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
FILE * f = open_file();
|
||||||
|
- if (f == NULL)
|
||||||
|
+ if (f == NULL) {
|
||||||
|
+ destroy_attr_sets();
|
||||||
|
return 1;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
int res = _load_rules(_config, f);
|
||||||
|
fclose(f);
|
||||||
|
- return res;
|
||||||
|
+
|
||||||
|
+ if (res) {
|
||||||
|
+ destroy_attr_sets();
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy_rules(void)
|
||||||
|
diff --git a/src/library/rules.c b/src/library/rules.c
|
||||||
|
index 5ffa40e..4a8b098 100644
|
||||||
|
--- a/src/library/rules.c
|
||||||
|
+++ b/src/library/rules.c
|
||||||
|
@@ -65,9 +65,6 @@ int rules_create(llist *l)
|
||||||
|
l->cur = NULL;
|
||||||
|
l->cnt = 0;
|
||||||
|
|
||||||
|
- if (init_attr_sets())
|
||||||
|
- return 1;
|
||||||
|
-
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
93
SOURCES/fapolicyd-librpm-workaround.patch
Normal file
93
SOURCES/fapolicyd-librpm-workaround.patch
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
diff -up ./src/daemon/fapolicyd.c.librpm-workaround ./src/daemon/fapolicyd.c
|
||||||
|
--- ./src/daemon/fapolicyd.c.librpm-workaround 2023-07-10 11:19:19.507044648 +0200
|
||||||
|
+++ ./src/daemon/fapolicyd.c 2023-07-10 11:19:19.509044621 +0200
|
||||||
|
@@ -572,7 +572,7 @@ int main(int argc, const char *argv[])
|
||||||
|
capng_clear(CAPNG_SELECT_BOTH);
|
||||||
|
capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
|
||||||
|
CAP_DAC_OVERRIDE, CAP_SYS_ADMIN, CAP_SYS_PTRACE,
|
||||||
|
- CAP_SYS_NICE, CAP_SYS_RESOURCE, CAP_AUDIT_WRITE, -1);
|
||||||
|
+ CAP_SYS_NICE, CAP_SYS_RESOURCE, CAP_AUDIT_WRITE, CAP_CHOWN, -1);
|
||||||
|
if (capng_change_id(config.uid, config.gid,
|
||||||
|
CAPNG_DROP_SUPP_GRP)) {
|
||||||
|
msg(LOG_ERR, "Cannot change to uid %d", config.uid);
|
||||||
|
diff -up ./src/library/rpm-backend.c.librpm-workaround ./src/library/rpm-backend.c
|
||||||
|
--- ./src/library/rpm-backend.c.librpm-workaround 2023-06-15 16:45:14.000000000 +0200
|
||||||
|
+++ ./src/library/rpm-backend.c 2023-07-10 11:22:07.066794595 +0200
|
||||||
|
@@ -32,7 +32,12 @@
|
||||||
|
#include <rpm/rpmdb.h>
|
||||||
|
#include <rpm/rpmpgp.h>
|
||||||
|
#include <fnmatch.h>
|
||||||
|
+#include <glob.h>
|
||||||
|
+#include <pwd.h>
|
||||||
|
+#include <grp.h>
|
||||||
|
+#include <fcntl.h>
|
||||||
|
|
||||||
|
+#include <unistd.h>
|
||||||
|
#include <uthash.h>
|
||||||
|
|
||||||
|
#include "message.h"
|
||||||
|
@@ -59,6 +64,50 @@ backend rpm_backend =
|
||||||
|
static rpmts ts = NULL;
|
||||||
|
static rpmdbMatchIterator mi = NULL;
|
||||||
|
|
||||||
|
+static void fix_files(void)
|
||||||
|
+{
|
||||||
|
+ glob_t glob_result;
|
||||||
|
+ const char *pattern = "/var/lib/rpm/__*";
|
||||||
|
+
|
||||||
|
+ struct passwd * usr = getpwnam("fapolicyd");
|
||||||
|
+ if (usr == NULL) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ struct group * grp = getgrnam("fapolicyd");
|
||||||
|
+ if (grp == NULL) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ int return_value = glob(pattern, 0, NULL, &glob_result);
|
||||||
|
+ if (return_value != 0) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (int i = 0; i < glob_result.gl_pathc; ++i) {
|
||||||
|
+
|
||||||
|
+ int fd = open(glob_result.gl_pathv[i], O_NOFOLLOW);
|
||||||
|
+
|
||||||
|
+ if (fd == -1)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ struct stat file_stat;
|
||||||
|
+ if (fstat(fd, &file_stat) != 0) {
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (file_stat.st_uid == usr->pw_uid &&
|
||||||
|
+ file_stat.st_gid == grp->gr_gid) {
|
||||||
|
+
|
||||||
|
+ fchown(fd, 0, 0);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ close(fd);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ globfree(&glob_result);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int init_rpm(void)
|
||||||
|
{
|
||||||
|
return rpmReadConfigFiles ((const char *)NULL, (const char *)NULL);
|
||||||
|
@@ -201,8 +250,13 @@ static int rpm_load_list(const conf_t *c
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ int fixed = 0;
|
||||||
|
// Loop across the rpm database
|
||||||
|
while (get_next_package_rpm()) {
|
||||||
|
+ if (!fixed) {
|
||||||
|
+ fixed = 1;
|
||||||
|
+ fix_files();
|
||||||
|
+ }
|
||||||
|
// Loop across the packages
|
||||||
|
while (get_next_file_rpm()) {
|
||||||
|
// We do not want directories or symlinks in the
|
@ -1,195 +0,0 @@
|
|||||||
diff -up ./BUILD.md.openssl ./BUILD.md
|
|
||||||
--- ./BUILD.md.openssl 2022-06-21 16:55:47.000000000 +0200
|
|
||||||
+++ ./BUILD.md 2022-08-02 14:10:48.092466542 +0200
|
|
||||||
@@ -16,7 +16,8 @@ BUILD-TIME DEPENDENCIES (fedora and RHEL
|
|
||||||
* libudev-devel
|
|
||||||
* kernel-headers
|
|
||||||
* systemd-devel
|
|
||||||
-* libgcrypt-devel
|
|
||||||
+* libgcrypt-devel ( <= fapolicyd-1.1.3)
|
|
||||||
+* openssl ( >= fapolicyd-1.1.4)
|
|
||||||
* rpm-devel (optional)
|
|
||||||
* file
|
|
||||||
* file-devel
|
|
||||||
diff -U0 ./ChangeLog.openssl ./ChangeLog
|
|
||||||
diff -up ./configure.ac.openssl ./configure.ac
|
|
||||||
--- ./configure.ac.openssl 2022-06-21 16:55:47.000000000 +0200
|
|
||||||
+++ ./configure.ac 2022-08-02 14:10:48.092466542 +0200
|
|
||||||
@@ -87,7 +87,7 @@ AC_CHECK_HEADER(uthash.h, , [AC_MSG_ERRO
|
|
||||||
echo .
|
|
||||||
echo Checking for required libraries
|
|
||||||
AC_CHECK_LIB(udev, udev_device_get_devnode, , [AC_MSG_ERROR([libudev not found])], -ludev)
|
|
||||||
-AC_CHECK_LIB(gcrypt, gcry_md_open, , [AC_MSG_ERROR([libgcrypt not found])], -lgcrypt)
|
|
||||||
+AC_CHECK_LIB(crypto, SHA256, , [AC_MSG_ERROR([openssl libcrypto not found])], -lcrypto)
|
|
||||||
AC_CHECK_LIB(magic, magic_descriptor, , [AC_MSG_ERROR([libmagic not found])], -lmagic)
|
|
||||||
AC_CHECK_LIB(cap-ng, capng_change_id, , [AC_MSG_ERROR([libcap-ng not found])], -lcap-ng)
|
|
||||||
AC_CHECK_LIB(seccomp, seccomp_rule_add, , [AC_MSG_ERROR([libseccomp not found])], -lseccomp)
|
|
||||||
diff -up ./fapolicyd.spec.openssl ./fapolicyd.spec
|
|
||||||
--- ./fapolicyd.spec.openssl 2022-06-21 16:55:47.000000000 +0200
|
|
||||||
+++ ./fapolicyd.spec 2022-08-02 14:10:48.092466542 +0200
|
|
||||||
@@ -8,7 +8,7 @@ Source0: https://people.redhat.com/sgrub
|
|
||||||
BuildRequires: gcc
|
|
||||||
BuildRequires: kernel-headers
|
|
||||||
BuildRequires: autoconf automake make gcc libtool
|
|
||||||
-BuildRequires: systemd-devel libgcrypt-devel rpm-devel file-devel file
|
|
||||||
+BuildRequires: systemd-devel openssl-devel rpm-devel file-devel file
|
|
||||||
BuildRequires: libcap-ng-devel libseccomp-devel lmdb-devel
|
|
||||||
BuildRequires: python3-devel
|
|
||||||
BuildRequires: uthash-devel
|
|
||||||
diff -up ./src/cli/fapolicyd-cli.c.openssl ./src/cli/fapolicyd-cli.c
|
|
||||||
--- ./src/cli/fapolicyd-cli.c.openssl 2022-06-21 16:55:47.000000000 +0200
|
|
||||||
+++ ./src/cli/fapolicyd-cli.c 2022-08-02 14:10:48.093466520 +0200
|
|
||||||
@@ -39,7 +39,6 @@
|
|
||||||
#include <stdatomic.h>
|
|
||||||
#include <lmdb.h>
|
|
||||||
#include <limits.h>
|
|
||||||
-#include <gcrypt.h>
|
|
||||||
#include "policy.h"
|
|
||||||
#include "database.h"
|
|
||||||
#include "file-cli.h"
|
|
||||||
@@ -670,11 +669,6 @@ static int check_trustdb(void)
|
|
||||||
if (rc)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
- // Initialize libgcrypt
|
|
||||||
- gcry_check_version(NULL);
|
|
||||||
- gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
|
|
||||||
- gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
|
|
||||||
-
|
|
||||||
do {
|
|
||||||
unsigned int tsource; // unused
|
|
||||||
off_t size;
|
|
||||||
diff -up ./src/library/database.c.openssl ./src/library/database.c
|
|
||||||
--- ./src/library/database.c.openssl 2022-08-02 14:10:48.090466587 +0200
|
|
||||||
+++ ./src/library/database.c 2022-08-02 14:13:11.995236110 +0200
|
|
||||||
@@ -35,7 +35,7 @@
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
-#include <gcrypt.h>
|
|
||||||
+#include <openssl/sha.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
@@ -244,26 +244,18 @@ static void abort_transaction(MDB_txn *t
|
|
||||||
static char *path_to_hash(const char *path, const size_t path_len) MALLOCLIKE;
|
|
||||||
static char *path_to_hash(const char *path, const size_t path_len)
|
|
||||||
{
|
|
||||||
- gcry_md_hd_t h;
|
|
||||||
- unsigned int len;
|
|
||||||
- unsigned char *hptr;
|
|
||||||
+ unsigned char hptr[80];
|
|
||||||
char *digest;
|
|
||||||
|
|
||||||
- if (gcry_md_open(&h, GCRY_MD_SHA512, GCRY_MD_FLAG_SECURE))
|
|
||||||
+ if (path_len == 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
- gcry_md_write(h, path, path_len);
|
|
||||||
- hptr = gcry_md_read(h, GCRY_MD_SHA512);
|
|
||||||
-
|
|
||||||
- len = gcry_md_get_algo_dlen(GCRY_MD_SHA512) * sizeof(char);
|
|
||||||
- digest = malloc((2 * len) + 1);
|
|
||||||
- if (digest == NULL) {
|
|
||||||
- gcry_md_close(h);
|
|
||||||
+ SHA512((unsigned char *)path, path_len, (unsigned char *)&hptr);
|
|
||||||
+ digest = malloc((SHA512_LEN * 2) + 1);
|
|
||||||
+ if (digest == NULL)
|
|
||||||
return digest;
|
|
||||||
- }
|
|
||||||
|
|
||||||
- bytes2hex(digest, hptr, len);
|
|
||||||
- gcry_md_close(h);
|
|
||||||
+ bytes2hex(digest, hptr, SHA512_LEN);
|
|
||||||
|
|
||||||
return digest;
|
|
||||||
}
|
|
||||||
@@ -296,7 +288,7 @@ static int write_db(const char *idx, con
|
|
||||||
if (hash == NULL)
|
|
||||||
return 5;
|
|
||||||
key.mv_data = (void *)hash;
|
|
||||||
- key.mv_size = gcry_md_get_algo_dlen(GCRY_MD_SHA512) * 2 + 1;
|
|
||||||
+ key.mv_size = (SHA512_LEN * 2) + 1;
|
|
||||||
} else {
|
|
||||||
key.mv_data = (void *)idx;
|
|
||||||
key.mv_size = len;
|
|
||||||
@@ -416,7 +408,7 @@ static char *lt_read_db(const char *inde
|
|
||||||
if (hash == NULL)
|
|
||||||
return NULL;
|
|
||||||
key.mv_data = (void *)hash;
|
|
||||||
- key.mv_size = gcry_md_get_algo_dlen(GCRY_MD_SHA512) * 2 + 1;
|
|
||||||
+ key.mv_size = (SHA512_LEN * 2) + 1;
|
|
||||||
} else {
|
|
||||||
key.mv_data = (void *)index;
|
|
||||||
key.mv_size = len;
|
|
||||||
diff -up ./src/library/file.c.openssl ./src/library/file.c
|
|
||||||
--- ./src/library/file.c.openssl 2022-06-21 16:55:47.000000000 +0200
|
|
||||||
+++ ./src/library/file.c 2022-08-02 14:10:48.094466497 +0200
|
|
||||||
@@ -31,7 +31,7 @@
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
-#include <gcrypt.h>
|
|
||||||
+#include <openssl/sha.h>
|
|
||||||
#include <magic.h>
|
|
||||||
#include <libudev.h>
|
|
||||||
#include <elf.h>
|
|
||||||
@@ -51,7 +51,6 @@ static struct udev *udev;
|
|
||||||
magic_t magic_cookie;
|
|
||||||
struct cache { dev_t device; const char *devname; };
|
|
||||||
static struct cache c = { 0, NULL };
|
|
||||||
-static size_t hash_size = 32; // init so cli doesn't need to call file_init
|
|
||||||
|
|
||||||
// readelf -l path-to-app | grep 'Requesting' | cut -d':' -f2 | tr -d ' ]';
|
|
||||||
static const char *interpreters[] = {
|
|
||||||
@@ -96,12 +95,6 @@ void file_init(void)
|
|
||||||
msg(LOG_ERR, "Unable to load magic database");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
-
|
|
||||||
- // Initialize libgcrypt
|
|
||||||
- gcry_check_version(NULL);
|
|
||||||
- gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
|
|
||||||
- gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
|
|
||||||
- hash_size = gcry_md_get_algo_dlen(GCRY_MD_SHA256) * sizeof(char);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -445,12 +438,12 @@ char *get_hash_from_fd2(int fd, size_t s
|
|
||||||
if (mapped != MAP_FAILED) {
|
|
||||||
unsigned char hptr[40];
|
|
||||||
|
|
||||||
- gcry_md_hash_buffer(GCRY_MD_SHA256, &hptr, mapped, size);
|
|
||||||
+ SHA256(mapped, size, (unsigned char *)&hptr);
|
|
||||||
munmap(mapped, size);
|
|
||||||
- digest = malloc(65);
|
|
||||||
+ digest = malloc((SHA256_LEN * 2) + 1);
|
|
||||||
|
|
||||||
// Convert to ASCII string
|
|
||||||
- bytes2hex(digest, hptr, hash_size);
|
|
||||||
+ bytes2hex(digest, hptr, SHA256_LEN);
|
|
||||||
}
|
|
||||||
return digest;
|
|
||||||
}
|
|
||||||
@@ -476,7 +469,7 @@ int get_ima_hash(int fd, char *sha)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Looks like it what we want...
|
|
||||||
- bytes2hex(sha, &tmp[2], 32);
|
|
||||||
+ bytes2hex(sha, &tmp[2], SHA256_LEN);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff -up ./src/library/file.h.openssl ./src/library/file.h
|
|
||||||
--- ./src/library/file.h.openssl 2022-06-21 16:55:47.000000000 +0200
|
|
||||||
+++ ./src/library/file.h 2022-08-02 14:10:48.094466497 +0200
|
|
||||||
@@ -40,6 +40,9 @@ struct file_info
|
|
||||||
struct timespec time;
|
|
||||||
};
|
|
||||||
|
|
||||||
+#define SHA256_LEN 32
|
|
||||||
+#define SHA512_LEN 64
|
|
||||||
+
|
|
||||||
void file_init(void);
|
|
||||||
void file_close(void);
|
|
||||||
struct file_info *stat_file_entry(int fd) MALLOCLIKE;
|
|
@ -1,30 +0,0 @@
|
|||||||
From b4618d133f473b9bbc36f2a5e94b8b0f257ba3e0 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Radovan Sroka <rsroka@redhat.com>
|
|
||||||
Date: Fri, 5 Aug 2022 14:49:30 +0200
|
|
||||||
Subject: [PATCH] Add mention that using of names requires name resolution
|
|
||||||
|
|
||||||
- using of user and group names as uid and gid attributes
|
|
||||||
requires correct name resolution
|
|
||||||
|
|
||||||
Signed-off-by: Radovan Sroka <rsroka@redhat.com>
|
|
||||||
---
|
|
||||||
README.md | 6 ++++++
|
|
||||||
1 file changed, 6 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/README.md b/README.md
|
|
||||||
index d932e00..abc5eee 100644
|
|
||||||
--- a/README.md
|
|
||||||
+++ b/README.md
|
|
||||||
@@ -131,6 +131,12 @@ You can similarly do this for trusted users that have to execute things in
|
|
||||||
the home dir. You can create a trusted_user group, add them the group,
|
|
||||||
and then write a rule allowing them to execute from their home dir.
|
|
||||||
|
|
||||||
+When you want to use user or group name (as a string). You have to guarantee
|
|
||||||
+that these names were correctly resolved. In case of systemd, you need to add
|
|
||||||
+a new after target 'After=nss-user-lookup.target'.
|
|
||||||
+To achieve that you can use `systemctl edit --full fapolicyd`,
|
|
||||||
+uncomment the respective line and save the change.
|
|
||||||
+
|
|
||||||
```
|
|
||||||
allow perm=any gid=trusted_user : ftype=%languages dir=/home
|
|
||||||
deny_audit perm=any all : ftype=%languages dir=/home
|
|
23
SOURCES/fapolicyd-selinux-links.patch
Normal file
23
SOURCES/fapolicyd-selinux-links.patch
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
From 05780f9accae504440ffed0548bd3e4144cfb70e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Radovan Sroka <rsroka@redhat.com>
|
||||||
|
Date: Wed, 19 Jul 2023 16:00:13 +0200
|
||||||
|
Subject: [PATCH] Allow links
|
||||||
|
|
||||||
|
Signed-off-by: Radovan Sroka <rsroka@redhat.com>
|
||||||
|
---
|
||||||
|
fapolicyd.te | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/fapolicyd-selinux-0.6/fapolicyd.te b/fapolicyd-selinux-0.6/fapolicyd.te
|
||||||
|
index daf31bd..5d6f9aa 100644
|
||||||
|
--- a/fapolicyd-selinux-0.6/fapolicyd.te
|
||||||
|
+++ b/fapolicyd-selinux-0.6/fapolicyd.te
|
||||||
|
@@ -53,6 +53,8 @@ ifdef(`fs_watch_all_fs',`
|
||||||
|
files_watch_sb_all_mountpoints(fapolicyd_t)
|
||||||
|
')
|
||||||
|
|
||||||
|
+allow fapolicyd_t file_type : lnk_file { getattr read };
|
||||||
|
+
|
||||||
|
manage_files_pattern(fapolicyd_t, fapolicyd_log_t, fapolicyd_log_t)
|
||||||
|
logging_log_filetrans(fapolicyd_t, fapolicyd_log_t, file)
|
||||||
|
|
@ -1,31 +0,0 @@
|
|||||||
diff -up ./fapolicyd-selinux-0.4/fapolicyd.te.selinux ./fapolicyd-selinux-0.4/fapolicyd.te
|
|
||||||
--- ./fapolicyd-selinux-0.4/fapolicyd.te.selinux 2021-03-23 10:21:31.000000000 +0100
|
|
||||||
+++ ./fapolicyd-selinux-0.4/fapolicyd.te 2022-06-29 12:06:57.958124735 +0200
|
|
||||||
@@ -61,25 +61,15 @@ corecmd_exec_bin(fapolicyd_t)
|
|
||||||
|
|
||||||
domain_read_all_domains_state(fapolicyd_t)
|
|
||||||
|
|
||||||
-files_mmap_usr_files(fapolicyd_t)
|
|
||||||
+files_mmap_all_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)
|
|
||||||
')
|
|
@ -1,141 +0,0 @@
|
|||||||
diff -up ./src/daemon/fapolicyd.c.sighup ./src/daemon/fapolicyd.c
|
|
||||||
--- ./src/daemon/fapolicyd.c.sighup 2022-06-21 16:55:47.000000000 +0200
|
|
||||||
+++ ./src/daemon/fapolicyd.c 2022-08-04 11:07:10.245069443 +0200
|
|
||||||
@@ -527,6 +527,7 @@ int main(int argc, const char *argv[])
|
|
||||||
while (!stop) {
|
|
||||||
if (hup) {
|
|
||||||
hup = 0;
|
|
||||||
+ msg(LOG_INFO, "Got SIGHUP");
|
|
||||||
reconfigure();
|
|
||||||
}
|
|
||||||
rc = poll(pfd, 2, -1);
|
|
||||||
diff -up ./src/library/database.c.sighup ./src/library/database.c
|
|
||||||
--- ./src/library/database.c.sighup 2022-08-04 11:07:10.237069609 +0200
|
|
||||||
+++ ./src/library/database.c 2022-08-04 11:08:44.852057119 +0200
|
|
||||||
@@ -68,7 +68,7 @@ static int lib_symlink=0, lib64_symlink=
|
|
||||||
static struct pollfd ffd[1] = { {0, 0, 0} };
|
|
||||||
static const char *fifo_path = "/run/fapolicyd/fapolicyd.fifo";
|
|
||||||
static integrity_t integrity;
|
|
||||||
-static atomic_int db_operation;
|
|
||||||
+static atomic_int reload_db = 0;
|
|
||||||
|
|
||||||
static pthread_t update_thread;
|
|
||||||
static pthread_mutex_t update_lock;
|
|
||||||
@@ -1147,7 +1147,31 @@ static int handle_record(const char * bu
|
|
||||||
|
|
||||||
void update_trust_database(void)
|
|
||||||
{
|
|
||||||
- db_operation = RELOAD_DB;
|
|
||||||
+ reload_db = 1;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void do_reload_db(conf_t* config)
|
|
||||||
+{
|
|
||||||
+ msg(LOG_INFO,"It looks like there was an update of the system... Syncing DB.");
|
|
||||||
+
|
|
||||||
+ int rc;
|
|
||||||
+ backend_close();
|
|
||||||
+ backend_init(config);
|
|
||||||
+ backend_load(config);
|
|
||||||
+
|
|
||||||
+ if ((rc = update_database(config))) {
|
|
||||||
+ msg(LOG_ERR,
|
|
||||||
+ "Cannot update trust database!");
|
|
||||||
+ close(ffd[0].fd);
|
|
||||||
+ backend_close();
|
|
||||||
+ unlink_fifo();
|
|
||||||
+ exit(rc);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ msg(LOG_INFO, "Updated");
|
|
||||||
+
|
|
||||||
+ // Conserve memory
|
|
||||||
+ backend_close();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *update_thread_main(void *arg)
|
|
||||||
@@ -1158,6 +1182,8 @@ static void *update_thread_main(void *ar
|
|
||||||
char err_buff[BUFFER_SIZE];
|
|
||||||
conf_t *config = (conf_t *)arg;
|
|
||||||
|
|
||||||
+ int do_operation = DB_NO_OP;;
|
|
||||||
+
|
|
||||||
#ifdef DEBUG
|
|
||||||
msg(LOG_DEBUG, "Update thread main started");
|
|
||||||
#endif
|
|
||||||
@@ -1182,6 +1208,12 @@ static void *update_thread_main(void *ar
|
|
||||||
|
|
||||||
rc = poll(ffd, 1, 1000);
|
|
||||||
|
|
||||||
+ // got SIGHUP
|
|
||||||
+ if (reload_db) {
|
|
||||||
+ reload_db = 0;
|
|
||||||
+ do_reload_db(config);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
#ifdef DEBUG
|
|
||||||
msg(LOG_DEBUG, "Update poll interrupted");
|
|
||||||
#endif
|
|
||||||
@@ -1228,17 +1260,17 @@ static void *update_thread_main(void *ar
|
|
||||||
// assume file name
|
|
||||||
// operation = 0
|
|
||||||
if (buff[i] == '/') {
|
|
||||||
- db_operation = ONE_FILE;
|
|
||||||
+ do_operation = ONE_FILE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buff[i] == '1') {
|
|
||||||
- db_operation = RELOAD_DB;
|
|
||||||
+ do_operation = RELOAD_DB;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buff[i] == '2') {
|
|
||||||
- db_operation = FLUSH_CACHE;
|
|
||||||
+ do_operation = FLUSH_CACHE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1252,34 +1284,16 @@ static void *update_thread_main(void *ar
|
|
||||||
*end = '\n';
|
|
||||||
|
|
||||||
// got "1" -> reload db
|
|
||||||
- if (db_operation == RELOAD_DB) {
|
|
||||||
- db_operation = DB_NO_OP;
|
|
||||||
- msg(LOG_INFO,
|
|
||||||
- "It looks like there was an update of the system... Syncing DB.");
|
|
||||||
-
|
|
||||||
- backend_close();
|
|
||||||
- backend_init(config);
|
|
||||||
- backend_load(config);
|
|
||||||
-
|
|
||||||
- if ((rc = update_database(config))) {
|
|
||||||
- msg(LOG_ERR,
|
|
||||||
- "Cannot update trust database!");
|
|
||||||
- close(ffd[0].fd);
|
|
||||||
- backend_close();
|
|
||||||
- unlink_fifo();
|
|
||||||
- exit(rc);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- msg(LOG_INFO, "Updated");
|
|
||||||
+ if (do_operation == RELOAD_DB) {
|
|
||||||
+ do_operation = DB_NO_OP;
|
|
||||||
+ do_reload_db(config);
|
|
||||||
|
|
||||||
- // Conserve memory
|
|
||||||
- backend_close();
|
|
||||||
// got "2" -> flush cache
|
|
||||||
- } else if (db_operation == FLUSH_CACHE) {
|
|
||||||
- db_operation = DB_NO_OP;
|
|
||||||
+ } else if (do_operation == FLUSH_CACHE) {
|
|
||||||
+ do_operation = DB_NO_OP;
|
|
||||||
needs_flush = true;
|
|
||||||
- } else if (db_operation == ONE_FILE) {
|
|
||||||
- db_operation = DB_NO_OP;
|
|
||||||
+ } else if (do_operation == ONE_FILE) {
|
|
||||||
+ do_operation = DB_NO_OP;
|
|
||||||
if (handle_record(buff))
|
|
||||||
continue;
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
From fb4c274f4857f2d652014b0189abafb1df4b001a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Steve Grubb <sgrubb@redhat.com>
|
|
||||||
Date: Tue, 19 Jul 2022 12:18:18 -0400
|
|
||||||
Subject: [PATCH] Add documentation describing support for user/group names
|
|
||||||
|
|
||||||
---
|
|
||||||
doc/fapolicyd.rules.5 | 6 +++---
|
|
||||||
init/fapolicyd.service | 2 ++
|
|
||||||
2 files changed, 5 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/doc/fapolicyd.rules.5 b/doc/fapolicyd.rules.5
|
|
||||||
index aa77177..3b8ec09 100644
|
|
||||||
--- a/doc/fapolicyd.rules.5
|
|
||||||
+++ b/doc/fapolicyd.rules.5
|
|
||||||
@@ -35,13 +35,13 @@ The subject is the process that is performing actions on system resources. The f
|
|
||||||
This matches against any subject. When used, this must be the only subject in the rule.
|
|
||||||
.TP
|
|
||||||
.B auid
|
|
||||||
-This is the login uid that the audit system assigns users when they log in to the system. Daemons have a value of -1.
|
|
||||||
+This is the login uid that the audit system assigns users when they log in to the system. Daemons have a value of -1. The given value may be numeric or the account name.
|
|
||||||
.TP
|
|
||||||
.B uid
|
|
||||||
-This is the user id that the program is running under.
|
|
||||||
+This is the user id that the program is running under. The given value may be numeric or the account name.
|
|
||||||
.TP
|
|
||||||
.B gid
|
|
||||||
-This is the group id that the program is running under.
|
|
||||||
+This is the group id that the program is running under. The given value may be numeric or the group name.
|
|
||||||
.TP
|
|
||||||
.B sessionid
|
|
||||||
This is the numeric session id that the audit system assigns to users when they log in. Daemons have a value of -1.
|
|
||||||
diff --git a/init/fapolicyd.service b/init/fapolicyd.service
|
|
||||||
index 715de98..a5a6a3f 100644
|
|
||||||
--- a/init/fapolicyd.service
|
|
||||||
+++ b/init/fapolicyd.service
|
|
||||||
@@ -11,6 +11,8 @@ PIDFile=/run/fapolicyd.pid
|
|
||||||
ExecStartPre=/usr/sbin/fagenrules
|
|
||||||
ExecStart=/usr/sbin/fapolicyd
|
|
||||||
Restart=on-abnormal
|
|
||||||
+# Uncomment the following line if rules need user/group name lookup
|
|
||||||
+#After=nss-user-lookup.target
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
--
|
|
||||||
2.37.1
|
|
||||||
|
|
13
SOURCES/selinux.patch
Normal file
13
SOURCES/selinux.patch
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
diff -up ./fapolicyd-selinux-0.6/fapolicyd.te.fix ./fapolicyd-selinux-0.6/fapolicyd.te
|
||||||
|
--- ./fapolicyd-selinux-0.6/fapolicyd.te.fix 2023-06-15 17:11:47.964646794 +0200
|
||||||
|
+++ ./fapolicyd-selinux-0.6/fapolicyd.te 2023-06-15 17:13:10.426477653 +0200
|
||||||
|
@@ -50,6 +50,9 @@ ifdef(`watch_mount_dirs_pattern',`
|
||||||
|
|
||||||
|
ifdef(`fs_watch_all_fs',`
|
||||||
|
fs_watch_all_fs(fapolicyd_t)
|
||||||
|
+')
|
||||||
|
+
|
||||||
|
+ifdef(`files_watch_sb_all_mountpoints',`
|
||||||
|
files_watch_sb_all_mountpoints(fapolicyd_t)
|
||||||
|
')
|
||||||
|
|
@ -1,11 +1,11 @@
|
|||||||
%global selinuxtype targeted
|
%global selinuxtype targeted
|
||||||
%global moduletype contrib
|
%global moduletype contrib
|
||||||
%define semodule_version 0.4
|
%define semodule_version 0.6
|
||||||
|
|
||||||
Summary: Application Whitelisting Daemon
|
Summary: Application Whitelisting Daemon
|
||||||
Name: fapolicyd
|
Name: fapolicyd
|
||||||
Version: 1.1.3
|
Version: 1.3.2
|
||||||
Release: 12%{?dist}
|
Release: 1%{?dist}
|
||||||
License: GPLv3+
|
License: GPLv3+
|
||||||
URL: http://people.redhat.com/sgrubb/fapolicyd
|
URL: http://people.redhat.com/sgrubb/fapolicyd
|
||||||
Source0: https://people.redhat.com/sgrubb/fapolicyd/%{name}-%{version}.tar.gz
|
Source0: https://people.redhat.com/sgrubb/fapolicyd/%{name}-%{version}.tar.gz
|
||||||
@ -30,19 +30,10 @@ Requires(postun): systemd-units
|
|||||||
# we require the rpm-plugin from now on and the dnf-plugin still needs to be part of
|
# 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
|
# the fapolicyd package because it provides safe upgrade path
|
||||||
Patch1: fapolicyd-dnf-plugin.patch
|
Patch1: fapolicyd-dnf-plugin.patch
|
||||||
Patch2: fapolicyd-selinux.patch
|
Patch2: selinux.patch
|
||||||
Patch3: fagenrules-group.patch
|
Patch3: fapolicyd-selinux-links.patch
|
||||||
|
Patch4: fapolicyd-leaks.patch
|
||||||
Patch4: fapolicyd-fgets-update-thread.patch
|
Patch5: fapolicyd-librpm-workaround.patch
|
||||||
Patch5: fapolicyd-openssl.patch
|
|
||||||
Patch6: fapolicyd-user-group-doc.patch
|
|
||||||
Patch7: fapolicyd-cli-segfault.patch
|
|
||||||
Patch8: fapolicyd-sighup.patch
|
|
||||||
Patch9: fapolicyd-readme.patch
|
|
||||||
|
|
||||||
Patch10: fapolicyd-falcon-sensor.patch
|
|
||||||
Patch11: fapolicyd-exclude-list.patch
|
|
||||||
Patch12: fapolicyd-already-started.patch
|
|
||||||
|
|
||||||
%description
|
%description
|
||||||
Fapolicyd (File Access Policy Daemon) implements application whitelisting
|
Fapolicyd (File Access Policy Daemon) implements application whitelisting
|
||||||
@ -69,19 +60,11 @@ The %{name}-selinux package contains selinux policy for the %{name} daemon.
|
|||||||
# selinux
|
# selinux
|
||||||
%setup -q -D -T -a 1
|
%setup -q -D -T -a 1
|
||||||
|
|
||||||
%patch1 -p1 -b .plugin
|
%patch -P 1 -p1 -b .dnf-plugin
|
||||||
%patch2 -p1 -b .selinux
|
%patch -P 2 -p1 -b .selinux
|
||||||
%patch3 -p1 -b .group
|
%patch -P 3 -p1 -b .selinux-links
|
||||||
%patch4 -p1 -b .update-thread
|
%patch -P 4 -p1 -b .leaks
|
||||||
%patch5 -p1 -b .openssl
|
%patch -P 5 -p1 -b .librpm-workaround
|
||||||
%patch6 -p1 -b .user-group
|
|
||||||
%patch7 -p1 -b .segfault
|
|
||||||
%patch8 -p1 -b .sighup
|
|
||||||
%patch9 -p1 -b .readme
|
|
||||||
|
|
||||||
%patch10 -p1 -b .event
|
|
||||||
%patch11 -p1 -b .exclude
|
|
||||||
%patch12 -p1 -b .already-started
|
|
||||||
|
|
||||||
# generate rules for python
|
# generate rules for python
|
||||||
sed -i "s|%python2_path%|`readlink -f %{__python2}`|g" rules.d/*.rules
|
sed -i "s|%python2_path%|`readlink -f %{__python2}`|g" rules.d/*.rules
|
||||||
@ -96,6 +79,7 @@ interpret=`readelf -e /usr/bin/bash \
|
|||||||
sed -i "s|%ld_so_path%|`realpath $interpret`|g" rules.d/*.rules
|
sed -i "s|%ld_so_path%|`realpath $interpret`|g" rules.d/*.rules
|
||||||
|
|
||||||
%build
|
%build
|
||||||
|
cp INSTALL INSTALL.tmp
|
||||||
./autogen.sh
|
./autogen.sh
|
||||||
%configure \
|
%configure \
|
||||||
--with-audit \
|
--with-audit \
|
||||||
@ -229,11 +213,12 @@ fi
|
|||||||
%attr(750,root,%{name}) %dir %{_sysconfdir}/%{name}
|
%attr(750,root,%{name}) %dir %{_sysconfdir}/%{name}
|
||||||
%attr(750,root,%{name}) %dir %{_sysconfdir}/%{name}/trust.d
|
%attr(750,root,%{name}) %dir %{_sysconfdir}/%{name}/trust.d
|
||||||
%attr(750,root,%{name}) %dir %{_sysconfdir}/%{name}/rules.d
|
%attr(750,root,%{name}) %dir %{_sysconfdir}/%{name}/rules.d
|
||||||
|
%attr(644,root,root) %{_sysconfdir}/bash_completion.d/*
|
||||||
%ghost %verify(not md5 size mtime) %attr(644,root,%{name}) %{_sysconfdir}/%{name}/rules.d/*
|
%ghost %verify(not md5 size mtime) %attr(644,root,%{name}) %{_sysconfdir}/%{name}/rules.d/*
|
||||||
%ghost %verify(not md5 size mtime) %attr(644,root,%{name}) %{_sysconfdir}/%{name}/%{name}.rules
|
%ghost %verify(not md5 size mtime) %attr(644,root,%{name}) %{_sysconfdir}/%{name}/%{name}.rules
|
||||||
%ghost %verify(not md5 size mtime) %attr(644,root,%{name}) %{_sysconfdir}/%{name}/compiled.rules
|
%ghost %verify(not md5 size mtime) %attr(644,root,%{name}) %{_sysconfdir}/%{name}/compiled.rules
|
||||||
%config(noreplace) %attr(644,root,%{name}) %{_sysconfdir}/%{name}/%{name}.conf
|
%config(noreplace) %attr(644,root,%{name}) %{_sysconfdir}/%{name}/%{name}.conf
|
||||||
%config(noreplace) %attr(644,root,%{name}) %{_sysconfdir}/%{name}/rpm-filter.conf
|
%config(noreplace) %attr(644,root,%{name}) %{_sysconfdir}/%{name}/%{name}-filter.conf
|
||||||
%config(noreplace) %attr(644,root,%{name}) %{_sysconfdir}/%{name}/%{name}.trust
|
%config(noreplace) %attr(644,root,%{name}) %{_sysconfdir}/%{name}/%{name}.trust
|
||||||
%attr(644,root,root) %{_unitdir}/%{name}.service
|
%attr(644,root,root) %{_unitdir}/%{name}.service
|
||||||
%attr(644,root,root) %{_tmpfilesdir}/%{name}.conf
|
%attr(644,root,root) %{_tmpfilesdir}/%{name}.conf
|
||||||
@ -242,7 +227,6 @@ fi
|
|||||||
%attr(755,root,root) %{_sbindir}/fagenrules
|
%attr(755,root,root) %{_sbindir}/fagenrules
|
||||||
%attr(644,root,root) %{_mandir}/man8/*
|
%attr(644,root,root) %{_mandir}/man8/*
|
||||||
%attr(644,root,root) %{_mandir}/man5/*
|
%attr(644,root,root) %{_mandir}/man5/*
|
||||||
%attr(644,root,root) %{_mandir}/man1/*
|
|
||||||
%ghost %attr(440,%{name},%{name}) %verify(not md5 size mtime) %{_localstatedir}/log/%{name}-access.log
|
%ghost %attr(440,%{name},%{name}) %verify(not md5 size mtime) %{_localstatedir}/log/%{name}-access.log
|
||||||
%attr(770,root,%{name}) %dir %{_localstatedir}/lib/%{name}
|
%attr(770,root,%{name}) %dir %{_localstatedir}/lib/%{name}
|
||||||
%attr(770,root,%{name}) %dir /run/%{name}
|
%attr(770,root,%{name}) %dir /run/%{name}
|
||||||
@ -271,6 +255,27 @@ fi
|
|||||||
%selinux_relabel_post -s %{selinuxtype}
|
%selinux_relabel_post -s %{selinuxtype}
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Jul 19 2023 Radovan Sroka <rsroka@redhat.com> - 1.3.2-1
|
||||||
|
RHEL 8.9.0 ERRATUM
|
||||||
|
- Rebase fapolicyd to the latest stable version
|
||||||
|
Resolves: RHEL-519
|
||||||
|
- RFE: send rule number to fanotify so it gets audited
|
||||||
|
Resolves: RHEL-628
|
||||||
|
- Default q_size doesn't match manpage's one
|
||||||
|
Resolves: RHEL-629
|
||||||
|
- fapolicyd can leak FDs and never answer request, causing target process to hang forever
|
||||||
|
Resolves: RHEL-632
|
||||||
|
- fapolicyd needs to make sure the FD limit is never reached
|
||||||
|
Resolves: RHEL-631
|
||||||
|
- fapolicyd still allows execution of a program after "untrusting" it
|
||||||
|
Resolves: RHEL-630
|
||||||
|
- Fix broken backwards compatibility backend numbers
|
||||||
|
Resolves: RHEL-731
|
||||||
|
- fapolicyd can create RPM DB files /var/lib/rpm/__db.xxx with bad ownership causing AVCs to occur
|
||||||
|
Resolves: RHEL-829
|
||||||
|
- SELinux prevents the fapolicyd from reading symlink (cert_t)
|
||||||
|
Resolves: RHEL-820
|
||||||
|
|
||||||
* Mon Jan 30 2023 Radovan Sroka <rsroka@redhat.com> - 1.1.3-12
|
* Mon Jan 30 2023 Radovan Sroka <rsroka@redhat.com> - 1.1.3-12
|
||||||
RHEL 8.8.0 ERRATUM
|
RHEL 8.8.0 ERRATUM
|
||||||
- statically linked app can execute untrusted app
|
- statically linked app can execute untrusted app
|
||||||
|
Loading…
Reference in New Issue
Block a user