mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-22 01:57:43 +00:00
parser: Enable cache overlay in the parser
Allow the parser to use cache overlays by extending the --cache-loc flag to support multiple locations via a comma separated list. eg. --cache-loc=/var/cache/apparmor/,/etc/apparmor.d/cache.d/ The overlayed cache directories are searched in the order specified. So in the above example /var/cache/apparmor is searched before /etc/apparmor.d/ Time stamps are ignored in the search, the first match found wins regardless if there exists a matching cache file with a newer timestamp in a directory is later in the search. Cache writes will only occur to the first dir in the list. So /var/cache/apparmor/ in the above example. Signed-off-by: John Johansen <john.johansen@canonical.com> Acked-by: Christian Boltz <apparmor@cboltz.de>
This commit is contained in:
parent
9e48a5da5e
commit
481f59a39b
@ -392,11 +392,7 @@ int aa_policy_cache_new(aa_policy_cache **policy_cache,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (max_caches > 1) {
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* TODO: currently no reaping of caches in excess of max_caches */
|
||||
pc = calloc(1, sizeof(*pc));
|
||||
if (!pc) {
|
||||
errno = ENOMEM;
|
||||
|
@ -233,8 +233,21 @@ inconsistent state
|
||||
|
||||
=item -L, --cache-loc
|
||||
|
||||
Set the location of the cache directory. If not specified the cache location
|
||||
defaults to /etc/apparmor.d/cache.d
|
||||
Set the location(s) of the cache directory. This option can accept a
|
||||
comma separated list of directories, which will be searched in order
|
||||
to find a matching cache. The first matching cache file found is used
|
||||
even if a directory later in the search order may contain a newer cache
|
||||
file.
|
||||
|
||||
If multiple directories are specified and --write-cache has been specified
|
||||
then cache writes will be made to the first directory in the list, all
|
||||
other directories will be treated as read only.
|
||||
|
||||
If a cache directory name needs to have a comma as part of the name, it
|
||||
can be specified by using a backslash to escape the comma character in
|
||||
the directory name.
|
||||
|
||||
If not specified the cache location defaults to /etc/apparmor.d/cache.d
|
||||
|
||||
=item --print-cache-dir
|
||||
|
||||
|
@ -97,10 +97,13 @@ long jobs_scale = 0; /* number of chance to resample online
|
||||
*/
|
||||
bool debug_jobs = false;
|
||||
|
||||
#define MAX_CACHE_LOCS 4
|
||||
|
||||
struct timespec cache_tstamp, mru_policy_tstamp;
|
||||
|
||||
static char *apparmorfs = NULL;
|
||||
static char *cacheloc = NULL;
|
||||
static char *cacheloc[MAX_CACHE_LOCS];
|
||||
static int cacheloc_n = 0;
|
||||
static bool print_cache_dir = false;
|
||||
|
||||
static aa_features *compile_features = NULL;
|
||||
@ -194,7 +197,7 @@ static void display_usage(const char *command)
|
||||
" --purge-cache Clear cache regardless of its state\n"
|
||||
" --debug-cache Debug cache file checks\n"
|
||||
" --print-cache_dir Print the cache directory path\n"
|
||||
"-L, --cache-loc n Set the location of the profile cache\n"
|
||||
"-L, --cache-loc n Set the location of the profile caches\n"
|
||||
"-q, --quiet Don't emit warnings\n"
|
||||
"-v, --verbose Show profile names as they load\n"
|
||||
"-Q, --skip-kernel-load Do everything except loading into kernel\n"
|
||||
@ -228,6 +231,51 @@ void display_warn(const char *command)
|
||||
print_flag_table(warnflag_table);
|
||||
}
|
||||
|
||||
/* Parse comma separated cachelocations. Commas can be escaped by \, */
|
||||
static int parse_cacheloc(const char *arg, char **cacheloc, int max_size)
|
||||
{
|
||||
const char *s = arg;
|
||||
const char *p = arg;
|
||||
int n = 0;
|
||||
|
||||
while(*p) {
|
||||
if (*p == '\\') {
|
||||
if (*(p + 1) != 0)
|
||||
p++;
|
||||
} else if (*p == ',') {
|
||||
if (p != s) {
|
||||
if (n == max_size) {
|
||||
errno = E2BIG;
|
||||
return -1;
|
||||
}
|
||||
cacheloc[n] = (char *) malloc(p - s + 1);
|
||||
if (cacheloc[n] == NULL)
|
||||
return -1;
|
||||
memcpy(cacheloc[n], s, p - s);
|
||||
cacheloc[n][p - s] = 0;
|
||||
n++;
|
||||
}
|
||||
p++;
|
||||
s = p;
|
||||
} else
|
||||
p++;
|
||||
}
|
||||
if (p != s) {
|
||||
if (n == max_size) {
|
||||
errno = E2BIG;
|
||||
return -1;
|
||||
}
|
||||
cacheloc[n] = (char *) malloc(p - s + 1);
|
||||
if (cacheloc[n] == NULL)
|
||||
return -1;
|
||||
memcpy(cacheloc[n], s, p - s);
|
||||
cacheloc[n][p - s] = 0;
|
||||
n++;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/* Treat conf file like options passed on command line
|
||||
*/
|
||||
static int getopt_long_file(FILE *f, const struct option *longopts,
|
||||
@ -520,7 +568,11 @@ static int process_arg(int c, char *optarg)
|
||||
skip_bad_cache_rebuild = 1;
|
||||
break;
|
||||
case 'L':
|
||||
cacheloc = strdup(optarg);
|
||||
cacheloc_n = parse_cacheloc(optarg, cacheloc, MAX_CACHE_LOCS);
|
||||
if (cacheloc_n == -1) {
|
||||
PERROR("%s: Invalid --cacheloc option '%s' %m\n", progname, optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'Q':
|
||||
kernel_load = 0;
|
||||
@ -690,6 +742,19 @@ static bool do_print_cache_dir(aa_features *features, int dirfd, const char *pat
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool do_print_cache_dirs(aa_features *features, char **cacheloc,
|
||||
int cacheloc_n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < cacheloc_n; i++) {
|
||||
if (!do_print_cache_dir(features, AT_FDCWD, cacheloc[i]))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int process_binary(int option, aa_kernel_interface *kernel_interface,
|
||||
const char *profilename)
|
||||
{
|
||||
@ -821,9 +886,14 @@ int process_profile(int option, aa_kernel_interface *kernel_interface,
|
||||
if (!force_complain && pc) {
|
||||
cachename = aa_policy_cache_filename(pc, basename);
|
||||
if (!cachename) {
|
||||
PERROR("Could not get cachename for '%s'\n", basename);
|
||||
} else
|
||||
autoclose int fd = aa_policy_cache_open(pc,
|
||||
basename,
|
||||
O_RDONLY);
|
||||
if (fd != -1)
|
||||
pwarn(_("Could not get cachename for '%s'\n"), basename);
|
||||
} else {
|
||||
valid_read_cache(cachename);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -890,15 +960,15 @@ int process_profile(int option, aa_kernel_interface *kernel_interface,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (pc && write_cache) {
|
||||
if (pc && write_cache && !force_complain) {
|
||||
writecachename = cache_filename(pc, 0, basename);
|
||||
if (!writecachename) {
|
||||
PERROR("Cache write disabled: Cannot create cache file name '%s': %m\n", basename);
|
||||
pwarn("Cache write disabled: Cannot create cache file name '%s': %m\n", basename);
|
||||
write_cache = 0;
|
||||
}
|
||||
cachetmp = setup_cache_tmp(&cachetmpname, writecachename);
|
||||
if (cachetmp == -1) {
|
||||
PERROR("Cache write disabled: Cannot create setup tmp cache file '%s': %m\n", writecachename);
|
||||
pwarn("Cache write disabled: Cannot create setup tmp cache file '%s': %m\n", writecachename);
|
||||
write_cache = 0;
|
||||
}
|
||||
}
|
||||
@ -907,7 +977,7 @@ int process_profile(int option, aa_kernel_interface *kernel_interface,
|
||||
if (retval == 0 && write_cache) {
|
||||
if (cachetmp == -1) {
|
||||
unlink(cachetmpname);
|
||||
PERROR("Warning failed to create cache: %s\n",
|
||||
pwarn("Warning failed to create cache: %s\n",
|
||||
basename);
|
||||
} else {
|
||||
install_cache(cachetmpname, writecachename);
|
||||
@ -1148,21 +1218,27 @@ int main(int argc, char *argv[])
|
||||
|
||||
if ((!skip_cache && (write_cache || !skip_read_cache)) ||
|
||||
print_cache_dir || force_clear_cache) {
|
||||
uint16_t max_caches = write_cache && cond_clear_cache ? 1 : 0;
|
||||
uint16_t max_caches = write_cache && cond_clear_cache ? (uint16_t) (-1) : 0;
|
||||
|
||||
if (!cacheloc && asprintf(&cacheloc, "%s/cache.d", basedir) == -1) {
|
||||
PERROR(_("Memory allocation error."));
|
||||
return 1;
|
||||
if (!cacheloc[0]) {
|
||||
char *tmp;
|
||||
|
||||
if (asprintf(&tmp, "%s/cache.d", basedir) == -1) {
|
||||
PERROR(_("Memory allocation error."));
|
||||
return 1;
|
||||
}
|
||||
cacheloc[0] = tmp;
|
||||
cacheloc_n = 1;
|
||||
}
|
||||
|
||||
if (print_cache_dir)
|
||||
return do_print_cache_dir(kernel_features, AT_FDCWD,
|
||||
cacheloc) ? 0 : 1;
|
||||
return do_print_cache_dirs(kernel_features, cacheloc,
|
||||
cacheloc_n) ? 0 : 1;
|
||||
|
||||
if (force_clear_cache) {
|
||||
if (aa_policy_cache_remove(AT_FDCWD, cacheloc)) {
|
||||
/* only ever write to the first cacheloc location */
|
||||
if (aa_policy_cache_remove(AT_FDCWD, cacheloc[0])) {
|
||||
PERROR(_("Failed to clear cache files (%s): %s\n"),
|
||||
cacheloc, strerror(errno));
|
||||
cacheloc[0], strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1173,24 +1249,33 @@ int main(int argc, char *argv[])
|
||||
pwarn(_("The --create-cache-dir option is deprecated. Please use --write-cache.\n"));
|
||||
|
||||
retval = aa_policy_cache_new(&policy_cache, kernel_features,
|
||||
AT_FDCWD, cacheloc, max_caches);
|
||||
AT_FDCWD, cacheloc[0], max_caches);
|
||||
if (retval) {
|
||||
if (errno != ENOENT && errno != EEXIST && errno != EROFS) {
|
||||
PERROR(_("Failed setting up policy cache (%s): %s\n"),
|
||||
cacheloc, strerror(errno));
|
||||
cacheloc[0], strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (show_cache) {
|
||||
if (max_caches > 0)
|
||||
PERROR("Cache write disabled: Cannot create cache '%s': %m\n",
|
||||
cacheloc);
|
||||
cacheloc[0]);
|
||||
else
|
||||
PERROR("Cache read/write disabled: Policy cache is invalid\n");
|
||||
PERROR("Cache read/write disabled: Policy cache is invalid: %m\n");
|
||||
}
|
||||
|
||||
write_cache = 0;
|
||||
skip_read_cache = 1;
|
||||
} else {
|
||||
if (show_cache)
|
||||
PERROR("Cache: added primary location '%s'\n", cacheloc[0]);
|
||||
for (i = 1; i < cacheloc_n; i++) {
|
||||
if (aa_policy_cache_add_ro_dir(policy_cache, AT_FDCWD,
|
||||
cacheloc[i])) {
|
||||
pwarn("Cache: failed to add read only location '%s', does not contain valid cache directory for the specified feature set\n", cacheloc[i]);
|
||||
} else if (show_cache)
|
||||
pwarn("Cache: added readonly location '%s'\n", cacheloc[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user