File upstream-changes-2.10-r3385..3390.diff of Package apparmor
------------------------------------------------------------
revno: 3390
fixes bug: https://launchpad.net/bugs/1668892
committer: Tyler Hicks <tyhicks@canonical.com>
branch nick: apparmor-2.10
timestamp: Fri 2017-03-24 17:39:49 +0000
message:
utils: Add aa-remove-unknown utility to unload unknown profiles
https://launchpad.net/bugs/1668892
This patch creates a new utility, with the code previously used in the
init script 'restart' action, that removes unknown profiles which are
not found in /etc/apparmor.d/. The functionality was removed from the
common init script code in the fix for CVE-2017-6507.
The new utility prints a message containing the name of each unknown
profile before the profiles are removed. It also supports a dry run mode
so that an administrator can check which profiles will be removed before
unloading any unknown profiles.
If you backport this utility with the fix for CVE-2017-6507 to an
apparmor 2.10 release and your backported aa-remove-unknown utility is
sourcing the upstream rc.apparmor.functions file, you'll want to include
the following bug fix to prevent the aa-remove-unknown utility from
removing child profiles that it shouldn't remove:
r3440 - Fix: parser: incorrect output of child profile names
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
------------------------------------------------------------
revno: 3389
fixes bug: https://launchpad.net/bugs/1668892
committer: Tyler Hicks <tyhicks@canonical.com>
branch nick: apparmor-2.10
timestamp: Fri 2017-03-24 17:36:51 +0000
message:
parser: Preserve unknown profiles when restarting apparmor init/job/unit
CVE-2017-6507
https://launchpad.net/bugs/1668892
The common AppArmor 'restart' code used by some init scripts, upstart
jobs, and/or systemd units contained functionality that is no longer
appropriate to retain. Any profiles not found /etc/apparmor.d/ were
assumed to be obsolete and were unloaded. That behavior became
problematic now that there's a growing number of projects that maintain
their own internal set of AppArmor profiles outside of /etc/apparmor.d/.
It resulted in the AppArmor 'restart' code leaving some important
processes running unconfined. A couple examples are profiles managed by
LXD and Docker.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
------------------------------------------------------------
revno: 3388
committer: Seth Arnold <seth.arnold@canonical.com>
branch nick: 2.10
timestamp: Tue 2017-03-21 21:44:57 -0700
message:
parser: Fix delete after new[] -- patch from Oleg Strikov <oleg.strikov@gmail.com>
------------------------------------------------------------
revno: 3387
committer: Christian Boltz <apparmor@cboltz.de>
branch nick: 2.10
timestamp: Thu 2017-02-23 01:01:51 +0100
message:
Ignore change_hat events with error=-1 and "unconfined can not change_hat"
That's much better than crashing aa-logprof ;-) (use the log line in
the added testcase if you want to see the crash)
Reported by pfak on IRC.
Acked-by: Seth Arnold <seth.arnold@canonical.com> for trunk, 2.10 and 2.9.
------------------------------------------------------------
revno: 3386
committer: Christian Boltz <apparmor@cboltz.de>
branch nick: 2.10
timestamp: Tue 2017-02-21 18:47:43 +0100
message:
Remove re.LOCALE flag
Starting with python 3.6, the re.LOCALE flag can only be used with byte
patterns, and errors out if used with str. This patch removes the flag
in get_translated_hotkey().
References: https://bugs.launchpad.net/apparmor/+bug/1661766
Acked-by: Steve Beattie <steve@nxnw.org> for trunk, 2.10 and 2.9
------------------------------------------------------------
revno: 3385
committer: Steve Beattie <sbeattie@ubuntu.com>
branch nick: 2.10
timestamp: Wed 2017-02-01 21:44:40 -0800
message:
regression tests: fix environ fail case
merge from trunk commit revision 3630
In the environ regression test, when the exec() of the child process
fails, we don't report FAIL to stdout, so the regression tests consider
it an error rather than a failure and abort, short-circuiting the
test script.
This commit fixes this by emitting the FAIL message when the result
from the wait() syscall indicates the child process did not succeed.
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
=== added file 'libraries/libapparmor/testsuite/test_multi/unconfined-change_hat.err'
=== added file 'libraries/libapparmor/testsuite/test_multi/unconfined-change_hat.in'
--- libraries/libapparmor/testsuite/test_multi/unconfined-change_hat.in 1970-01-01 00:00:00 +0000
+++ libraries/libapparmor/testsuite/test_multi/unconfined-change_hat.in 2017-02-23 00:01:51 +0000
@@ -0,0 +1,1 @@
+Feb 21 23:22:01 mail-20170118 kernel: [1222198.459750] audit: type=1400 audit(1487719321.954:218): apparmor="ALLOWED" operation="change_hat" info="unconfined can not change_hat" error=-1 profile="unconfined" pid=19941 comm="apache2"
=== added file 'libraries/libapparmor/testsuite/test_multi/unconfined-change_hat.out'
--- libraries/libapparmor/testsuite/test_multi/unconfined-change_hat.out 1970-01-01 00:00:00 +0000
+++ libraries/libapparmor/testsuite/test_multi/unconfined-change_hat.out 2017-02-23 00:01:51 +0000
@@ -0,0 +1,12 @@
+START
+File: unconfined-change_hat.in
+Event type: AA_RECORD_ALLOWED
+Audit ID: 1487719321.954:218
+Operation: change_hat
+Profile: unconfined
+Command: apache2
+Info: unconfined can not change_hat
+ErrorCode: 1
+PID: 19941
+Epoch: 1487719321
+Audit subid: 218
=== added file 'libraries/libapparmor/testsuite/test_multi/unconfined-change_hat.profile'
--- libraries/libapparmor/testsuite/test_multi/unconfined-change_hat.profile 1970-01-01 00:00:00 +0000
+++ libraries/libapparmor/testsuite/test_multi/unconfined-change_hat.profile 2017-02-23 00:01:51 +0000
@@ -0,0 +1,2 @@
+profile unconfined {
+}
=== modified file 'parser/libapparmor_re/expr-tree.h'
--- parser/libapparmor_re/expr-tree.h 2015-10-14 20:49:26 +0000
+++ parser/libapparmor_re/expr-tree.h 2017-03-22 04:44:57 +0000
@@ -672,7 +672,7 @@
~hashedNodeVec()
{
- delete nodes;
+ delete [] nodes;
}
unsigned long size()const { return len; }
=== modified file 'parser/rc.apparmor.functions'
--- parser/rc.apparmor.functions 2012-02-24 12:21:59 +0000
+++ parser/rc.apparmor.functions 2017-03-24 17:36:51 +0000
@@ -451,34 +451,7 @@
configure_owlsm
parse_profiles reload
- # Clean out running profiles not associated with the current profile
- # set, excluding the libvirt dynamically generated profiles.
- # Note that we reverse sort the list of profiles to remove to
- # ensure that child profiles (e.g. hats) are removed before the
- # parent. We *do* need to remove the child profile and not rely
- # on removing the parent profile when the profile has had its
- # child profile names changed.
- profiles_names_list | awk '
-BEGIN {
- while (getline < "'${SFS_MOUNTPOINT}'/profiles" ) {
- str = sub(/ \((enforce|complain)\)$/, "", $0);
- if (match($0, /^libvirt-[0-9a-f\-]+$/) == 0)
- arr[$str] = $str
- }
-}
-
-{ if (length(arr[$0]) > 0) { delete arr[$0] } }
-
-END {
- for (key in arr)
- if (length(arr[key]) > 0) {
- printf("%s\n", arr[key])
- }
-}
-' | LC_COLLATE=C sort -r | while IFS= read profile ; do
- echo -n "$profile" > "$SFS_MOUNTPOINT/.remove"
- done
- # will not catch all errors, but still better than nothing
+
rc=$?
aa_log_end_msg $rc
return $rc
=== modified file 'tests/regression/apparmor/environ.c'
--- tests/regression/apparmor/environ.c 2010-12-20 20:29:10 +0000
+++ tests/regression/apparmor/environ.c 2017-02-02 05:44:40 +0000
@@ -63,6 +63,8 @@
if (retval == RET_CHLD_SUCCESS) {
printf("PASS\n");
retval = 0;
+ } else {
+ printf("FAIL: Child failed\n");
}
} else if (pid == 0) {
=== modified file 'utils/Makefile'
--- utils/Makefile 2015-11-18 20:29:25 +0000
+++ utils/Makefile 2017-03-24 17:39:49 +0000
@@ -24,7 +24,7 @@
PYTOOLS = aa-easyprof aa-genprof aa-logprof aa-cleanprof aa-mergeprof \
aa-autodep aa-audit aa-complain aa-enforce aa-disable \
aa-status aa-unconfined
-TOOLS = ${PERLTOOLS} ${PYTOOLS} aa-decode
+TOOLS = ${PERLTOOLS} ${PYTOOLS} aa-decode aa-remove-unknown
PYSETUP = python-tools-setup.py
PYMODULES = $(wildcard apparmor/*.py apparmor/rule/*.py)
=== added file 'utils/aa-remove-unknown'
--- utils/aa-remove-unknown 1970-01-01 00:00:00 +0000
+++ utils/aa-remove-unknown 2017-03-24 17:39:49 +0000
@@ -0,0 +1,108 @@
+#!/bin/sh
+# ----------------------------------------------------------------------
+# Copyright (c) 2017 Canonical Ltd. (All rights reserved)
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of version 2 of the GNU General Public
+# License published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# ----------------------------------------------------------------------
+
+APPARMOR_FUNCTIONS=/lib/apparmor/rc.apparmor.functions
+APPARMORFS=/sys/kernel/security/apparmor
+PROFILES="${APPARMORFS}/profiles"
+REMOVE="${APPARMORFS}/.remove"
+
+DRY_RUN=0
+
+. $APPARMOR_FUNCTIONS
+
+usage() {
+ local progname="$1"
+ local rc="$2"
+ local msg="usage: ${progname} [options]\n
+Remove profiles unknown to the system
+
+Options:
+ -h, --help Show this help message and exit
+ -n Dry run; don't remove profiles"
+
+ if [ "$rc" -ne 0 ] ; then
+ echo "$msg" 1>&2
+ else
+ echo "$msg"
+ fi
+
+ exit "$rc"
+}
+
+if [ "$#" -gt 1 ] ; then
+ usage "$0" 1
+elif [ "$#" -eq 1 ] ; then
+ if [ "$1" = "-h" -o "$1" = "--help" ] ; then
+ usage "$0" 0
+ elif [ "$1" = "-n" ] ; then
+ DRY_RUN=1
+ else
+ usage "$0" 1
+ fi
+fi
+
+
+# We can't use a -r test here because while $PROFILES is world-readable,
+# apparmorfs may still return EACCES from open()
+#
+# We have to do this check because error checking awk's getline() below is
+# tricky and, as is, results in an infinite loop when apparmorfs returns an
+# error from open().
+if ! IFS= read line < "$PROFILES" ; then
+ echo "ERROR: Unable to read apparmorfs profiles file" 1>&2
+ exit 1
+elif [ ! -w "$REMOVE" ] ; then
+ echo "ERROR: Unable to write to apparmorfs remove file" 1>&2
+ exit 1
+fi
+
+# Clean out running profiles not associated with the current profile
+# set, excluding the libvirt dynamically generated profiles.
+# Note that we reverse sort the list of profiles to remove to
+# ensure that child profiles (e.g. hats) are removed before the
+# parent. We *do* need to remove the child profile and not rely
+# on removing the parent profile when the profile has had its
+# child profile names changed.
+profiles_names_list | awk '
+BEGIN {
+ while (getline < "'${PROFILES}'" ) {
+ str = sub(/ \((enforce|complain)\)$/, "", $0);
+ if (match($0, /^libvirt-[0-9a-f\-]+$/) == 0)
+ arr[$str] = $str
+ }
+}
+
+{ if (length(arr[$0]) > 0) { delete arr[$0] } }
+
+END {
+ for (key in arr)
+ if (length(arr[key]) > 0) {
+ printf("%s\n", arr[key])
+ }
+}
+' | LC_COLLATE=C sort -r | \
+ while IFS= read profile ; do
+ if [ "$DRY_RUN" -ne 0 ]; then
+ echo "Would remove '${profile}'"
+ else
+ echo "Removing '${profile}'"
+ echo -n "$profile" > "${REMOVE}"
+ fi
+ done
+
+# will not catch all errors, but still better than nothing
+exit $?
=== added file 'utils/aa-remove-unknown.pod'
--- utils/aa-remove-unknown.pod 1970-01-01 00:00:00 +0000
+++ utils/aa-remove-unknown.pod 2017-03-24 17:39:49 +0000
@@ -0,0 +1,51 @@
+=pod
+
+=head1 NAME
+
+aa-remove-unknown - remove unknown AppArmor profiles
+
+=head1 SYNOPSIS
+
+B<aa-remove-unknown> [option]
+
+=head1 DESCRIPTION
+
+B<aa-remove-unknown> will inventory all profiles in /etc/apparmor.d/, compare
+that list to the profiles currently loaded into the kernel, and then remove all
+of the loaded profiles that were not found in /etc/apparmor.d/. It will also
+report the name of each profile that it removes on standard out.
+
+=head1 OPTIONS
+
+=over 4
+
+=item -h, --help
+
+displays a short usage statement.
+
+=item -n
+
+dry run; only prints the names of profiles that would be removed
+
+=back
+
+=head1 EXAMPLES
+
+ $ sudo ./aa-remove-unknown -n
+ Would remove 'test//null-/usr/bin/whoami'
+ Would remove 'test'
+
+ $ sudo ./aa-remove-unknown
+ Removing 'test//null-/usr/bin/whoami'
+ Removing 'test'
+
+=head1 BUGS
+
+None. Please report any you find to Launchpad at
+L<https://bugs.launchpad.net/apparmor/+filebug>.
+
+=head1 SEE ALSO
+
+apparmor(7)
+
+=cut
=== modified file 'utils/apparmor/logparser.py'
--- utils/apparmor/logparser.py 2016-12-06 21:29:39 +0000
+++ utils/apparmor/logparser.py 2017-02-23 00:01:51 +0000
@@ -231,6 +231,8 @@
if e['operation'] == 'change_hat':
if aamode != 'HINT' and aamode != 'PERMITTING':
return None
+ if e['error_code'] == 1 and e['info'] == 'unconfined can not change_hat':
+ return None
profile = e['name2']
#hat = None
if '//' in e['name2']:
=== modified file 'utils/apparmor/ui.py'
--- utils/apparmor/ui.py 2016-10-03 19:02:15 +0000
+++ utils/apparmor/ui.py 2017-02-21 17:47:43 +0000
@@ -64,8 +64,8 @@
msg = 'PromptUser: ' + _('Invalid hotkey for')
# Originally (\S) was used but with translations it would not work :(
- if re.search('\((\S+)\)', translated, re.LOCALE):
- return re.search('\((\S+)\)', translated, re.LOCALE).groups()[0]
+ if re.search('\((\S+)\)', translated):
+ return re.search('\((\S+)\)', translated).groups()[0]
else:
if cmsg:
raise AppArmorException(cmsg)
vim:ft=diff