Skip to content

Commit

Permalink
Introduce runtime rules reloading feature
Browse files Browse the repository at this point in the history
- rules are reloaded in case of SIGHUB
- the pipe logic was extended as well since it accepts number 3 now (for
  rules reloading)
- CLI has new option "-r" that provides this capability

Signed-off-by: Radovan Sroka <rsroka@redhat.com>
  • Loading branch information
radosroka committed Jun 14, 2023
1 parent 331a38e commit fd1bb74
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 56 deletions.
27 changes: 23 additions & 4 deletions src/cli/fapolicyd-cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ static const char *usage =
"-t, --ftype file-path Prints out the mime type of a file\n"
"-l, --list Prints a list of the daemon's rules with numbers\n"
"-u, --update Notifies fapolicyd to perform update of database\n"
"-r, --reload-rules Notifies fapolicyd to perform reload of rules\n"
;

static struct option long_opts[] =
Expand All @@ -83,11 +84,15 @@ static struct option long_opts[] =
{"ftype", 1, NULL, 't'},
{"list", 0, NULL, 'l'},
{"update", 0, NULL, 'u'},
{"reload-rules", 0, NULL, 'r'},
{ NULL, 0, NULL, 0 }
};

volatile atomic_bool stop = 0; // Library needs this
unsigned int debug_mode = 0; // Library needs this
unsigned int permissive = 0; // Library needs this

typedef enum _reload_code { DB, RULES} reload_code;

static char *get_line(FILE *f, unsigned *lineno)
{
Expand Down Expand Up @@ -452,7 +457,7 @@ static int do_list(void)
}


static int do_update(void)
static int do_reload(int code)
{
int fd = -1;
struct stat s;
Expand Down Expand Up @@ -487,7 +492,16 @@ static int do_update(void)
}
}

ssize_t ret = write(fd, "1\n", 2);
ssize_t ret;
char str[32] = {0};

if (code == DB) {
snprintf(str, 32, "%c\n", RELOAD_TRUSTDB_COMMAND);
ret = write(fd, "1\n", strlen(str));
} else if (code == RULES) {
snprintf(str, 32, "%c\n", RELOAD_RULES_COMMAND);
ret = write(fd, "3\n", strlen(str));
}

if (ret == -1) {
fprintf(stderr,"Write: %s -> %s\n", fifo_path, strerror(errno));
Expand Down Expand Up @@ -874,7 +888,7 @@ int main(int argc, char * const argv[])
return rc;
}

