mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-31 06:16:03 +00:00
Move feature handling code into its own file
Signed-off-by: John Johansen <john.johansen@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@canonical.com> Acked-by: Seth Arnold <seth.arnold@canonical.com>
This commit is contained in:
committed by
Tyler Hicks
parent
c85bca38f5
commit
4959e2e2a8
@@ -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");
|
||||
|
Reference in New Issue
Block a user