From: John Johansen <[email protected]>

Signed-off-by: John Johansen <[email protected]>
[tyhicks: Don't move globals in favor of lifting those out later]
Signed-off-by: Tyler Hicks <[email protected]>
---
 parser/Makefile       |  14 +++--
 parser/parser.h       |  16 +++++-
 parser/parser_lex.l   |   1 +
 parser/parser_main.c  | 123 +---------------------------------------
 parser/policy_cache.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++
 parser/policy_cache.h |  45 +++++++++++++++
 6 files changed, 221 insertions(+), 129 deletions(-)
 create mode 100644 parser/policy_cache.c
 create mode 100644 parser/policy_cache.h

diff --git a/parser/Makefile b/parser/Makefile
index c6ee00d..9175a30 100644
--- a/parser/Makefile
+++ b/parser/Makefile
@@ -75,10 +75,10 @@ SRCS = parser_common.c parser_include.c parser_interface.c 
parser_lex.c \
        parser_yacc.c parser_regex.c parser_variable.c parser_policy.c \
        parser_alias.c common_optarg.c lib.c network.c \
        mount.cc dbus.cc profile.cc rule.cc signal.cc ptrace.cc \
-       af_rule.cc af_unix.cc features.c
+       af_rule.cc af_unix.cc features.c policy_cache.c
 HDRS = parser.h parser_include.h immunix.h mount.h dbus.h lib.h profile.h \
        rule.h common_optarg.h signal.h ptrace.h network.h af_rule.h af_unix.h \
-       features.h
+       features.h policy_cache.h
 TOOLS = apparmor_parser
 
 OBJECTS = $(patsubst %.cc, %.o, $(SRCS:.c=.o))
@@ -115,7 +115,8 @@ TEST_OBJECTS = $(filter-out \
                        parser_lex.o \
                        parser_yacc.o \
                        common_optarg.o \
-                       parser_main.o, ${OBJECTS}) \
+                       parser_main.o \
+                       policy_cache.o, ${OBJECTS}) \
                $(AAREOBJECTS)
 TEST_LDFLAGS = $(AARE_LDFLAGS)
 
@@ -187,7 +188,7 @@ apparmor_parser: $(OBJECTS) $(AAREOBJECTS) $(LIBAPPARMOR_A)
 parser_yacc.c parser_yacc.h: parser_yacc.y parser.h profile.h
        $(YACC) $(YFLAGS) -o parser_yacc.c parser_yacc.y
 
-parser_lex.c: parser_lex.l parser_yacc.h parser.h profile.h mount.h dbus.h
+parser_lex.c: parser_lex.l parser_yacc.h parser.h profile.h mount.h dbus.h 
policy_cache.h
        $(LEX) ${LEXFLAGS} -o$@ $<
 
 parser_lex.o: parser_lex.c parser.h parser_yacc.h