opt = getopt_long(argc, argv, "Ddf:ht:lu",
opt = getopt_long(argc, argv, "Ddf:ht:lur",
long_opts, &option_index);
switch (opt) {
case 'd':
Expand Down Expand Up @@ -911,7 +925,12 @@ int main(int argc, char * const argv[])
case 'u':
if (argc > 2)
goto args_err;
rc = do_update();
rc = do_reload(DB);
break;
case 'r':
if (argc > 2)
goto args_err;
rc = do_reload(RULES);
break;

// Now the pure long options
Expand Down
4 changes: 2 additions & 2 deletions src/daemon/fapolicyd.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,9 @@ static void usr1_handler(int sig __attribute__((unused)))
*/
static void reconfigure(void)
{
update_trust_database();
set_reload_rules();

// TODO: Update rules
set_reload_trust_database();

// TODO: Update configuration
}
Expand Down
1 change: 1 addition & 0 deletions src/daemon/notify.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@

// External variables
extern volatile atomic_bool stop, run_stats;
extern unsigned int permissive;

// Local variables
static pid_t our_pid;
Expand Down
50 changes: 45 additions & 5 deletions src/library/database.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,11 @@
#include "backend-manager.h"
#include "gcc-attributes.h"
#include "paths.h"
#include "policy.h"

// Local defines
enum { READ_DATA, READ_TEST_KEY, READ_DATA_DUP };
typedef enum { DB_NO_OP, ONE_FILE, RELOAD_DB, FLUSH_CACHE } db_ops_t;
typedef enum { DB_NO_OP, ONE_FILE, RELOAD_DB, FLUSH_CACHE, RELOAD_RULES } db_ops_t;
#define BUFFER_SIZE 4096
#define MEGABYTE (1024*1024)

Expand All @@ -71,6 +72,7 @@ static atomic_int reload_db = 0;

static pthread_t update_thread;
static pthread_mutex_t update_lock;
static pthread_mutex_t rule_lock;

// Local functions
static void *update_thread_main(void *arg);
Expand All @@ -79,6 +81,7 @@ static int update_database(conf_t *config);
// External variables
extern volatile atomic_bool stop;
extern volatile atomic_bool needs_flush;
extern volatile atomic_bool reload_rules;


static int is_link(const char *path)
Expand Down Expand Up @@ -848,6 +851,7 @@ int init_database(conf_t *config)

// update_lock is used in update_database()
pthread_mutex_init(&update_lock, NULL);
pthread_mutex_init(&rule_lock, NULL);

if (migrate_database())
return 1;
Expand Down Expand Up @@ -1078,6 +1082,7 @@ void close_database(void)
// we can close db when we are really sure update_thread does not exist
close_db(1);
pthread_mutex_destroy(&update_lock);
pthread_mutex_destroy(&rule_lock);

backend_close();
unlink_fifo();
Expand All @@ -1098,7 +1103,6 @@ void lock_update_thread(void) {
//msg(LOG_DEBUG, "lock_update_thread()");
}


/*
* Unlock wrapper for update mutex
*/
Expand All @@ -1107,6 +1111,21 @@ void unlock_update_thread(void) {
//msg(LOG_DEBUG, "unlock_update_thread()");
}

/*
* Lock wrapper for rule mutex
*/
void lock_rule(void) {
pthread_mutex_lock(&rule_lock);
//msg(LOG_DEBUG, "lock_rule()");
}

/*
* Unlock wrapper for rule mutex
*/
void unlock_rule(void) {
pthread_mutex_unlock(&rule_lock);
//msg(LOG_DEBUG, "unlock_rule()");
}

/*
* This function reloads updated backend db into our internal database.
Expand Down Expand Up @@ -1183,7 +1202,7 @@ static int handle_record(const char * buffer)
return 0;
}

void update_trust_database(void)
void set_reload_trust_database(void)
{
reload_db = 1;
}
Expand Down Expand Up @@ -1246,6 +1265,14 @@ static void *update_thread_main(void *arg)

rc = poll(ffd, 1, 1000);

if (reload_rules) {
reload_rules = 0;
load_rule_file();

lock_rule();
do_reload_rules(config);
unlock_rule();
}
// got SIGHUP
if (reload_db) {
reload_db = 0;
Expand Down Expand Up @@ -1302,16 +1329,21 @@ static void *update_thread_main(void *arg)
break;
}

if (buff[i] == '1') {
if (buff[i] == RELOAD_TRUSTDB_COMMAND) {
do_operation = RELOAD_DB;
break;
}

if (buff[i] == '2') {
if (buff[i] == FLUSH_CACHE_COMMAND) {
do_operation = FLUSH_CACHE;
break;
}

if (buff[i] == RELOAD_RULES_COMMAND) {
do_operation = RELOAD_RULES;
break;
}

if (isspace(buff[i]))
continue;

Expand All @@ -1325,6 +1357,14 @@ static void *update_thread_main(void *arg)
if (do_operation == RELOAD_DB) {
do_operation = DB_NO_OP;
do_reload_db(config);
} else if (do_operation == RELOAD_RULES) {
do_operation = DB_NO_OP;

load_rule_file();

lock_rule();
do_reload_rules(config);
unlock_rule();

// got "2" -> flush cache
} else if (do_operation == FLUSH_CACHE) {
Expand Down
10 changes: 8 additions & 2 deletions src/library/database.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
#include "conf.h"
#include "file.h"


typedef struct {
MDB_val path;
MDB_val data;
Expand All @@ -43,16 +42,23 @@ const char *lookup_tsource(unsigned int tsource);
int preconstruct_fifo(const conf_t *config);
int init_database(conf_t *config);
int check_trust_database(const char *path, struct file_info *info, int fd);
void update_trust_database(void);
void set_reload_trust_database(void);
void close_database(void);
void database_report(FILE *f);
int unlink_db(void);
void unlink_fifo(void);

void lock_rule(void);
void unlock_rule(void);

// Database verification functions
int walk_database_start(conf_t *config);
walkdb_entry_t *walk_database_get_entry(void);
int walk_database_next(void);
void walk_database_finish(void);

#define RELOAD_TRUSTDB_COMMAND '1'
#define FLUSH_CACHE_COMMAND '2'
#define RELOAD_RULES_COMMAND '3'

#endif
1 change: 1 addition & 0 deletions src/library/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "file.h"
#include "lru.h"
#include "message.h"
#include "policy.h"

#define ALL_EVENTS (FAN_ALL_EVENTS|FAN_OPEN_PERM|FAN_ACCESS_PERM| \
FAN_OPEN_EXEC_PERM)
Expand Down
Loading

0 comments on commit fd1bb74

Please sign in to comment.