[apparmor] [PATCH 2/2] Set cache file tstamp to the mtime of most recent policy file tstamps
John Johansen
john.johansen at canonical.com
Fri Jun 5 22:24:23 UTC 2015
Currently the cache file has its mtime set to its creation time, but this
can lead to cache issues when a policy file is updated separately from
the cache file so that is possible a policy file is newer than the
what the cache file was generated from but still fails the comparison
because the generated cache file has a newer timestamp.
Signed-off-by: John Johansen <john.johansen at canonical.com>
---
parser/parser.h | 1 -
parser/parser_main.c | 5 +++--
parser/policy_cache.c | 25 +++++++++++++++++++------
parser/policy_cache.h | 12 +++++++-----
4 files changed, 29 insertions(+), 14 deletions(-)
diff --git a/parser/parser.h b/parser/parser.h
index f4566b9..f27e18b 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 cff0813..f274d00 100644
--- a/parser/parser_main.c
+++ b/parser/parser_main.c
@@ -76,7 +76,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;
@@ -645,7 +645,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 65829a6..4ba732c 100644
--- a/parser/policy_cache.c
+++ b/parser/policy_cache.c
@@ -25,6 +25,8 @@
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
+#include <sys/time.h>
+#include <utime.h>
#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 3c3e85d..693370d 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);
--
2.1.4
More information about the AppArmor
mailing list