change_profile rules need a modifier to allow non-secureexec transitions
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
AppArmor |
Fix Released
|
High
|
Tyler Hicks | ||
apparmor (Ubuntu) |
Fix Released
|
High
|
Tyler Hicks | ||
Xenial |
Fix Released
|
High
|
Tyler Hicks |
Bug Description
[Impact]
Applications which use libapparmor's aa_change_onexec() to set up an AppArmor profile transition across an upcoming exec() cannot pre-initialize the environment. This is caused by AppArmor unconditionally setting the AT_SECURE flag on the process, causing libc to scrub the environment upon exec().
Upstream AppArmor and Yakkety now support policy language that allows the policy author to specify that the environment should not be scrubbed but the changes need to be SRU'ed to Ubuntu 16.04.
[Test Case]
The upstream changes include exhaustive tests for the new policy language keywords. Some of them are run at build time (the apparmor_parser tests) and all of them are run by QRT's test-apparmor.py (the apparmor_parser tests, the Python utility tests, and the kernel regression tests).
If a manual test is desired, see the original report below for steps.
[Regression Potential]
Regression potential is considerable since the fixes add new keywords to the policy language. No kernel changes are required, which mitigates some of the risk. Additionally, as mentioned above, the upstream changes include many new tests to ensure that regressions are not introduced.
[Original Report]
As it stands today, all exec transitions triggered by a change_profile rule cause the AT_SECURE flag in the auxiliary vector to be set due to the kernel function apparmor_
There should be a way to indicate, in the policy language, that AT_SECURE should not be triggered. This would be equivalent to the file rule type having the Px permission to trigger AT_SECURE and the px permission to not trigger it. The file rule type even has an 'unsafe' modifier keyword that could be reused as the change_profile modifier keyword.
Steps to show that AT_SECURE is being set:
# Build a test program to dump the AT_SECURE flag
$ cat <<EOF > print_at_secure.c
#include <stdio.h>
#include <sys/auxv.h>
int main(void)
{
printf("AT_SECURE = %lu\n", getauxval(
return 0;
}
EOF
$ gcc -o print_at_secure print_at_secure.c
# Load the test profile that allows all file accesses and any change_profile operations
$ echo "profile test { file, change_profile, }" | sudo apparmor_parser -qr
# Run bash under the test profile
$ aa-exec -p test -- bash
# Show the AT_SECURE is not set on exec
$ ./print_at_secure
AT_SECURE = 0
# Set up an exec transition (change_profile from the test profile back to the test profile)
$ echo "exec test" > /proc/self/
# See that AT_SECURE is now set on exec
$ ./print_at_secure
AT_SECURE = 1
$ exit
Steps to show that the new change_profile syntax allows AT_SECURE to remain
unset:
$ echo "profile test { file, change_profile unsafe /** -> *, }" | \
sudo apparmor_parser -qr
$ aa-exec -p test -- bash
$ ./print_at_secure
AT_SECURE = 0
$ echo "exec test" > /proc/self/
$ ./print_at_secure
AT_SECURE = 0
$ exit
Changed in apparmor: | |
assignee: | nobody → Tyler Hicks (tyhicks) |
importance: | Undecided → High |
status: | New → In Progress |
Changed in apparmor (Ubuntu): | |
status: | In Progress → Triaged |
tags: | added: aa-parser |
description: | updated |
Changed in apparmor (Ubuntu Xenial): | |
assignee: | nobody → Tyler Hicks (tyhicks) |
importance: | Undecided → High |
status: | New → In Progress |
description: | updated |
description: | updated |
description: | updated |
The tools also need to be updated (as soon as we decided on the exact syntax etc.)