2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-22 10:07:12 +00:00

[4/7] libapparmor: fix available and enabled checks

Make it easier to separate errors from an actual answer, and ensure
we do a fallback check if there was an error.

Also fix the error code returned from aa_is_enabled() which got
broken by the addition of the private_enabled() check.

Finally make sure the private enabled error code is documented.

Fixes: https://gitlab.com/apparmor/apparmor/-/issues/150
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/713
Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
John Johansen 2021-03-17 05:18:05 -07:00
parent 3fb4c4b876
commit d0c4fc7d68
2 changed files with 28 additions and 16 deletions

View File

@ -70,6 +70,10 @@ AppArmor extensions to the system are not available.
AppArmor is available on the system but has been disabled at boot. AppArmor is available on the system but has been disabled at boot.
=item B<EBUSY>
AppArmor is available but only via private interfaces.
=item B<ENOENT> =item B<ENOENT>
AppArmor is available (and maybe even enforcing policy) but the interface is AppArmor is available (and maybe even enforcing policy) but the interface is

View File

@ -100,18 +100,18 @@ int aa_find_mountpoint(char **mnt)
int rc, fd; \ int rc, fd; \
fd = open("/sys/module/apparmor/parameters/" PARAM, O_RDONLY); \ fd = open("/sys/module/apparmor/parameters/" PARAM, O_RDONLY); \
if (fd == -1) { \ if (fd == -1) { \
rc = errno; \ rc = -errno; \
} else { \ } else { \
char buffer[2]; \ char buffer[2]; \
int size = read(fd, &buffer, 2); \ int size = read(fd, &buffer, 2); \
rc = errno; \ rc = -errno; \
close(fd); \ close(fd); \
errno = rc; \ errno = -rc; \
if (size > 0) { \ if (size > 0) { \
if (buffer[0] == 'Y') \ if (buffer[0] == 'Y') \
rc = 0; \ rc = 1; \
else \ else \
rc = ECANCELED; \ rc = 0; \
} \ } \
} \ } \
(rc); \ (rc); \
@ -130,14 +130,17 @@ static void param_check_enabled_init_once(void)
static int param_check_enabled() static int param_check_enabled()
{ {
if (pthread_once(&param_enabled_ctl, param_check_enabled_init_once) == 0) if (pthread_once(&param_enabled_ctl, param_check_enabled_init_once) == 0 && param_enabled >= 0)
return param_enabled; return param_enabled;
/* fallback if not initialized OR we recorded an error when
* initializing.
*/
return param_check_base("enabled"); return param_check_base("enabled");
} }
static int is_enabled(void) static int is_enabled(void)
{ {
return !param_check_enabled(); return param_check_enabled() == 1;
} }
static void param_check_private_enabled_init_once(void) static void param_check_private_enabled_init_once(void)
@ -147,14 +150,17 @@ static void param_check_private_enabled_init_once(void)
static int param_check_private_enabled() static int param_check_private_enabled()
{ {
if (pthread_once(&param_private_enabled_ctl, param_check_private_enabled_init_once) == 0) if (pthread_once(&param_private_enabled_ctl, param_check_private_enabled_init_once) == 0 && param_private_enabled >= 0)
return param_private_enabled; return param_private_enabled;
/* fallback if not initialized OR we recorded an error when
* initializing.
*/
return param_check_base("available"); return param_check_base("available");
} }
static int is_private_enabled(void) static int is_private_enabled(void)
{ {
return !param_check_private_enabled(); return param_check_private_enabled() == 1;
} }
/** /**
@ -174,15 +180,17 @@ int aa_is_enabled(void)
bool private = false; bool private = false;
rc = param_check_enabled(); rc = param_check_enabled();
if (rc) { if (rc < 1) {
if (rc == ENOENT) if (!is_private_enabled()) {
errno = ENOSYS; if (rc == 0)
else errno = ECANCELED;
errno = rc; else if (rc == -ENOENT)
errno = ENOSYS;
else
errno = -rc;
if (!is_private_enabled())
return 0; return 0;
}
/* actually available but only on private interfaces */ /* actually available but only on private interfaces */
private = true; private = true;
} }