[apparmor] [PATCH v2 04/42] Move feature handling code into its own file
Tyler Hicks
tyhicks at canonical.com
Fri Mar 6 21:48:20 UTC 2015
From: John Johansen <john.johansen at canonical.com>
Signed-off-by: John Johansen <john.johansen at canonical.com>
[tyhicks: Forward ported patch to trunk]
[tyhicks: Don't move set_supported_features()]
[tyhicks: Don't move set_features_by_match_file()]
Signed-off-by: Tyler Hicks <tyhicks at canonical.com>
---
parser/Makefile | 8 ++-
parser/features.c | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++
parser/features.h | 31 +++++++++
parser/parser.h | 2 +
parser/parser_main.c | 144 +-----------------------------------------
5 files changed, 213 insertions(+), 145 deletions(-)
create mode 100644 parser/features.c
create mode 100644 parser/features.h
diff --git a/parser/Makefile b/parser/Makefile
index a300f6b..c6ee00d 100644
--- a/parser/Makefile
+++ b/parser/Makefile
@@ -75,9 +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
+ af_rule.cc af_unix.cc features.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
+ rule.h common_optarg.h signal.h ptrace.h network.h af_rule.h af_unix.h \
+ features.h
TOOLS = apparmor_parser
OBJECTS = $(patsubst %.cc, %.o, $(SRCS:.c=.o))
@@ -234,6 +235,9 @@ mount.o: mount.cc mount.h parser.h immunix.h rule.h
common_optarg.o: common_optarg.c common_optarg.h parser.h libapparmor_re/apparmor_re.h
$(CXX) $(EXTRA_CFLAGS) -c -o $@ $<
+features.o: features.c features.h parser.h libapparmor_re/apparmor_re.h
+ $(CXX) $(EXTRA_CFLAGS) -c -o $@ $<
+
lib.o: lib.c lib.h parser.h
$(CXX) $(EXTRA_CFLAGS) -c -o $@ $<
diff --git a/parser/features.c b/parser/features.c
new file mode 100644
index 0000000..d183365
--- /dev/null
+++ b/parser/features.c
@@ -0,0 +1,173 @@
+/*
+ * 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 <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <libintl.h>
+#include <locale.h>
+#define _(s) gettext(s)
+
+#include "features.h"
+#include "lib.h"
+#include "parser.h"
+
+#define FEATURES_STRING_SIZE 8192
+char *features_string = NULL;
+
+static char *snprintf_buffer(char *buf, char *pos, ssize_t size,
+ const char *fmt, ...)
+{
+ va_list args;
+ int i, remaining = size - (pos - buf);
+
+ va_start(args, fmt);
+ i = vsnprintf(pos, remaining, fmt, args);
+ va_end(args);
+
+ if (i >= size) {
+ PERROR(_("Feature buffer full."));
+ exit(1);
+ }
+
+ return pos + i;
+}
+
+struct features_struct {
+ char **buffer;
+ int size;
+ char *pos;
+};
+
+static int features_dir_cb(DIR *dir, const char *name, struct stat *st,
+ void *data)
+{
+ struct features_struct *fst = (struct features_struct *) data;
+
+ /* skip dot files and files with no name */
+ if (*name == '.' || !strlen(name))
+ return 0;
+
+ fst->pos = snprintf_buffer(*fst->buffer, fst->pos, fst->size, "%s {", name);
+
+ if (S_ISREG(st->st_mode)) {
+ int len, file;
+ int remaining = fst->size - (fst->pos - *fst->buffer);
+
+ file = openat(dirfd(dir), name, O_RDONLY);
+ if (file == -1) {
+ PDEBUG("Could not open '%s'", name);
+ return -1;
+ }
+ PDEBUG("Opened features \"%s\"\n", name);
+ if (st->st_size > remaining) {
+ PDEBUG("Feature buffer full.");
+ return -1;
+ }
+
+ do {
+ len = read(file, fst->pos, remaining);
+ if (len > 0) {
+ remaining -= len;
+ fst->pos += len;
+ *fst->pos = 0;
+ }
+ } while (len > 0);
+ if (len < 0) {
+ PDEBUG("Error reading feature file '%s'\n", name);
+ return -1;
+ }
+ close(file);
+ } else if (S_ISDIR(st->st_mode)) {
+ if (dirat_for_each(dir, name, fst, features_dir_cb))
+ return -1;
+ }
+
+ fst->pos = snprintf_buffer(*fst->buffer, fst->pos, fst->size, "}\n");
+
+ return 0;
+}
+
+static char *handle_features_dir(const char *filename, char **buffer, int size,
+ char *pos)
+{
+ struct features_struct fst = { buffer, size, pos };
+
+ if (dirat_for_each(NULL, filename, &fst, features_dir_cb)) {
+ PDEBUG("Failed evaluating %s\n", filename);
+ exit(1);
+ }
+
+ return fst.pos;
+}
+
+char *load_features_file(const char *name) {
+ char *buffer;
+ FILE *f = NULL;
+ size_t size;
+
+ f = fopen(name, "r");
+ if (!f)
+ return NULL;
+
+ buffer = (char *) malloc(FEATURES_STRING_SIZE);
+ if (!buffer)
+ goto fail;
+
+ size = fread(buffer, 1, FEATURES_STRING_SIZE - 1, f);
+ if (!size || ferror(f))
+ goto fail;
+ buffer[size] = 0;
+
+ fclose(f);
+ return buffer;
+
+fail:
+ int save = errno;
+ free(buffer);
+ if (f)
+ fclose(f);
+ errno = save;
+ return NULL;
+}
+
+int load_features(const char *name)
+{
+ struct stat stat_file;
+
+ if (stat(name, &stat_file) == -1)
+ return -1;
+
+ if (S_ISDIR(stat_file.st_mode)) {
+ /* if we have a features directory default to */
+ features_string = (char *) malloc(FEATURES_STRING_SIZE);
+ handle_features_dir(name, &features_string, FEATURES_STRING_SIZE, features_string);
+ } else {
+ features_string = load_features_file(name);
+ if (!features_string)
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/parser/features.h b/parser/features.h
new file mode 100644
index 0000000..201d8fc
--- /dev/null
+++ b/parser/features.h
@@ -0,0 +1,31 @@
+/*
+ * 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_FEATURES_H
+#define __AA_FEATURES_H
+
+#include "parser.h"
+
+#define FEATURES_FILE "/sys/kernel/security/" MODULE_NAME "/features"
+
+extern char *features_string;
+
+char *load_features_file(const char *name);
+int load_features(const char *name);
+
+#endif /* __AA_FEATURES_H */
diff --git a/parser/parser.h b/parser/parser.h
index daa6fe6..b3d4882 100644
--- a/parser/parser.h
+++ b/parser/parser.h
@@ -42,6 +42,8 @@ using namespace std;
class Profile;
class rule_t;
+#define MODULE_NAME "apparmor"
+
/* Global variable to pass token to lexer. Will be replaced by parameter
* when lexer and parser are made reentrant
*/
diff --git a/parser/parser_main.c b/parser/parser_main.c
index ba98a10..ac2fa44 100644
--- a/parser/parser_main.c
+++ b/parser/parser_main.c
@@ -40,18 +40,17 @@
#include <sys/apparmor.h>
#include "lib.h"
+#include "features.h"
#include "parser.h"
#include "parser_version.h"
#include "parser_include.h"
#include "common_optarg.h"
#include "libapparmor_re/apparmor_re.h"
-#define MODULE_NAME "apparmor"
#define OLD_MODULE_NAME "subdomain"
#define PROC_MODULES "/proc/modules"
#define DEFAULT_APPARMORFS "/sys/kernel/security/" MODULE_NAME
#define MATCH_FILE "/sys/kernel/security/" MODULE_NAME "/matching"
-#define FEATURES_FILE "/sys/kernel/security/" MODULE_NAME "/features"
#define MOUNTED_FS "/proc/mounts"
#define AADFA "pattern=aadfa"
@@ -80,14 +79,8 @@ int mru_skip_cache = 1;
int debug_cache = 0;
struct timespec mru_tstamp;
-#define FEATURES_STRING_SIZE 8192
-char *features_string = NULL;
char *cacheloc = NULL;
-/* per-profile settings */
-
-static int load_features(const char *name);
-
/* Make sure to update BOTH the short and long_options */
static const char *short_options = "adf:h::rRVvI:b:BCD:NSm:M:qQn:XKTWkL:O:po:";
struct option long_options[] = {
@@ -557,141 +550,6 @@ int have_enough_privilege(void)
return 0;
}
-char *snprintf_buffer(char *buf, char *pos, ssize_t size, const char *fmt, ...)
-{
- va_list args;
- int i, remaining = size - (pos - buf);
-
- va_start(args, fmt);
- i = vsnprintf(pos, remaining, fmt, args);
- va_end(args);
-
- if (i >= size) {
- PERROR(_("Feature buffer full."));
- exit(1);
- }
-
- return pos + i;
-}
-
-struct features_struct {
- char **buffer;
- int size;
- char *pos;
-};
-
-static int features_dir_cb(DIR *dir, const char *name, struct stat *st,
- void *data)
-{
- struct features_struct *fst = (struct features_struct *) data;
-
- /* skip dot files and files with no name */
- if (*name == '.' || !strlen(name))
- return 0;
-
- fst->pos = snprintf_buffer(*fst->buffer, fst->pos, fst->size, "%s {", name);
-
- if (S_ISREG(st->st_mode)) {
- int len, file;
- int remaining = fst->size - (fst->pos - *fst->buffer);
-
- file = openat(dirfd(dir), name, O_RDONLY);
- if (file == -1) {
- PDEBUG("Could not open '%s'", name);
- return -1;
- }
- PDEBUG("Opened features \"%s\"\n", name);
- if (st->st_size > remaining) {
- PDEBUG("Feature buffer full.");
- return -1;
- }
-
- do {
- len = read(file, fst->pos, remaining);
- if (len > 0) {
- remaining -= len;
- fst->pos += len;
- *fst->pos = 0;
- }
- } while (len > 0);
- if (len < 0) {
- PDEBUG("Error reading feature file '%s'\n", name);
- return -1;
- }
- close(file);
- } else if (S_ISDIR(st->st_mode)) {
- if (dirat_for_each(dir, name, fst, features_dir_cb))
- return -1;
- }
-
- fst->pos = snprintf_buffer(*fst->buffer, fst->pos, fst->size, "}\n");
-
- return 0;
-}
-
-static char *handle_features_dir(const char *filename, char **buffer, int size,
- char *pos)
-{
- struct features_struct fst = { buffer, size, pos };
-
- if (dirat_for_each(NULL, filename, &fst, features_dir_cb)) {
- PDEBUG("Failed evaluating %s\n", filename);
- exit(1);
- }
-
- return fst.pos;
-}
-
-static char *load_features_file(const char *name) {
- char *buffer;
- FILE *f = NULL;
- size_t size;
-
- f = fopen(name, "r");
- if (!f)
- return NULL;
-
- buffer = (char *) malloc(FEATURES_STRING_SIZE);
- if (!buffer)
- goto fail;
-
- size = fread(buffer, 1, FEATURES_STRING_SIZE - 1, f);
- if (!size || ferror(f))
- goto fail;
- buffer[size] = 0;
-
- fclose(f);
- return buffer;
-
-fail:
- int save = errno;
- free(buffer);
- if (f)
- fclose(f);
- errno = save;
- return NULL;
-}
-
-static int load_features(const char *name)
-{
- struct stat stat_file;
-
- if (stat(name, &stat_file) == -1)
- return -1;
-
- if (S_ISDIR(stat_file.st_mode)) {
- /* if we have a features directory default to */
- features_string = (char *) malloc(FEATURES_STRING_SIZE);
- handle_features_dir(name, &features_string, FEATURES_STRING_SIZE, features_string);
- } else {
- features_string = load_features_file(name);
- if (!features_string)
- return -1;
- }
-
- return 0;
-}
-
static void set_features_by_match_file(void)
{
FILE *ms = fopen(MATCH_FILE, "r");
--
2.1.4
More information about the AppArmor
mailing list