2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-30 22:05:27 +00:00

parser: Finalize the aa_kernel_interface API

Create new, ref, and unref functions for aa_kernel_interface. The "new"
function allows for the caller to pass in an aa_features object that is
then used to check if the kernel supports set load operations.
Additionally, the "new" function allows for the apparmorfs path to be
discovered once instead of during every policy load.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
Tyler Hicks
2015-03-25 17:09:26 -05:00
parent f2154ca65d
commit 9aa29f4117
7 changed files with 226 additions and 103 deletions

View File

@@ -80,6 +80,7 @@ int mru_skip_cache = 1;
int debug_cache = 0;
struct timespec mru_tstamp;
static char *apparmorfs = NULL;
static char *cacheloc = NULL;
static aa_features *features = NULL;
@@ -362,7 +363,7 @@ static int process_arg(int c, char *optarg)
}
break;
case 'f':
subdomainbase = strndup(optarg, PATH_MAX);
apparmorfs = strndup(optarg, PATH_MAX);
break;
case 'D':
skip_read_cache = 1;
@@ -517,19 +518,6 @@ static int process_config_file(const char *name)
return 1;
}
int find_subdomainfs_mountpoint(void)
{
if (aa_find_iface_dir(&subdomainbase) == -1) {
PERROR(_("Warning: unable to find a suitable fs in %s, is it "
"mounted?\nUse --subdomainfs to override.\n"),
MOUNTED_FS);
return false;
}
return true;
}
int have_enough_privilege(void)
{
uid_t uid, euid;
@@ -603,7 +591,8 @@ static void set_supported_features(void)
dfaflags &= ~DFA_CONTROL_DIFF_ENCODE;
}
int process_binary(int option, const char *profilename)
int process_binary(int option, aa_kernel_interface *kernel_interface,
const char *profilename)
{
const char *printed_name;
int retval;
@@ -613,8 +602,8 @@ int process_binary(int option, const char *profilename)
if (kernel_load) {
if (option == OPTION_ADD) {
retval = profilename ?
aa_kernel_interface_load_policy_from_file(profilename) :
aa_kernel_interface_load_policy_from_fd(0);
aa_kernel_interface_load_policy_from_file(kernel_interface, profilename) :
aa_kernel_interface_load_policy_from_fd(kernel_interface, 0);
if (retval == -1) {
retval = errno;
PERROR(_("Error: Could not load profile %s: %s\n"),
@@ -623,8 +612,8 @@ int process_binary(int option, const char *profilename)
}
} else if (option == OPTION_REPLACE) {
retval = profilename ?
aa_kernel_interface_replace_policy_from_file(profilename) :
aa_kernel_interface_replace_policy_from_fd(0);
aa_kernel_interface_replace_policy_from_file(kernel_interface, profilename) :
aa_kernel_interface_replace_policy_from_fd(kernel_interface, 0);
if (retval == -1) {
retval = errno;
PERROR(_("Error: Could not replace profile %s: %s\n"),
@@ -685,7 +674,8 @@ int test_for_dir_mode(const char *basename, const char *linkdir)
return rc;
}
int process_profile(int option, const char *profilename, const char *cachedir)
int process_profile(int option, aa_kernel_interface *kernel_interface,
const char *profilename, const char *cachedir)
{
int retval = 0;
autofree const char *cachename = NULL;
@@ -757,7 +747,8 @@ int process_profile(int option, const char *profilename, const char *cachedir)
if (cachename) {
/* Load a binary cache if it exists and is newest */
if (cache_hit(cachename)) {
retval = process_binary(option, cachename);
retval = process_binary(option, kernel_interface,
cachename);
if (!retval || skip_bad_cache_rebuild)
return retval;
}
@@ -799,7 +790,7 @@ int process_profile(int option, const char *profilename, const char *cachedir)
}
/* cache file generated by load_policy */
retval = load_policy(option, cachetmp);
retval = load_policy(option, kernel_interface, cachetmp);
if (retval == 0 && write_cache) {
if (cachetmp == -1) {
unlink(cachetmpname);
@@ -815,6 +806,7 @@ out:
}
struct dir_cb_data {
aa_kernel_interface *kernel_interface;
const char *dirname; /* name of the parent dir */
const char *cachedir; /* path to the cache sub directory */
};
@@ -830,7 +822,8 @@ static int profile_dir_cb(DIR *dir unused, const char *name, struct stat *st,
autofree char *path = NULL;
if (asprintf(&path, "%s/%s", cb_data->dirname, name) < 0)
PERROR(_("Out of memory"));
rc = process_profile(option, path, cb_data->cachedir);
rc = process_profile(option, cb_data->kernel_interface, path,
cb_data->cachedir);
}
return rc;
}
@@ -846,7 +839,7 @@ static int binary_dir_cb(DIR *dir unused, const char *name, struct stat *st,
autofree char *path = NULL;
if (asprintf(&path, "%s/%s", cb_data->dirname, name) < 0)
PERROR(_("Out of memory"));
rc = process_binary(option, path);
rc = process_binary(option, cb_data->kernel_interface, path);
}
return rc;
}
@@ -868,6 +861,7 @@ static void setup_flags(void)
int main(int argc, char *argv[])
{
aa_kernel_interface *kernel_interface = NULL;
aa_policy_cache *policy_cache;
int retval, last_error;
int i;
@@ -891,16 +885,18 @@ int main(int argc, char *argv[])
return retval;
}
/* Check to make sure there is an interface to load policy */
if (!(UNPRIVILEGED_OPS) && (subdomainbase == NULL) &&
!find_subdomainfs_mountpoint()) {
return 1;
}
if (!binary_input) parse_default_paths();
setup_flags();
if (!(UNPRIVILEGED_OPS) &&
aa_kernel_interface_new(&kernel_interface, features, apparmorfs) == -1) {
PERROR(_("Warning: unable to find a suitable fs in %s, is it "
"mounted?\nUse --subdomainfs to override.\n"),
MOUNTED_FS);
return 1;
}
if ((!skip_cache && (write_cache || !skip_read_cache)) ||
force_clear_cache) {
if (!cacheloc && asprintf(&cacheloc, "%s/cache", basedir) == -1) {
@@ -979,9 +975,11 @@ int main(int argc, char *argv[])
profilename);
}
} else if (binary_input) {
retval = process_binary(option, profilename);
retval = process_binary(option, kernel_interface,
profilename);
} else {
retval = process_profile(option, profilename, cacheloc);
retval = process_profile(option, kernel_interface,
profilename, cacheloc);
}
if (profilename) free(profilename);