[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