[apparmor] [PATCH 4/6] libapparmor: Migrate aa_features API to openat() style
Tyler Hicks
tyhicks at canonical.com
Thu Mar 26 21:48:00 UTC 2015
Instead of only accepting a path in the aa_features API, accept a
directory file descriptor and a path like then openat() family of
syscalls. This type of interface is better since it can operate exactly
like a path-only interface, by passing AT_FDCWD or -1 as the dirfd.
However, using the dirfd/path combination, it can eliminate string
allocations needed to open files in subdirectories along with the
even more important benefits mentioned in the open(2) man page.
Signed-off-by: Tyler Hicks <tyhicks at canonical.com>
---
libraries/libapparmor/include/sys/apparmor.h | 5 +++--
libraries/libapparmor/src/features.c | 20 ++++++++++++--------
libraries/libapparmor/src/policy_cache.c | 4 ++--
parser/parser_main.c | 2 +-
4 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/libraries/libapparmor/include/sys/apparmor.h b/libraries/libapparmor/include/sys/apparmor.h
index 43d6efc..2643cde 100644
--- a/libraries/libapparmor/include/sys/apparmor.h
+++ b/libraries/libapparmor/include/sys/apparmor.h
@@ -105,14 +105,15 @@ extern int aa_query_label(uint32_t mask, char *query, size_t size, int *allow,
(aa_change_hat_vargs)(T, __macroarg_counter(X), X)
typedef struct aa_features aa_features;
-int aa_features_new(aa_features **features, const char *path);
+int aa_features_new(aa_features **features, int dirfd, const char *path);
int aa_features_new_from_string(aa_features **features,
const char *string, size_t size);
int aa_features_new_from_kernel(aa_features **features);
aa_features *aa_features_ref(aa_features *features);
void aa_features_unref(aa_features *features);
-int aa_features_write_to_file(aa_features *features, const char *path);
+int aa_features_write_to_file(aa_features *features,
+ int dirfd, const char *path);
bool aa_features_is_equal(aa_features *features1, aa_features *features2);
bool aa_features_supports(aa_features *features, const char *str);
diff --git a/libraries/libapparmor/src/features.c b/libraries/libapparmor/src/features.c
index 0bb90ee..12a708b 100644
--- a/libraries/libapparmor/src/features.c
+++ b/libraries/libapparmor/src/features.c
@@ -359,12 +359,13 @@ static bool walk_one(const char **str, const struct component *component,
* aa_features_new - create a new features based on a path
* @features: will point to the address of an allocated and initialized
* aa_features object upon success
+ * @dirfd: directory file descriptor or AT_FDCWD (see openat(2))
* @path: path to a features file or directory
*
* Returns: 0 on success, -1 on error with errno set and *@features pointing to
* NULL
*/
-int aa_features_new(aa_features **features, const char *path)
+int aa_features_new(aa_features **features, int dirfd, const char *path)
{
struct stat stat_file;
aa_features *f;
@@ -372,7 +373,7 @@ int aa_features_new(aa_features **features, const char *path)
*features = NULL;
- if (stat(path, &stat_file) == -1)
+ if (fstatat(dirfd, path, &stat_file, 0) == -1)
return -1;
f = calloc(1, sizeof(*f));
@@ -383,8 +384,8 @@ int aa_features_new(aa_features **features, const char *path)
aa_features_ref(f);
retval = S_ISDIR(stat_file.st_mode) ?
- load_features_dir(AT_FDCWD, path, f->string, STRING_SIZE) :
- load_features_file(AT_FDCWD, path, f->string, STRING_SIZE);
+ load_features_dir(dirfd, path, f->string, STRING_SIZE) :
+ load_features_file(dirfd, path, f->string, STRING_SIZE);
if (retval == -1) {
int save = errno;
@@ -443,7 +444,7 @@ int aa_features_new_from_string(aa_features **features,
*/
int aa_features_new_from_kernel(aa_features **features)
{
- return aa_features_new(features, FEATURES_FILE);
+ return aa_features_new(features, -1, FEATURES_FILE);
}
/**
@@ -471,19 +472,22 @@ void aa_features_unref(aa_features *features)
/**
* aa_features_write_to_file - write a string representation to a file
* @features: the features
+ * @dirfd: directory file descriptor or AT_FDCWD (see openat(2))
* @path: the path to write to
*
* Returns: 0 on success, -1 on error with errno set
*/
-int aa_features_write_to_file(aa_features *features, const char *path)
+int aa_features_write_to_file(aa_features *features,
+ int dirfd, const char *path)
{
autoclose int fd = -1;
size_t size;
ssize_t retval;
char *string;
- fd = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC | O_CLOEXEC,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ fd = openat(dirfd, path,
+ O_WRONLY | O_CREAT | O_TRUNC | O_SYNC | O_CLOEXEC,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (fd == -1)
return -1;
diff --git a/libraries/libapparmor/src/policy_cache.c b/libraries/libapparmor/src/policy_cache.c
index 22f84dd..515e2d0 100644
--- a/libraries/libapparmor/src/policy_cache.c
+++ b/libraries/libapparmor/src/policy_cache.c
@@ -56,7 +56,7 @@ static int create_cache(aa_policy_cache *policy_cache, aa_features *features)
goto error;
create_file:
- if (aa_features_write_to_file(features,
+ if (aa_features_write_to_file(features, -1,
policy_cache->features_path) == -1)
goto error;
@@ -85,7 +85,7 @@ error:
static int init_cache_features(aa_policy_cache *policy_cache,
aa_features *kernel_features, bool create)
{
- if (aa_features_new(&policy_cache->features,
+ if (aa_features_new(&policy_cache->features, -1,
policy_cache->features_path)) {
policy_cache->features = NULL;
if (!create || errno != ENOENT)
diff --git a/parser/parser_main.c b/parser/parser_main.c
index 1069e9d..428c3ea 100644
--- a/parser/parser_main.c
+++ b/parser/parser_main.c
@@ -397,7 +397,7 @@ static int process_arg(int c, char *optarg)
}
break;
case 'M':
- if (aa_features_new(&features, optarg)) {
+ if (aa_features_new(&features, AT_FDCWD, optarg)) {
fprintf(stderr,
"Failed to load features from '%s': %m\n",
optarg);
--
2.1.4
More information about the AppArmor
mailing list