On Fri, Mar 06, 2015 at 03:48:20PM -0600, Tyler Hicks wrote: > From: John Johansen <[email protected]> > > Signed-off-by: John Johansen <[email protected]> > [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 <[email protected]>
Acked-by: Seth Arnold <[email protected]> Thanks > --- > 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 > > > -- > AppArmor mailing list > [email protected] > Modify settings or unsubscribe at: > https://lists.ubuntu.com/mailman/listinfo/apparmor >
signature.asc
Description: Digital signature
-- AppArmor mailing list [email protected] Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor
