[apparmor] [PATCH v2 41/42] libapparmor: Move the aa_policy_cache API
Tyler Hicks
tyhicks at canonical.com
Fri Mar 6 21:48:57 UTC 2015
Signed-off-by: Tyler Hicks <tyhicks at canonical.com>
---
libraries/libapparmor/include/sys/apparmor.h | 13 ++
libraries/libapparmor/src/Makefile.am | 2 +-
libraries/libapparmor/src/libapparmor.map | 7 +
libraries/libapparmor/src/policy_cache.c | 279 +++++++++++++++++++++++++++
parser/policy_cache.c | 250 ------------------------
parser/policy_cache.h | 16 --
6 files changed, 300 insertions(+), 267 deletions(-)
create mode 100644 libraries/libapparmor/src/policy_cache.c
diff --git a/libraries/libapparmor/include/sys/apparmor.h b/libraries/libapparmor/include/sys/apparmor.h
index f7ff1a7..8aa6b0e 100644
--- a/libraries/libapparmor/include/sys/apparmor.h
+++ b/libraries/libapparmor/include/sys/apparmor.h
@@ -139,6 +139,19 @@ int aa_kernel_interface_remove_policy(aa_kernel_interface *kernel_interface,
const char *fqname);
int aa_kernel_interface_write_policy(int fd, const char *buffer, size_t size);
+typedef struct aa_policy_cache aa_policy_cache;
+int aa_policy_cache_new(aa_policy_cache **policy_cache,
+ aa_features *kernel_features, const char *path,
+ bool create);
+aa_policy_cache *aa_policy_cache_ref(aa_policy_cache *policy_cache);
+void aa_policy_cache_unref(aa_policy_cache *policy_cache);
+
+bool aa_policy_cache_is_valid(aa_policy_cache *policy_cache);
+int aa_policy_cache_create(aa_policy_cache *policy_cache);
+int aa_policy_cache_remove(const char *path);
+int aa_policy_cache_replace_all(aa_policy_cache *policy_cache,
+ aa_kernel_interface *kernel_interface);
+
__END_DECLS
#endif /* sys/apparmor.h */
diff --git a/libraries/libapparmor/src/Makefile.am b/libraries/libapparmor/src/Makefile.am
index 86996dd..baad1e9 100644
--- a/libraries/libapparmor/src/Makefile.am
+++ b/libraries/libapparmor/src/Makefile.am
@@ -48,7 +48,7 @@ af_protos.h: /usr/include/netinet/in.h
lib_LTLIBRARIES = libapparmor.la
noinst_HEADERS = grammar.h parser.h scanner.h af_protos.h private.h
-libapparmor_la_SOURCES = grammar.y libaalogparse.c kernel.c scanner.c private.c features.c kernel_interface.c
+libapparmor_la_SOURCES = grammar.y libaalogparse.c kernel.c scanner.c private.c features.c kernel_interface.c policy_cache.c
libapparmor_la_LDFLAGS = -version-info $(AA_LIB_CURRENT):$(AA_LIB_REVISION):$(AA_LIB_AGE) -XCClinker -dynamic -pthread \
-Wl,--version-script=$(top_srcdir)/src/libapparmor.map
diff --git a/libraries/libapparmor/src/libapparmor.map b/libraries/libapparmor/src/libapparmor.map
index 5b06b54..0b7e72a 100644
--- a/libraries/libapparmor/src/libapparmor.map
+++ b/libraries/libapparmor/src/libapparmor.map
@@ -82,6 +82,13 @@ APPARMOR_2.10 {
aa_kernel_interface_replace_policy_from_fd;
aa_kernel_interface_remove_policy;
aa_kernel_interface_write_policy;
+ aa_policy_cache_new;
+ aa_policy_cache_ref;
+ aa_policy_cache_unref;
+ aa_policy_cache_is_valid;
+ aa_policy_cache_create;
+ aa_policy_cache_remove;
+ aa_policy_cache_replace_all;
local:
*;
} APPARMOR_2.9;
diff --git a/libraries/libapparmor/src/policy_cache.c b/libraries/libapparmor/src/policy_cache.c
new file mode 100644
index 0000000..d9ec4a1
--- /dev/null
+++ b/libraries/libapparmor/src/policy_cache.c
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 2014
+ * Canonical, Ltd. (All rights reserved)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact Novell, Inc. or Canonical
+ * Ltd.
+ */
+
+#include <dirent.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/apparmor.h>
+
+#include "private.h"
+
+struct aa_policy_cache {
+ unsigned int ref_count;
+ aa_features *features;
+ aa_features *kernel_features;
+ char *path;
+ char *features_path;
+};
+
+static int clear_cache_cb(DIR *dir, const char *path, struct stat *st,
+ void *data unused)
+{
+ /* remove regular files */
+ if (S_ISREG(st->st_mode))
+ return unlinkat(dirfd(dir), path, 0);
+
+ /* do nothing with other file types */
+ return 0;
+}
+
+static int create_cache(aa_policy_cache *policy_cache, aa_features *features)
+{
+ struct stat stat_file;
+ autofclose FILE * f = NULL;
+
+ if (aa_policy_cache_remove(policy_cache->path))
+ goto error;
+
+create_file:
+ if (aa_features_write_to_file(features,
+ policy_cache->features_path) == -1)
+ goto error;
+
+ aa_features_unref(policy_cache->features);
+ policy_cache->features = aa_features_ref(features);
+ return 0;
+
+error:
+ /* does the dir exist? */
+ if (stat(policy_cache->path, &stat_file) == -1) {
+ if (mkdir(policy_cache->path, 0700) == 0)
+ goto create_file;
+ PERROR("Can't create cache directory: %s\n",
+ policy_cache->path);
+ } else if (!S_ISDIR(stat_file.st_mode)) {
+ PERROR("File in cache directory location: %s\n",
+ policy_cache->path);
+ } else {
+ PERROR("Can't update cache directory: %s\n",
+ policy_cache->path);
+ }
+
+ return -1;
+}
+
+static int init_cache_features(aa_policy_cache *policy_cache,
+ aa_features *kernel_features, bool create)
+{
+ if (aa_features_new(&policy_cache->features,
+ policy_cache->features_path)) {
+ policy_cache->features = NULL;
+ if (!create || errno != ENOENT)
+ return -1;
+
+ return create_cache(policy_cache, kernel_features);
+ }
+
+ return 0;
+}
+
+struct replace_all_cb_data {
+ aa_policy_cache *policy_cache;
+ aa_kernel_interface *kernel_interface;
+};
+
+static int replace_all_cb(DIR *dir unused, const char *name, struct stat *st,
+ void *cb_data)
+{
+ int retval = 0;
+
+ if (!S_ISDIR(st->st_mode) && !_aa_is_blacklisted(name, NULL)) {
+ struct replace_all_cb_data *data;
+ autofree char *path = NULL;
+
+ data = (struct replace_all_cb_data *) cb_data;
+ if (asprintf(&path, "%s/%s",
+ data->policy_cache->path, name) < 0) {
+ path = NULL;
+ errno = ENOMEM;
+ return -1;
+ }
+ retval = aa_kernel_interface_replace_policy_from_file(data->kernel_interface,
+ path);
+ }
+
+ return retval;
+}
+
+/**
+ * aa_policy_cache_new - create a new policy_cache from a path
+ * @policy_cache: will point to the address of an allocated and initialized
+ * aa_policy_cache_new object upon success
+ * @kernel_features: features representing the currently running kernel
+ * @path: path to the policy cache
+ * @create: true if the cache should be created if it doesn't already exist
+ *
+ * Returns: 0 on success, -1 on error with errno set and *@policy_cache
+ * pointing to NULL
+ */
+int aa_policy_cache_new(aa_policy_cache **policy_cache,
+ aa_features *kernel_features, const char *path,
+ bool create)
+{
+ aa_policy_cache *pc;
+
+ *policy_cache = NULL;
+
+ if (!path) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ pc = (aa_policy_cache *) calloc(1, sizeof(*pc));
+ if (!pc) {
+ errno = ENOMEM;
+ return -1;
+ }
+ aa_policy_cache_ref(pc);
+
+ pc->path = strdup(path);
+ if (!pc->path) {
+ aa_policy_cache_unref(pc);
+ errno = ENOMEM;
+ return -1;
+ }
+
+ if (asprintf(&pc->features_path, "%s/.features", pc->path) == -1) {
+ pc->features_path = NULL;
+ aa_policy_cache_unref(pc);
+ errno = ENOMEM;
+ return -1;
+ }
+
+ if (init_cache_features(pc, kernel_features, create)) {
+ int save = errno;
+
+ aa_policy_cache_unref(pc);
+ errno = save;
+ return -1;
+ }
+
+ pc->kernel_features = aa_features_ref(kernel_features);
+ *policy_cache = pc;
+
+ return 0;
+}
+
+/**
+ * aa_policy_cache_ref - increments the ref count of a policy_cache
+ * @policy_cache: the policy_cache
+ *
+ * Returns: the policy_cache
+ */
+aa_policy_cache *aa_policy_cache_ref(aa_policy_cache *policy_cache)
+{
+ atomic_inc(&policy_cache->ref_count);
+ return policy_cache;
+}
+
+/**
+ * aa_policy_cache_unref - decrements the ref count and frees the policy_cache when 0
+ * @policy_cache: the policy_cache (can be NULL)
+ */
+void aa_policy_cache_unref(aa_policy_cache *policy_cache)
+{
+ if (policy_cache && atomic_dec_and_test(&policy_cache->ref_count)) {
+ free(policy_cache->features_path);
+ free(policy_cache->path);
+ free(policy_cache);
+ }
+}
+
+/**
+ * aa_policy_cache_is_valid - checks if the policy_cache is valid for the currently running kernel
+ * @policy_cache: the policy_cache
+ *
+ * Returns: true if the policy_cache is valid for the currently running kernel,
+ * false if not
+ */
+bool aa_policy_cache_is_valid(aa_policy_cache *policy_cache)
+{
+ return aa_features_is_equal(policy_cache->features,
+ policy_cache->kernel_features);
+}
+
+/**
+ * aa_policy_cache_create - creates a valid policy_cache for the currently running kernel
+ * @policy_cache: the policy_cache
+ *
+ * Returns: 0 on success, -1 on error with errno set and features pointing to
+ * NULL
+ */
+int aa_policy_cache_create(aa_policy_cache *policy_cache)
+{
+ return create_cache(policy_cache, policy_cache->kernel_features);
+}
+
+/**
+ * aa_policy_cache_remove - removes all policy cache files under a path
+ * @path: the path to a policy cache directory
+ *
+ * Returns: 0 on success, -1 on error with errno set
+ */
+int aa_policy_cache_remove(const char *path)
+{
+ return _aa_dirat_for_each(NULL, path, NULL, clear_cache_cb);
+}
+
+/**
+ * aa_policy_cache_replace_all - performs a kernel policy replacement of all cached policies
+ * @policy_cache: the policy_cache
+ * @kernel_interface: the kernel interface to use when doing the replacement
+ *
+ * Returns: 0 on success, -1 on error with errno set and features pointing to
+ * NULL
+ */
+int aa_policy_cache_replace_all(aa_policy_cache *policy_cache,
+ aa_kernel_interface *kernel_interface)
+{
+ struct replace_all_cb_data cb_data;
+ int retval;
+
+ if (kernel_interface) {
+ aa_kernel_interface_ref(kernel_interface);
+ } else if (aa_kernel_interface_new(&kernel_interface,
+ policy_cache->kernel_features,
+ NULL) == -1) {
+ kernel_interface = NULL;
+ return -1;
+ }
+
+ cb_data.policy_cache = policy_cache;
+ cb_data.kernel_interface = kernel_interface;
+ retval = _aa_dirat_for_each(NULL, policy_cache->path, &cb_data,
+ replace_all_cb);
+
+ aa_kernel_interface_unref(kernel_interface);
+
+ return retval;
+}
diff --git a/parser/policy_cache.c b/parser/policy_cache.c
index c28a981..fc4912e 100644
--- a/parser/policy_cache.c
+++ b/parser/policy_cache.c
@@ -32,14 +32,6 @@
#define le16_to_cpu(x) ((uint16_t)(le16toh (*(uint16_t *) x)))
-struct aa_policy_cache {
- unsigned int ref_count;
- aa_features *features;
- aa_features *kernel_features;
- char *path;
- char *features_path;
-};
-
const char header_string[] = "\004\010\000version\000\002";
#define HEADER_STRING_SIZE 12
bool valid_cached_file_version(const char *cachename)
@@ -96,52 +88,6 @@ void update_mru_tstamp(FILE *file, const char *name)
}
}
-static int clear_cache_cb(DIR *dir, const char *path, struct stat *st,
- void *data unused)
-{
- /* remove regular files */
- if (S_ISREG(st->st_mode))
- return unlinkat(dirfd(dir), path, 0);
-
- /* do nothing with other file types */
- return 0;
-}
-
-static int create_cache(aa_policy_cache *policy_cache, aa_features *features)
-{
- struct stat stat_file;
- autofclose FILE * f = NULL;
-
- if (aa_policy_cache_remove(policy_cache->path))
- goto error;
-
-create_file:
- if (aa_features_write_to_file(features,
- policy_cache->features_path) == -1)
- goto error;
-
- aa_features_unref(policy_cache->features);
- policy_cache->features = aa_features_ref(features);
- return 0;
-
-error:
- /* does the dir exist? */
- if (stat(policy_cache->path, &stat_file) == -1) {
- if (mkdir(policy_cache->path, 0700) == 0)
- goto create_file;
- PERROR("Can't create cache directory: %s\n",
- policy_cache->path);
- } else if (!S_ISDIR(stat_file.st_mode)) {
- PERROR("File in cache directory location: %s\n",
- policy_cache->path);
- } else {
- PERROR("Can't update cache directory: %s\n",
- policy_cache->path);
- }
-
- return -1;
-}
-
char *cache_filename(const char *cachedir, const char *basename)
{
char *cachename;
@@ -222,199 +168,3 @@ void install_cache(const char *cachetmpname, const char *cachename)
}
}
}
-
-static int init_cache_features(aa_policy_cache *policy_cache,
- aa_features *kernel_features, bool create)
-{
- if (aa_features_new(&policy_cache->features,
- policy_cache->features_path)) {
- policy_cache->features = NULL;
- if (!create || errno != ENOENT)
- return -1;
-
- return create_cache(policy_cache, kernel_features);
- }
-
- return 0;
-}
-
-struct replace_all_cb_data {
- aa_policy_cache *policy_cache;
- aa_kernel_interface *kernel_interface;
-};
-
-static int replace_all_cb(DIR *dir unused, const char *name, struct stat *st,
- void *cb_data)
-{
- int retval = 0;
-
- if (!S_ISDIR(st->st_mode) && !is_blacklisted(name, NULL)) {
- struct replace_all_cb_data *data;
- autofree char *path = NULL;
-
- data = (struct replace_all_cb_data *) cb_data;
- if (asprintf(&path, "%s/%s",
- data->policy_cache->path, name) < 0) {
- path = NULL;
- errno = ENOMEM;
- return -1;
- }
- retval = aa_kernel_interface_replace_policy_from_file(data->kernel_interface,
- path);
- }
-
- return retval;
-}
-
-/**
- * aa_policy_cache_new - create a new policy_cache from a path
- * @policy_cache: will point to the address of an allocated and initialized
- * aa_policy_cache_new object upon success
- * @kernel_features: features representing the currently running kernel
- * @path: path to the policy cache
- * @create: true if the cache should be created if it doesn't already exist
- *
- * Returns: 0 on success, -1 on error with errno set and *@policy_cache
- * pointing to NULL
- */
-int aa_policy_cache_new(aa_policy_cache **policy_cache,
- aa_features *kernel_features, const char *path,
- bool create)
-{
- aa_policy_cache *pc;
-
- *policy_cache = NULL;
-
- if (!path) {
- errno = EINVAL;
- return -1;
- }
-
- pc = (aa_policy_cache *) calloc(1, sizeof(*pc));
- if (!pc) {
- errno = ENOMEM;
- return -1;
- }
- aa_policy_cache_ref(pc);
-
- pc->path = strdup(path);
- if (!pc->path) {
- aa_policy_cache_unref(pc);
- errno = ENOMEM;
- return -1;
- }
-
- if (asprintf(&pc->features_path, "%s/.features", pc->path) == -1) {
- pc->features_path = NULL;
- aa_policy_cache_unref(pc);
- errno = ENOMEM;
- return -1;
- }
-
- if (init_cache_features(pc, kernel_features, create)) {
- int save = errno;
-
- aa_policy_cache_unref(pc);
- errno = save;
- return -1;
- }
-
- pc->kernel_features = aa_features_ref(kernel_features);
- *policy_cache = pc;
-
- return 0;
-}
-
-/**
- * aa_policy_cache_ref - increments the ref count of a policy_cache
- * @policy_cache: the policy_cache
- *
- * Returns: the policy_cache
- */
-aa_policy_cache *aa_policy_cache_ref(aa_policy_cache *policy_cache)
-{
- atomic_inc(&policy_cache->ref_count);
- return policy_cache;
-}
-
-/**
- * aa_policy_cache_unref - decrements the ref count and frees the policy_cache when 0
- * @policy_cache: the policy_cache (can be NULL)
- */
-void aa_policy_cache_unref(aa_policy_cache *policy_cache)
-{
- if (policy_cache && atomic_dec_and_test(&policy_cache->ref_count)) {
- free(policy_cache->features_path);
- free(policy_cache->path);
- free(policy_cache);
- }
-}
-
-/**
- * aa_policy_cache_is_valid - checks if the policy_cache is valid for the currently running kernel
- * @policy_cache: the policy_cache
- *
- * Returns: true if the policy_cache is valid for the currently running kernel,
- * false if not
- */
-bool aa_policy_cache_is_valid(aa_policy_cache *policy_cache)
-{
- return aa_features_is_equal(policy_cache->features,
- policy_cache->kernel_features);
-}
-
-/**
- * aa_policy_cache_create - creates a valid policy_cache for the currently running kernel
- * @policy_cache: the policy_cache
- *
- * Returns: 0 on success, -1 on error with errno set and features pointing to
- * NULL
- */
-int aa_policy_cache_create(aa_policy_cache *policy_cache)
-{
- return create_cache(policy_cache, policy_cache->kernel_features);
-}
-
-/**
- * aa_policy_cache_remove - removes all policy cache files under a path
- * @path: the path to a policy cache directory
- *
- * Returns: 0 on success, -1 on error with errno set
- */
-int aa_policy_cache_remove(const char *path)
-{
- return dirat_for_each(NULL, path, NULL, clear_cache_cb);
-}
-
-/**
- * aa_policy_cache_replace_all - performs a kernel policy replacement of all cached policies
- * @policy_cache: the policy_cache
- * @kernel_interface: the kernel interface to use when doing the replacement
- *
- * Returns: 0 on success, -1 on error with errno set and features pointing to
- * NULL
- */
-int aa_policy_cache_replace_all(aa_policy_cache *policy_cache,
- aa_kernel_interface *kernel_interface)
-{
- struct replace_all_cb_data cb_data;
- int retval;
-
- if (kernel_interface) {
- aa_kernel_interface_ref(kernel_interface);
- } else if (aa_kernel_interface_new(&kernel_interface,
- policy_cache->kernel_features,
- NULL) == -1) {
- kernel_interface = NULL;
- return -1;
- }
-
- cb_data.policy_cache = policy_cache;
- cb_data.kernel_interface = kernel_interface;
- retval = dirat_for_each(NULL, policy_cache->path, &cb_data,
- replace_all_cb);
-
- aa_kernel_interface_unref(kernel_interface);
-
- return retval;
-}
diff --git a/parser/policy_cache.h b/parser/policy_cache.h
index 6b222da..3c3e85d 100644
--- a/parser/policy_cache.h
+++ b/parser/policy_cache.h
@@ -19,8 +19,6 @@
#ifndef __AA_POLICY_CACHE_H
#define __AA_POLICY_CACHE_H
-#include "features.h"
-
extern struct timespec mru_tstamp;
/* returns true if time is more recent than mru_tstamp */
@@ -47,18 +45,4 @@ int cache_hit(const char *cachename);
int setup_cache_tmp(const char **cachetmpname, const char *cachename);
void install_cache(const char *cachetmpname, const char *cachename);
-typedef struct aa_policy_cache aa_policy_cache;
-
-int aa_policy_cache_new(aa_policy_cache **policy_cache,
- aa_features *kernel_features, const char *path,
- bool create);
-aa_policy_cache *aa_policy_cache_ref(aa_policy_cache *policy_cache);
-void aa_policy_cache_unref(aa_policy_cache *policy_cache);
-bool aa_policy_cache_is_valid(aa_policy_cache *policy_cache);
-int aa_policy_cache_create(aa_policy_cache *policy_cache);
-int aa_policy_cache_remove(const char *path);
-int aa_policy_cache_replace_all(aa_policy_cache *policy_cache,
- aa_kernel_interface *kernel_interface);
-
-
#endif /* __AA_POLICY_CACHE_H */
--
2.1.4
More information about the AppArmor
mailing list