diff --git a/parser/parser.h b/parser/parser.h index f4566b949..f27e18b91 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -333,7 +333,6 @@ extern int abort_on_error; extern int skip_bad_cache_rebuild; extern int mru_skip_cache; extern int debug_cache; -extern struct timespec mru_tstamp; /* provided by parser_lex.l (cannot be used in tst builds) */ extern FILE *yyin; diff --git a/parser/parser_main.c b/parser/parser_main.c index 8aee1483c..2a6c09332 100644 --- a/parser/parser_main.c +++ b/parser/parser_main.c @@ -77,7 +77,7 @@ int abort_on_error = 0; /* stop processing profiles if error */ int skip_bad_cache_rebuild = 0; int mru_skip_cache = 1; int debug_cache = 0; -struct timespec mru_tstamp; +struct timespec cache_tstamp, mru_policy_tstamp; static char *apparmorfs = NULL; static char *cacheloc = NULL; @@ -646,7 +646,8 @@ int process_binary(int option, aa_kernel_interface *kernel_interface, void reset_parser(const char *filename) { - memset(&mru_tstamp, 0, sizeof(mru_tstamp)); + memset(&mru_policy_tstamp, 0, sizeof(mru_policy_tstamp)); + memset(&cache_tstamp, 0, sizeof(cache_tstamp)); mru_skip_cache = 1; free_aliases(); free_symtabs(); diff --git a/parser/policy_cache.c b/parser/policy_cache.c index 65829a69a..4ba732cb4 100644 --- a/parser/policy_cache.c +++ b/parser/policy_cache.c @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include "lib.h" #include "parser.h" @@ -70,22 +72,27 @@ bool valid_cached_file_version(const char *cachename) } -void set_mru_tstamp(struct timespec t) +void set_cache_tstamp(struct timespec t) { mru_skip_cache = 0; - mru_tstamp = t; + cache_tstamp = t; } void update_mru_tstamp(FILE *file, const char *name) { struct stat stat_file; - if (fstat(fileno(file), &stat_file) || (mru_tstamp.tv_sec == 0 && mru_tstamp.tv_nsec == 0)) + if (fstat(fileno(file), &stat_file)) return; - if (mru_t_cmp(stat_file.st_mtim)) { + if (tstamp_cmp(mru_policy_tstamp, stat_file.st_mtim) < 0) + /* keep track of the most recent policy tstamp */ + mru_policy_tstamp = stat_file.st_mtim; + if (tstamp_is_null(cache_tstamp)) + return; + if (tstamp_cmp(stat_file.st_mtim, cache_tstamp) > 0) { if (debug_cache) pwarn("%s: file '%s' is newer than cache file\n", progname, name); mru_skip_cache = 1; - } + } } char *cache_filename(const char *cachedir, const char *basename) @@ -109,7 +116,7 @@ void valid_read_cache(const char *cachename) if (stat(cachename, &stat_bin) == 0 && stat_bin.st_size > 0) { if (valid_cached_file_version(cachename)) - set_mru_tstamp(stat_bin.st_mtim); + set_cache_tstamp(stat_bin.st_mtim); else if (!cond_clear_cache) write_cache = 0; } else { @@ -159,6 +166,12 @@ void install_cache(const char *cachetmpname, const char *cachename) /* Only install the generate cache file if it parsed correctly and did not have write/close errors */ if (cachetmpname) { + struct timeval t; + /* set the mtime of the cache file to the most newest mtime + * of policy files used to generate it + */ + TIMESPEC_TO_TIMEVAL(&t, &mru_policy_tstamp); + utimes(cachetmpname, &t); if (rename(cachetmpname, cachename) < 0) { pwarn("Warning failed to write cache: %s\n", cachename); unlink(cachetmpname); diff --git a/parser/policy_cache.h b/parser/policy_cache.h index 3c3e85d59..693370d00 100644 --- a/parser/policy_cache.h +++ b/parser/policy_cache.h @@ -19,12 +19,14 @@ #ifndef __AA_POLICY_CACHE_H #define __AA_POLICY_CACHE_H -extern struct timespec mru_tstamp; +extern struct timespec cache_tstamp, mru_policy_tstamp; /* returns true if time is more recent than mru_tstamp */ -#define mru_t_cmp(a) \ -(((a).tv_sec == (mru_tstamp).tv_sec) ? \ - (a).tv_nsec > (mru_tstamp).tv_nsec : (a).tv_sec > (mru_tstamp).tv_sec) +#define tstamp_cmp(a, b) \ + (((a).tv_sec == (b).tv_sec) ? \ + ((a).tv_nsec - (b).tv_nsec) : \ + ((a).tv_sec - (b).tv_sec)) +#define tstamp_is_null(a) ((a).tv_sec == 0 && (a).tv_nsec == 0) extern int show_cache; extern int skip_cache; @@ -36,7 +38,7 @@ extern int create_cache_dir; /* create the cache dir if missing? */ extern int mru_skip_cache; extern int debug_cache; -void set_mru_tstamp(struct timespec t); +void set_cache_tstamp(struct timespec t); void update_mru_tstamp(FILE *file, const char *path); bool valid_cached_file_version(const char *cachename); char *cache_filename(const char *cachedir, const char *basename);