[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