[apparmor] [patch 22/24] Move feature handling code into its own file

john.johansen at canonical.com john.johansen at canonical.com
Fri Mar 7 17:31:43 UTC 2014


Signed-off-by: John Johansen <john.johansen at canonical.com>
---
 parser/Makefile      |    7 +
 parser/features.c    |  214 +++++++++++++++++++++++++++++++++++++++++++++++++++
 parser/features.h    |   22 +++++
 parser/parser_main.c |  192 ---------------------------------------------
 4 files changed, 241 insertions(+), 194 deletions(-)

--- 2.9-test.orig/parser/Makefile
+++ 2.9-test/parser/Makefile
@@ -80,9 +80,9 @@
        parser_main.c parser_misc.c parser_merge.c parser_symtab.c \
        parser_yacc.c parser_regex.c parser_variable.c parser_policy.c \
        parser_alias.c mount.c dbus.c lib.c profile.cc rule.c signal.c \
-       ptrace.c common_optarg.c
+       ptrace.c common_optarg.c features.c
 HDRS = parser.h parser_include.h immunix.h mount.h dbus.h lib.h profile.h \
-       rule.h signal.h ptrace.h common_optarg.h
+       rule.h signal.h ptrace.h common_optarg.h features.h
 TOOLS = apparmor_parser
 
 OBJECTS = $(SRCS:.c=.o)
@@ -238,6 +238,9 @@
 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 $@ $<
 
--- /dev/null
+++ 2.9-test/parser/features.c
@@ -0,0 +1,214 @@
+/*
+ *   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 "features.h"
+#include "lib.h"
+
+
+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);
+		if (!(file = openat(dirfd(dir), name, O_RDONLY))) {
+			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");
+	if (ms) {
+		char *match_string = (char *) malloc(1000);
+		if (!match_string)
+			goto no_match;
+		if (!fgets(match_string, 1000, ms)) {
+			free(match_string);
+			goto no_match;
+		}
+		if (strstr(match_string, " perms=c"))
+			perms_create = 1;
+		free(match_string);
+		kernel_supports_network = 1;
+		goto out;
+	}
+no_match:
+	perms_create = 1;
+
+out:
+	if (ms)
+		fclose(ms);
+}
+
+static void set_supported_features(void) {
+
+	/* has process_args() already assigned a match string? */
+	if (!features_string) {
+		if (load_features(FEATURES_FILE) == -1) {
+			set_features_by_match_file();
+			return;
+		}
+	}
+
+	perms_create = 1;
+
+	/* TODO: make this real parsing and config setting */
+	if (strstr(features_string, "file {"))	/* pre policydb is file= */
+		kernel_supports_policydb = 1;
+	if (strstr(features_string, "v6"))
+		kernel_abi_version = 6;
+	if (strstr(features_string, "network"))
+		kernel_supports_network = 1;
+	if (strstr(features_string, "mount"))
+		kernel_supports_mount = 1;
+	if (strstr(features_string, "dbus"))
+		kernel_supports_dbus = 1;
+	if (strstr(features_string, "signal"))
+		kernel_supports_signal = 1;
+	if (strstr(features_string, "ptrace {"))
+		kernel_supports_ptrace = 1;
+	if (strstr(features_string, "diff_encode"))
+		kernel_supports_diff_encode = 1;
+	else if (dfaflags & DFA_CONTROL_DIFF_ENCODE)
+		/* clear diff_encode because it is not supported */
+		dfaflags &= ~DFA_CONTROL_DIFF_ENCODE;
+}
--- /dev/null
+++ 2.9-test/parser/features.h
@@ -0,0 +1,22 @@
+/*
+ *   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
+
+#endif /* __AA_FEATURES_H */
--- 2.9-test.orig/parser/parser_main.c
+++ 2.9-test/parser/parser_main.c
@@ -514,198 +514,6 @@
 	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);
-		if (!(file = openat(dirfd(dir), name, O_RDONLY))) {
-			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");
-	if (ms) {
-		char *match_string = (char *) malloc(1000);
-		if (!match_string)
-			goto no_match;
-		if (!fgets(match_string, 1000, ms)) {
-			free(match_string);
-			goto no_match;
-		}
-		if (strstr(match_string, " perms=c"))
-			perms_create = 1;
-		free(match_string);
-		kernel_supports_network = 1;
-		goto out;
-	}
-no_match:
-	perms_create = 1;
-
-out:
-	if (ms)
-		fclose(ms);
-}
-
-static void set_supported_features(void) {
-
-	/* has process_args() already assigned a match string? */
-	if (!features_string) {
-		if (load_features(FEATURES_FILE) == -1) {
-			set_features_by_match_file();
-			return;
-		}
-	}
-
-	perms_create = 1;
-
-	/* TODO: make this real parsing and config setting */
-	if (strstr(features_string, "file {"))	/* pre policydb is file= */
-		kernel_supports_policydb = 1;
-	if (strstr(features_string, "v6"))
-		kernel_abi_version = 6;
-	if (strstr(features_string, "network"))
-		kernel_supports_network = 1;
-	if (strstr(features_string, "mount"))
-		kernel_supports_mount = 1;
-	if (strstr(features_string, "dbus"))
-		kernel_supports_dbus = 1;
-	if (strstr(features_string, "signal"))
-		kernel_supports_signal = 1;
-	if (strstr(features_string, "ptrace {"))
-		kernel_supports_ptrace = 1;
-	if (strstr(features_string, "diff_encode"))
-		kernel_supports_diff_encode = 1;
-	else if (dfaflags & DFA_CONTROL_DIFF_ENCODE)
-		/* clear diff_encode because it is not supported */
-		dfaflags &= ~DFA_CONTROL_DIFF_ENCODE;
-}
-
 int process_binary(int option, const char *profilename)
 {
 	char *buffer = NULL;




More information about the AppArmor mailing list