@@ -199,7 +200,7 @@ parser_misc.o: parser_misc.c parser.h parser_yacc.h 
profile.h cap_names.h $(APPA
 parser_yacc.o: parser_yacc.c parser_yacc.h $(APPARMOR_H)
        $(CXX) $(EXTRA_CFLAGS) -c -o $@ $<
 
-parser_main.o: parser_main.c parser.h parser_version.h 
libapparmor_re/apparmor_re.h $(APPARMOR_H)
+parser_main.o: parser_main.c parser.h parser_version.h policy_cache.h 
libapparmor_re/apparmor_re.h $(APPARMOR_H)
        $(CXX) $(EXTRA_CFLAGS) -c -o $@ $<
 
 parser_interface.o: parser_interface.c parser.h profile.h 
libapparmor_re/apparmor_re.h
@@ -238,6 +239,9 @@ common_optarg.o: common_optarg.c common_optarg.h parser.h 
libapparmor_re/apparmo
 features.o: features.c features.h parser.h libapparmor_re/apparmor_re.h
        $(CXX) $(EXTRA_CFLAGS) -c -o $@ $<
 
+policy_cache.o: policy_cache.c policy_cache.h parser.h
+       $(CXX) $(EXTRA_CFLAGS) -c -o $@ $<
+
 lib.o: lib.c lib.h parser.h
        $(CXX) $(EXTRA_CFLAGS) -c -o $@ $<
 
diff --git a/parser/parser.h b/parser/parser.h
index b3d4882..12b8b86 100644
--- a/parser/parser.h
+++ b/parser/parser.h
@@ -318,9 +318,21 @@ extern void pwarn(const char *fmt, ...) 
__attribute__((__format__(__printf__, 1,
 
 /* from parser_main (cannot be used in tst builds) */
 extern int force_complain;
-extern struct timespec mru_tstamp;
-extern void update_mru_tstamp(FILE *file, const char *path);
 extern void display_version(void);
+extern int show_cache;
+extern int skip_cache;
+extern int skip_read_cache;
+extern int write_cache;
+extern int cond_clear_cache;
+extern int force_clear_cache;
+extern int create_cache_dir;
+extern int preprocess_only;
+extern int skip_mode_force;
+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_lex.l b/parser/parser_lex.l
index 749ee52..2f6f914 100644
--- a/parser/parser_lex.l
+++ b/parser/parser_lex.l
@@ -42,6 +42,7 @@
 #include "parser_include.h"
 #include "parser_yacc.h"
 #include "lib.h"
+#include "policy_cache.h"
 
 #ifdef PDEBUG
 #undef PDEBUG
diff --git a/parser/parser_main.c b/parser/parser_main.c
index ac2fa44..f075618 100644
--- a/parser/parser_main.c
+++ b/parser/parser_main.c
@@ -45,6 +45,7 @@
 #include "parser_version.h"
 #include "parser_include.h"
 #include "common_optarg.h"
+#include "policy_cache.h"
 #include "libapparmor_re/apparmor_re.h"
 
 #define OLD_MODULE_NAME "subdomain"
@@ -708,69 +709,6 @@ int test_for_dir_mode(const char *basename, const char 
*linkdir)
        return rc;
 }
 
-#define le16_to_cpu(x) ((uint16_t)(le16toh (*(uint16_t *) x)))
-
-const char header_string[] = "\004\010\000version\000\002";
-#define HEADER_STRING_SIZE 12
-static bool valid_cached_file_version(const char *cachename)
-{
-       char buffer[16];
-       FILE *f;
-       if (!(f = fopen(cachename, "r"))) {
-               PERROR(_("Error: Could not read cache file '%s', 
skipping...\n"), cachename);
-               return false;
-       }
-       size_t res = fread(buffer, 1, 16, f);
-       fclose(f);
-       if (res < 16) {
-               if (debug_cache)
-                       pwarn("%s: cache file '%s' invalid size\n", progname, 
cachename);
-               return false;
-       }
-
-       /* 12 byte header that is always the same and then 4 byte version # */
-       if (memcmp(buffer, header_string, HEADER_STRING_SIZE) != 0) {
-               if (debug_cache)
-                       pwarn("%s: cache file '%s' has wrong header\n", 
progname, cachename);
-               return false;
-       }
-
-       uint32_t version = cpu_to_le32(ENCODE_VERSION(force_complain,
-                                                     policy_version,
-                                                     parser_abi_version,
-                                                     kernel_abi_version));
-       if (memcmp(buffer + 12, &version, 4) != 0) {
-               if (debug_cache)
-                       pwarn("%s: cache file '%s' has wrong version\n", 
progname, cachename);
-               return false;
-       }
-
-       return true;
-}
-
-/* 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)
-
-void set_mru_tstamp(struct timespec t)
-{
-       mru_skip_cache = 0;
-       mru_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))
-               return;
-       if (mru_t_cmp(stat_file.st_mtim)) {
-               if (debug_cache)
-                       pwarn("%s: file '%s' is newer than cache file\n", 
progname, name);
-               mru_skip_cache = 1;
-       }
-}
-
 int process_profile(int option, const char *profilename)
 {
        struct stat stat_bin;
@@ -982,65 +920,6 @@ static int binary_dir_cb(DIR *dir unused, const char 
*name, struct stat *st,
        return rc;
 }
 
-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 clear_cache_files(const char *path)
-{
-       return dirat_for_each(NULL, path, NULL, clear_cache_cb);
-}
-
-static int create_cache(const char *cachedir, const char *path,
-                       const char *features)
-{
-       struct stat stat_file;
-       FILE * f = NULL;
-
-       if (clear_cache_files(cacheloc) != 0)
-               goto error;
-
-create_file:
-       f = fopen(path, "w");
-       if (f) {
-               if (fwrite(features, strlen(features), 1, f) != 1 )
-                       goto error;
-
-               fclose(f);
-
-
-               return 0;
-       }
-
-error:
-       /* does the dir exist? */
-       if (stat(cachedir, &stat_file) == -1 && create_cache_dir) {
-               if (mkdir(cachedir, 0700) == 0)
-                       goto create_file;
-               if (show_cache)
-                       PERROR(_("Can't create cache directory: %s\n"), 
cachedir);
-       } else if (!S_ISDIR(stat_file.st_mode)) {
-               if (show_cache)
-                       PERROR(_("File in cache directory location: %s\n"), 
cachedir);
-       } else {
-               if (show_cache)
-                       PERROR(_("Can't update cache directory: %s\n"), 
cachedir);
-       }
-
-       if (show_cache)
-               PERROR("Cache write disabled: cannot create %s\n", path);
-       write_cache = 0;
-
-       return -1;
-}
-
 static void setup_flags(void)
 {
        char *cache_features_path = NULL;
diff --git a/parser/policy_cache.c b/parser/policy_cache.c
new file mode 100644
index 0000000..f2909b9
--- /dev/null
+++ b/parser/policy_cache.c
@@ -0,0 +1,151 @@
+/*
+ *   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 <ctype.h>
+#include <dirent.h>
+#include <libintl.h>
+#include <locale.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#define _(s) gettext(s)
+
+#include "lib.h"
+#include "parser.h"
+#include "policy_cache.h"
+
+#define le16_to_cpu(x) ((uint16_t)(le16toh (*(uint16_t *) x)))
+
+const char header_string[] = "\004\010\000version\000\002";
+#define HEADER_STRING_SIZE 12
+bool valid_cached_file_version(const char *cachename)
+{
+       char buffer[16];
+       FILE *f;
+       if (!(f = fopen(cachename, "r"))) {
+               PERROR(_("Error: Could not read cache file '%s', 
skipping...\n"), cachename);
+               return false;
+       }
+       size_t res = fread(buffer, 1, 16, f);
+       fclose(f);
+       if (res < 16) {
+               if (debug_cache)
+                       pwarn("%s: cache file '%s' invalid size\n", progname, 
cachename);
+               return false;
+       }
+
+       /* 12 byte header that is always the same and then 4 byte version # */
+       if (memcmp(buffer, header_string, HEADER_STRING_SIZE) != 0) {
+               if (debug_cache)
+                       pwarn("%s: cache file '%s' has wrong header\n", 
progname, cachename);
+               return false;
+       }
+
+       uint32_t version = cpu_to_le32(ENCODE_VERSION(force_complain,
+                                                     policy_version,
+                                                     parser_abi_version,
+                                                     kernel_abi_version));
+       if (memcmp(buffer + 12, &version, 4) != 0) {
+               if (debug_cache)
+                       pwarn("%s: cache file '%s' has wrong version\n", 
progname, cachename);
+               return false;
+       }
+
+       return true;
+}
+
+
+void set_mru_tstamp(struct timespec t)
+{
+       mru_skip_cache = 0;
+       mru_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))
+               return;
+       if (mru_t_cmp(stat_file.st_mtim)) {
+               if (debug_cache)
+                       pwarn("%s: file '%s' is newer than cache file\n", 
progname, name);
+               mru_skip_cache = 1;
+       }
+}
+
+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;
+}
+
+int clear_cache_files(const char *path)
+{
+       return dirat_for_each(NULL, path, NULL, clear_cache_cb);
+}
+
+int create_cache(const char *cachedir, const char *path, const char *features)
+{
+       struct stat stat_file;
+       FILE * f = NULL;
+
+       if (clear_cache_files(cachedir) != 0)
+               goto error;
+
+create_file:
+       f = fopen(path, "w");
+       if (f) {
+               if (fwrite(features, strlen(features), 1, f) != 1 )
+                       goto error;
+
+               fclose(f);
+
+
+               return 0;
+       }
+
+error:
+       /* does the dir exist? */
+       if (stat(cachedir, &stat_file) == -1 && create_cache_dir) {
+               if (mkdir(cachedir, 0700) == 0)
+                       goto create_file;
+               if (show_cache)
+                       PERROR(_("Can't create cache directory: %s\n"), 
cachedir);
+       } else if (!S_ISDIR(stat_file.st_mode)) {
+               if (show_cache)
+                       PERROR(_("File in cache directory location: %s\n"), 
cachedir);
+       } else {
+               if (show_cache)
+                       PERROR(_("Can't update cache directory: %s\n"), 
cachedir);
+       }
+
+       if (show_cache)
+               PERROR("Cache write disabled: cannot create %s\n", path);
+       write_cache = 0;
+
+       return -1;
+}
diff --git a/parser/policy_cache.h b/parser/policy_cache.h
new file mode 100644
index 0000000..2b9a5dc
--- /dev/null
+++ b/parser/policy_cache.h
@@ -0,0 +1,45 @@
+/*
+ *   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.
+ */
+
+#ifndef __AA_POLICY_CACHE_H
+#define __AA_POLICY_CACHE_H
+
+extern struct timespec mru_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)
+
+extern int show_cache;
+extern int skip_cache;
+extern int skip_read_cache;
+extern int write_cache;
+extern int cond_clear_cache;           /* only applies if write is set */
+extern int force_clear_cache;          /* force clearing regargless of state */
+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 update_mru_tstamp(FILE *file, const char *path);
+bool valid_cached_file_version(const char *cachename);
+int clear_cache_files(const char *path);
+int create_cache(const char *cachedir, const char *path, const char *features);
+
+#endif /* __AA_POLICY_CACHE_H */
-- 
2.1.4


-- 
AppArmor mailing list
[email protected]
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor

Reply via email to