mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-04 08:24:42 +01:00
expose aa_features_check
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
This commit is contained in:
parent
3f46d96aca
commit
e7d4a509a7
4 changed files with 54 additions and 36 deletions
|
@ -157,6 +157,8 @@ extern int aa_features_write_to_file(aa_features *features,
|
|||
int dirfd, const char *path);
|
||||
extern bool aa_features_is_equal(aa_features *features1,
|
||||
aa_features *features2);
|
||||
extern int aa_features_check(int dirfd, const char *path,
|
||||
aa_features *features);
|
||||
extern bool aa_features_supports(aa_features *features, const char *str);
|
||||
extern char *aa_features_id(aa_features *features);
|
||||
extern char *aa_features_value(aa_features *features, const char *str, size_t *len);
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "PMurHash.h"
|
||||
|
||||
#define FEATURES_FILE "/sys/kernel/security/apparmor/features"
|
||||
#define CACHE_FEATURES_FILE ".features"
|
||||
|
||||
#define HASH_SIZE (8 + 1) /* 32 bits binary to hex + NUL terminator */
|
||||
#define STRING_SIZE 8192
|
||||
|
@ -656,6 +657,44 @@ bool aa_features_is_equal(aa_features *features1, aa_features *features2)
|
|||
strcmp(features1->string, features2->string) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* aa_features_check - check if features from a directory matches an aa_features object
|
||||
* @dirfd: a directory file descriptory or AT_FDCWD (see openat(2))
|
||||
* @path: the path containing the features
|
||||
* @features: features to be matched against
|
||||
*
|
||||
* Returns: 0 on success, -1 on failure. errno is set to EEXIST when there's not a match
|
||||
*/
|
||||
int aa_features_check(int dirfd, const char *path,
|
||||
aa_features *features)
|
||||
{
|
||||
aa_features *local_features = NULL;
|
||||
autofree char *name = NULL;
|
||||
bool rc;
|
||||
int len;
|
||||
|
||||
len = asprintf(&name, "%s/%s", path, CACHE_FEATURES_FILE);
|
||||
if (len == -1) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* verify that path dir .features matches */
|
||||
if (aa_features_new(&local_features, dirfd, name)) {
|
||||
PDEBUG("could not setup new features object for dirfd '%d' '%s'\n", dirfd, name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = aa_features_is_equal(local_features, features);
|
||||
aa_features_unref(local_features);
|
||||
if (!rc) {
|
||||
errno = EEXIST;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *features_lookup(aa_features *features, const char *str)
|
||||
{
|
||||
const char *features_string = features->string;
|
||||
|
|
|
@ -124,6 +124,13 @@ APPARMOR_3.0 {
|
|||
*;
|
||||
} APPARMOR_2.13.1;
|
||||
|
||||
APPARMOR_3.1 {
|
||||
global:
|
||||
aa_features_check;
|
||||
local:
|
||||
*;
|
||||
} APPARMOR_3.0;
|
||||
|
||||
PRIVATE {
|
||||
global:
|
||||
_aa_is_blacklisted;
|
||||
|
|
|
@ -145,36 +145,6 @@ repeat:
|
|||
return path;
|
||||
}
|
||||
|
||||
static int cache_check_features(int dirfd, const char *cache_name,
|
||||
aa_features *features)
|
||||
{
|
||||
aa_features *local_features = NULL;
|
||||
autofree char *name = NULL;
|
||||
bool rc;
|
||||
int len;
|
||||
|
||||
len = asprintf(&name, "%s/%s", cache_name, CACHE_FEATURES_FILE);
|
||||
if (len == -1) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* verify that cache dir .features matches */
|
||||
if (aa_features_new(&local_features, dirfd, name)) {
|
||||
PDEBUG("could not setup new features object for dirfd '%d' '%s'\n", dirfd, name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = aa_features_is_equal(local_features, features);
|
||||
aa_features_unref(local_features);
|
||||
if (!rc) {
|
||||
errno = EEXIST;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int create_cache(aa_policy_cache *policy_cache, aa_features *features)
|
||||
{
|
||||
if (aa_policy_cache_remove(policy_cache->dirfd[0], "."))
|
||||
|
@ -192,8 +162,8 @@ static int create_cache(aa_policy_cache *policy_cache, aa_features *features)
|
|||
static int init_cache_features(aa_policy_cache *policy_cache,
|
||||
aa_features *kernel_features, bool create)
|
||||
{
|
||||
if (cache_check_features(policy_cache->dirfd[0], ".",
|
||||
kernel_features)) {
|
||||
if (aa_features_check(policy_cache->dirfd[0], ".",
|
||||
kernel_features)) {
|
||||
/* EEXIST must come before ENOENT for short circuit eval */
|
||||
if (!create || errno == EEXIST || errno != ENOENT)
|
||||
return -1;
|
||||
|
@ -229,13 +199,13 @@ static int cache_miss_cb(int dirfd, const struct dirent *ent, void *arg)
|
|||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
if (!cache_check_features(dirfd, cache_name, data->features) || errno == ENOENT) {
|
||||
if (!aa_features_check(dirfd, cache_name, data->features) || errno == ENOENT) {
|
||||
/* found cache dir matching pattern */
|
||||
data->cache_name = cache_name;
|
||||
/* return 1 to stop iteration and signal dir found */
|
||||
return 1;
|
||||
} else if (errno != EEXIST) {
|
||||
PDEBUG("cache_check_features() failed for dirfd '%d' '%s'\n", dirfd, cache_name);
|
||||
PDEBUG("aa_features_check() failed for dirfd '%d' '%s'\n", dirfd, cache_name);
|
||||
free(cache_name);
|
||||
return -1;
|
||||
}
|
||||
|
@ -271,12 +241,12 @@ static int cache_dir_from_path_and_features(char **cache_path,
|
|||
if (len == -1)
|
||||
return -1;
|
||||
|
||||
if (!cache_check_features(dirfd, cache_dir, features) || errno == ENOENT) {
|
||||
if (!aa_features_check(dirfd, cache_dir, features) || errno == ENOENT) {
|
||||
PDEBUG("cache_dir_from_path_and_features() found '%s'\n", cache_dir);
|
||||
*cache_path = cache_dir;
|
||||
return 0;
|
||||
} else if (errno != EEXIST) {
|
||||
PDEBUG("cache_check_features() failed for dirfd '%d' %s\n", dirfd, cache_dir);
|
||||
PDEBUG("aa_features_check() failed for dirfd '%d' %s\n", dirfd, cache_dir);
|
||||
free(cache_dir);
|
||||
return -1;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue