From 454b681e13d78795d4f98fda77d2788c2e54451914becb9485b5dae36170e06c Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sun, 26 Mar 2017 18:43:45 +0000 Subject: [PATCH 1/2] Accepting request 482764 from home:cboltz - add upstream-changes-r-3629..3648.diff: - preserve unknown profiles when reloading apparmor.service (CVE-2017-6507, lp#1668892, boo#1029696) - add aa-remove-unknown utility to unload unknown profiles (lp#1668892) - update nvidia abstraction for newer nvidia drivers - don't enforce ordering of dbus rule attributes in utils (lp#1628286) - add --parser, --base and --Include option to aa-easyprof to allow non-standard paths (useful for tests) (lp#1521031) - move initialization code in apparmor.aa to init_aa(). This allows to run all utils tests even if /etc/apparmor.d/ or /sbin/apparmor_parser don't exist. - several improvements in the utils tests - drop upstreamed python3-drop-re-locale.patch - no longer delete/skip some of the utils tests (to allow this, add parser-tests-dbus-duplicated-conditionals.diff) - add var.mount dependeny to apparmor.service (boo#1016259#c34) OBS-URL: https://build.opensuse.org/request/show/482764 OBS-URL: https://build.opensuse.org/package/show/security:apparmor/apparmor?expand=0&rev=174 --- apparmor.changes | 20 + apparmor.service | 2 +- apparmor.spec | 25 +- ...er-tests-dbus-duplicated-conditionals.diff | 20 + python3-drop-re-locale.patch | 15 - upstream-changes-r3629..3648.diff | 1736 +++++++++++++++++ 6 files changed, 1786 insertions(+), 32 deletions(-) create mode 100644 parser-tests-dbus-duplicated-conditionals.diff delete mode 100644 python3-drop-re-locale.patch create mode 100644 upstream-changes-r3629..3648.diff diff --git a/apparmor.changes b/apparmor.changes index 0baf52a..660621b 100644 --- a/apparmor.changes +++ b/apparmor.changes @@ -1,3 +1,23 @@ +------------------------------------------------------------------- +Sat Mar 25 21:42:10 UTC 2017 - suse-beta@cboltz.de + +- add upstream-changes-r-3629..3648.diff: + - preserve unknown profiles when reloading apparmor.service + (CVE-2017-6507, lp#1668892, boo#1029696) + - add aa-remove-unknown utility to unload unknown profiles (lp#1668892) + - update nvidia abstraction for newer nvidia drivers + - don't enforce ordering of dbus rule attributes in utils (lp#1628286) + - add --parser, --base and --Include option to aa-easyprof to allow + non-standard paths (useful for tests) (lp#1521031) + - move initialization code in apparmor.aa to init_aa(). This allows to + run all utils tests even if /etc/apparmor.d/ or /sbin/apparmor_parser + don't exist. + - several improvements in the utils tests +- drop upstreamed python3-drop-re-locale.patch +- no longer delete/skip some of the utils tests (to allow this, add + parser-tests-dbus-duplicated-conditionals.diff) +- add var.mount dependeny to apparmor.service (boo#1016259#c34) + ------------------------------------------------------------------- Thu Mar 16 20:13:00 UTC 2017 - kukuk@suse.com diff --git a/apparmor.service b/apparmor.service index 27911c1..891e40b 100644 --- a/apparmor.service +++ b/apparmor.service @@ -3,7 +3,7 @@ Description=Load AppArmor profiles DefaultDependencies=no Before=sysinit.target After=systemd-journald-audit.socket -After=var-lib.mount +After=var.mount var-lib.mount ConditionSecurity=apparmor [Service] diff --git a/apparmor.spec b/apparmor.spec index ac2bc29..71c3076 100644 --- a/apparmor.spec +++ b/apparmor.spec @@ -75,8 +75,11 @@ Patch8: sshd-profile-drop-local-include-r3615.diff # upstream changes (trunk r3616..3628) Patch9: upstream-changes-r3616..3628.diff -# drop deprecated re.LOCALE flag from regexps -Patch10: python3-drop-re-locale.patch +# upstream changes (trunk r3629..3648) +Patch10: upstream-changes-r3629..3648.diff + +# add some exceptions to utils/test/test-parser-simple-tests.py (submitted upstream 2017-03-25) +Patch11: parser-tests-dbus-duplicated-conditionals.diff PreReq: sed BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -377,9 +380,10 @@ SubDomain. %patch7 -p1 %patch8 %patch9 -%if %{with python3} -%patch10 -p1 -%endif +%patch10 +# patch10 (upstream-changes-r3629..3648.diff) fails to create empty files, do it manually +touch libraries/libapparmor/testsuite/test_multi/unconfined-change_hat.err +%patch11 # search for left-over multiline rules test -z "$(grep -r '^\s*\(unix\|dbus\)[^,]\(([^)]*)\)*[^,]*$' profiles/apparmor.d/)" @@ -457,17 +461,6 @@ make check -C binutils # also, check-parser breaks if using 'make -C' (but works if cd'ing into the directory) (cd profiles && make check-parser) -# these tests fail if /etc/apparmor.d/abstractions/* or /sbin/apparmor_parser don't exist -# (aa.py doesn't allow to inject in-tree paths early enough) -rm -v utils/test/test-aa.py -rm -v utils/test/test-aa-easyprof.py -rm -v utils/test/test-libapparmor-test_multi.py -rm -v utils/test/test-mount_parse.py -rm -v utils/test/test-parser-simple-tests.py -rm -v utils/test/test-pivot_root_parse.py -rm -v utils/test/test-regex_matches.py -rm -v utils/test/test-unix_parse.py - make check -C utils %install diff --git a/parser-tests-dbus-duplicated-conditionals.diff b/parser-tests-dbus-duplicated-conditionals.diff new file mode 100644 index 0000000..f8c25d2 --- /dev/null +++ b/parser-tests-dbus-duplicated-conditionals.diff @@ -0,0 +1,20 @@ +=== modified file 'utils/test/test-parser-simple-tests.py' +--- utils/test/test-parser-simple-tests.py 2017-03-03 12:14:03 +0000 ++++ utils/test/test-parser-simple-tests.py 2017-03-25 20:45:42 +0000 +@@ -49,6 +49,15 @@ + 'change_profile/onx_conflict_unsafe1.sd', + 'change_profile/onx_conflict_unsafe2.sd', + ++ # duplicated conditionals aren't detected by the tools ++ 'generated_dbus/duplicated-conditionals-45127.sd', ++ 'generated_dbus/duplicated-conditionals-45131.sd', ++ 'generated_dbus/duplicated-conditionals-45124.sd', ++ 'generated_dbus/duplicated-conditionals-45130.sd', ++ 'generated_dbus/duplicated-conditionals-45125.sd', ++ 'generated_dbus/duplicated-conditionals-45128.sd', ++ 'generated_dbus/duplicated-conditionals-45129.sd', ++ + 'dbus/bad_modifier_2.sd', + 'dbus/bad_regex_01.sd', + 'dbus/bad_regex_02.sd', + diff --git a/python3-drop-re-locale.patch b/python3-drop-re-locale.patch deleted file mode 100644 index f85636a..0000000 --- a/python3-drop-re-locale.patch +++ /dev/null @@ -1,15 +0,0 @@ -Index: apparmor-2.11.0/utils/apparmor/ui.py -=================================================================== ---- apparmor-2.11.0.orig/utils/apparmor/ui.py -+++ apparmor-2.11.0/utils/apparmor/ui.py -@@ -64,8 +64,8 @@ def get_translated_hotkey(translated, cm - 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) diff --git a/upstream-changes-r3629..3648.diff b/upstream-changes-r3629..3648.diff new file mode 100644 index 0000000..5476893 --- /dev/null +++ b/upstream-changes-r3629..3648.diff @@ -0,0 +1,1736 @@ +------------------------------------------------------------ +revno: 3648 +fixes bug: https://launchpad.net/bugs/1668892 +committer: Tyler Hicks +branch nick: apparmor +timestamp: Fri 2017-03-24 05:08:01 +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 + Acked-by: Seth Arnold + Acked-by: John Johansen +------------------------------------------------------------ +revno: 3647 +fixes bug: https://launchpad.net/bugs/1668892 +committer: Tyler Hicks +branch nick: apparmor +timestamp: Fri 2017-03-24 05:06:07 +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 + Acked-by: Seth Arnold + Acked-by: John Johansen +------------------------------------------------------------ +revno: 3646 +committer: Seth Arnold +branch nick: apparmor +timestamp: Tue 2017-03-21 12:09:59 -0700 +message: + parser: Fix delete after new[] -- patch from Oleg Strikov +------------------------------------------------------------ +revno: 3645 [merge] +committer: Tyler Hicks +branch nick: apparmor +timestamp: Thu 2017-03-16 02:51:03 +0000 +message: + profiles: Update nvidia abstraction for newer nvidia drivers + + Signed-off-by: Tyler Hicks + Acked-by: Jamie Strandboge +------------------------------------------------------------ +revno: 3644 +committer: Christian Boltz +branch nick: apparmor +timestamp: Fri 2017-03-03 13:14:55 +0100 +message: + Fix regressions caused by init_aa() + + With the init_aa() patch series commited, minitools_test.py showed + several test failures - which effectively means the -d option of + aa-complain, aa-cleanprof etc. was broken. + + These failures were caused by + - calling init_aa() too late in tools.py - _after_ setting the + profiledir, which then got overwritten by init_aa() + - calling init_aa() twice (because apparmor.aa gets imported in two + modules used by aa-cleanprof), which overwrote the manually set values + on the second run + + This patch fixes the call order in tools.py and adds a check to + init_aa() so that it only runs once and ignores additional calls. + + + Acked-by: Tyler Hicks + Acked-by: Seth Arnold +------------------------------------------------------------ +revno: 3643 +committer: Christian Boltz +branch nick: apparmor +timestamp: Fri 2017-03-03 13:14:03 +0100 +message: + test-parser-simple-tests.py: No longer skip testing generated_perms_leading profiles + + FileRule understands leading permissions, so the reason to skip those + (generated) test profiles in test-parser-simple-tests.py is gone. + + However, the gen-xtrans.pl script generates profiles with a not-so-valid + mix of uppercase and lowercase, for example "Pux" and "Cux". The parser + accepts this, but the tools complain about such rules. Therefore add the + affected profiles to the exception list. + + In total, this means we now test 319 of the 380 generated_perms_leading + test profiles. + + The patch also moves some lines around to get the \-escaped profiles + out of the mixed uppercase/lowercase exec rule section. + + + Acked-by: Seth Arnold +------------------------------------------------------------ +revno: 3642 +committer: Tyler Hicks +branch nick: apparmor +timestamp: Thu 2017-03-02 21:25:01 +0000 +message: + utils: Fix apparmor.easyprof import in test-aa-easyprof.py + + The test-aa-easyprof.py script was attempting to do its own special + setup to import the in-tree easyprof module. However, this proved to be + very flaky and resulted in the test periodically failing due to an + AttributeError the first time easyprof.parse_args() was called. + + This patch removes the flakiness by trusting that PYTHONPATH is set up + appropriately before the test script is ran. PYTHONPATH is already + initialized appropriately by utils/test/Makefile according to the + USE_SYSTEM make variable. + + Signed-off-by: Tyler Hicks + Acked-by: Seth Arnold + Acked-by: Christian Boltz +------------------------------------------------------------ +revno: 3641 +committer: Tyler Hicks +branch nick: apparmor +timestamp: Thu 2017-03-02 21:24:33 +0000 +message: + utils: Set parser executable path according to USE_SYSTEM make variable + + if USE_SYSTEM is not set, the utils make check target will instruct + test-aa-easyprof.py to provide the path of the in-tree parser executable + to aa-easyprof. + + If USE_SYSTEM is set, the default parser path (/sbin/apparmor_parser or + the result of `which apparmor_parser`) is used. + + The test-aa-easyprof.py script receives the parser path by checking the + __AA_PARSER environment variable. This environment variable is strictly + used by the test script and not any user-facing code so two leading + underscores were used. + + Signed-off-by: Tyler Hicks + Acked-by: Christian Boltz + Acked-by: Seth Arnold +------------------------------------------------------------ +revno: 3640 +committer: Tyler Hicks +branch nick: apparmor +timestamp: Thu 2017-03-02 21:24:05 +0000 +message: + utils: Add option to aa-easyprof to specify the apparmor_parser path + + When testing against a clean system without the apparmor_parser binary + installed, the test-aa-easyprof.py script ends up skipping profile + verification because it can't find the parser binary. This even causes a + test failure due to the test_genpolicy_invalid_template_policy test. + + Adding a --parser option to aa-easyprof is the first step in addressing + this problem. + + Signed-off-by: Tyler Hicks + Acked-by: Christian Boltz + Acked-by: Seth Arnold +------------------------------------------------------------ +revno: 3639 +committer: Tyler Hicks +branch nick: apparmor +timestamp: Thu 2017-03-02 21:23:32 +0000 +message: + utils: Set parser base path according to USE_SYSTEM make variable + + If USE_SYSTEM is not set, the utils make check target will instruct + test-aa-easyprof.py to provide the path of the in-tree + profiles/apparmor.d directory to aa-easyprof as the parser base + directory. + + If USE_SYSTEM is set, the default base directory (/etc/apparmor.d) is + used. + + The test-aa-easyprof.py script receives the base path by checking the + __AA_BASEDIR environment variable. This environment variable is strictly + used by the test script and not any user-facing code so two leading + underscores were used. + + Signed-off-by: Tyler Hicks + Acked-by: Christian Boltz + Acked-by: Seth Arnold +------------------------------------------------------------ +revno: 3638 +fixes bug: https://launchpad.net/bugs/1521031 +committer: Tyler Hicks +branch nick: apparmor +timestamp: Thu 2017-03-02 21:22:57 +0000 +message: + utils: Accept parser base and include options in aa-easyprof + + https://launchpad.net/bugs/1521031 + + aa-easyprof accepts a list of abstractions to include and, by default, + execs apparmor_parser to verify the generated profile including any + abstractions. However, aa-easyprof didn't provide the same flexibility + as apparmor_parser when it came to where in the filesystem the + abstraction files could exist. + + The parser supports --base (defaulting to /etc/apparmor.d) and --Include + (defaulting to unset) options to specify the search paths for + abstraction files. This patch adds the same options to aa-easyprof to + aide in two different situations: + + 1) Some Ubuntu packages use aa-easyprof to generate AppArmor profiles + at build time. Something that has been previously needed is a way + for those packages to ship their own abstractions file(s) that are + #included in the easyprof-generated profile. That's not been + possible since the abstraction file(s) have not yet been installed + during the package build. + + 2) The test-aa-easyprof.py script contains some tests that specify + abstractions that should be #included. Without the ability to + specify a different --base or --Include directory, the abstractions + were required to be present in /etc/apparmor.d/abstractions/ or the + tests would fail. This prevents the Python utils from being able to + strictly test against in-tree code/profiles/etc. + + I don't like the names of the command line options --base and --Include. + They're not particularly descriptive and the capital 'I' is not user + friendly. However, I decided to preserve the name of the options from + apparmor_parser. + + Signed-off-by: Tyler Hicks + Acked-by: Christian Boltz + Acked-by: Seth Arnold +------------------------------------------------------------ +revno: 3637 +committer: Tyler Hicks +branch nick: apparmor +timestamp: Thu 2017-03-02 21:21:53 +0000 +message: + utils: Require apparmor.aa users to call init_aa() + + Introduce an apparmor.aa.init_aa() method and move the initialization + code of the apparmor.aa module into it. Note that this change will break + any external users of apparmor.aa because global variables that were + previously initialized when importing apparmor.aa will not be + initialized unless a call to the new apparmor.aa.init_aa() method is + made. + + The main purpose of this change is to allow the utils tests to be able + to set a non-default location for configuration files. Instead of + hard-coding the location of logprof.conf and other utils related + configuration files to /etc/apparmor/, this patch allows it to be + configured by calling apparmor.aa.init_aa(confdir=PATH). + + This allows for the make check target to use the in-tree config file, + profiles, and parser by default. A helper method, setup_aa(), is added + to common_test.py that checks for an environment variable containing a + non-default configuration directory path prior to calling + apparmor.aa.init_aa(). All test scripts that use apparmor.aa are updated + to call setup_aa(). + + Signed-off-by: Tyler Hicks + Suggested-by: Christian Boltz + Acked-by: Seth Arnold + Acked-by: Christian Boltz +------------------------------------------------------------ +revno: 3636 +committer: Tyler Hicks +branch nick: apparmor +timestamp: Thu 2017-03-02 21:21:21 +0000 +message: + utils: Update the logprof.conf in the test dir to point to in-tree paths + + The utils tests should make use of the logprof.conf that resides in + utils/test/ when testing against the in-tree parser and profiles. When + testing against the system, it the utils tests should continue to use + the system logprof.conf. + + This patch updates the parser and profiles paths to point to the in-tree + paths. Another patch is needed to get aa.py to honor a non-hardcoded + search path for logprof.conf and other configuration files. + + Signed-off-by: Tyler Hicks + Acked-by: Christian Boltz + Acked-by: Seth Arnold +------------------------------------------------------------ +revno: 3635 +committer: Tyler Hicks +branch nick: apparmor +timestamp: Thu 2017-03-02 21:20:45 +0000 +message: + utils: Improve error messages when profiles/parser is not found + + When aa.py is imported, it looks for a set of profiles and it also looks + for the parser. Both of these paths are configured by logprof.conf but + it isn't always obvious which logprof.conf file was used and, therefore, + it isn't always obvious where aa.py is looking. This patch includes the + paths in the error messages. + + Signed-off-by: Tyler Hicks + Acked-by: Christian Boltz + Acked-by: Seth Arnold +------------------------------------------------------------ +revno: 3634 +fixes bug: https://launchpad.net/bugs/1628286 +committer: Tyler Hicks +branch nick: apparmor +timestamp: Tue 2017-02-28 23:04:24 +0000 +message: + utils: Don't enforce ordering of dbus rule attributes + + https://launchpad.net/bugs/1628286 + + The utils were enforcing that the dbus rule attributes were strictly + ordered in the following fashion: + + bus -> path -> interface -> member -> peer + + However, the parser has always accepted the attributes in any order. If + the system contained a profile which did not use the strict ordering + enforced by the utils, the utils would refuse to operate at all. + + This patch eases the restriction on the ordering at the expense of the + utils no longer being able to detect and reject a single attribute that + is repeated multiple times. In that situation, only the last occurrence + of the attribute will be honored by the utils. + + Signed-off-by: Tyler Hicks + Acked-by: Christian Boltz +------------------------------------------------------------ +revno: 3633 +committer: Tyler Hicks +branch nick: apparmor +timestamp: Tue 2017-02-28 23:03:25 +0000 +message: + utils: Fix failing tests in test-aa.py + + The merged /usr patches to the policy broke some utils tests due to a + change in the expected output. + + Fixes: r3600 update lots of profiles for usrMerge + Signed-off-by: Tyler Hicks + Acked-by: Christian Boltz + Acked-by: Seth Arnold +------------------------------------------------------------ +revno: 3632 +committer: Christian Boltz +branch nick: apparmor +timestamp: Thu 2017-02-23 01:00:36 +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 for trunk, 2.10 and 2.9. +------------------------------------------------------------ +revno: 3631 +committer: Christian Boltz +branch nick: apparmor +timestamp: Tue 2017-02-21 18:46:36 +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 for trunk, 2.10 and 2.9 +------------------------------------------------------------ +revno: 3630 +committer: Steve Beattie +branch nick: apparmor +timestamp: Wed 2017-02-01 21:41:52 -0800 +message: + regression tests: fix environ fail case + + 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 + Acked-by: Seth Arnold +------------------------------------------------------------ +revno: 3629 +committer: Christian Boltz +branch nick: apparmor +timestamp: Mon 2017-01-30 20:48:50 +0100 +message: + Rename global variable "pid" to "log_pid" + + aa.py has a global variable "pid", but it also has several functions + that use "pid" as a local variable name. do_logprof_pass() even uses + both - first, it passes the global variable to ReadLog, and then it + creates a local variable in the "for pid in ..." loop. + + This patch renames the global variable to log_pid to get rid of the + confusion. + + Note that the global variable is only handed over to ReadLog, and the + only case where its previous content _might_ be used is aa-genprof which + does multipe do_logprof_pass() runs. + + Maybe we could even get rid of this variable in aa.py and make it local + to the ReadLog class, but I'm not sure if that would affect aa-genprof + in interesting[tm] ways. + + + Acked-by: John Johansen +------------------------------------------------------------ +Use --include-merged or -n0 to see merged revisions. + + +=== 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:00:36 +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:00:36 +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:00:36 +0000 +@@ -0,0 +1,2 @@ ++profile unconfined { ++} + +=== modified file 'parser/libapparmor_re/expr-tree.h' +--- parser/libapparmor_re/expr-tree.h 2016-01-19 23:07:04 +0000 ++++ parser/libapparmor_re/expr-tree.h 2017-03-21 19:09:59 +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 05:06:07 +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 'profiles/apparmor.d/abstractions/nvidia' +--- profiles/apparmor.d/abstractions/nvidia 2014-06-06 18:50:58 +0000 ++++ profiles/apparmor.d/abstractions/nvidia 2017-03-06 18:59:43 +0000 +@@ -8,8 +8,9 @@ + /etc/vdpau_wrapper.cfg r, + + # device files +- /dev/nvidia0 rw, +- /dev/nvidiactl rw, ++ /dev/nvidiactl rw, ++ /dev/nvidia-modeset rw, ++ /dev/nvidia[0-9]* rw, + + @{PROC}/interrupts r, + @{PROC}/sys/vm/max_map_count r, +@@ -18,3 +19,5 @@ + + owner @{HOME}/.nv/GLCache/ r, + owner @{HOME}/.nv/GLCache/** rwk, ++ ++ unix (send, receive) type=dgram peer=(addr="@nvidia[0-9a-f]*"), + +=== 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:41:52 +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 2016-12-10 18:25:31 +0000 ++++ utils/Makefile 2017-03-24 05:08:01 +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) + + +=== modified file 'utils/aa-easyprof.pod' +--- utils/aa-easyprof.pod 2015-03-27 21:33:35 +0000 ++++ utils/aa-easyprof.pod 2017-03-02 21:24:05 +0000 +@@ -57,6 +57,12 @@ + AppArmor rules or policies. They are similar to AppArmor abstractions, but + usually encompass more policy rules. + ++=item --parser PATH ++ ++Specify the PATH of the apparmor_parser binary to use when verifying ++policy. If this option is not specified, aa-easyprof will attempt to ++locate the path starting with /sbin/apparmor_parser. ++ + =item -a ABSTRACTIONS, --abstractions=ABSTRACTIONS + + Specify ABSTRACTIONS as a comma-separated list of AppArmor abstractions. It is +@@ -64,6 +70,16 @@ + convenience. AppArmor abstractions are located in /etc/apparmor.d/abstractions. + See apparmor.d(5) for details. + ++=item -b PATH, --base=PATH ++ ++Set the base PATH for resolving abstractions specified by --abstractions. ++See the same option in apparmor_parser(8) for details. ++ ++=item -I PATH, --Include=PATH ++ ++Add PATH to the search paths used for resolving abstractions specified by ++--abstractions. See the same option in apparmor_parser(8) for details. ++ + =item -r PATH, --read-path=PATH + + Specify a PATH to allow owner reads. May be specified multiple times. If the + +=== modified file 'utils/aa-genprof' +--- utils/aa-genprof 2016-10-01 18:57:09 +0000 ++++ utils/aa-genprof 2017-03-02 21:21:53 +0000 +@@ -66,6 +66,7 @@ + profiling = args.program + profiledir = args.dir + ++apparmor.init_aa() + apparmor.set_logfile(args.file) + + aa_mountpoint = apparmor.check_for_apparmor() + +=== modified file 'utils/aa-logprof' +--- utils/aa-logprof 2016-10-01 18:57:09 +0000 ++++ utils/aa-logprof 2017-03-02 21:21:53 +0000 +@@ -34,6 +34,7 @@ + profiledir = args.dir + logmark = args.mark or '' + ++apparmor.init_aa() + apparmor.set_logfile(args.file) + + aa_mountpoint = apparmor.check_for_apparmor() + +=== modified file 'utils/aa-mergeprof' +--- utils/aa-mergeprof 2017-01-19 15:54:47 +0000 ++++ utils/aa-mergeprof 2017-03-02 21:21:53 +0000 +@@ -43,6 +43,8 @@ + + args.other = None + ++apparmor.aa.init_aa() ++ + profiles = args.files + + profiledir = args.dir + +=== added file 'utils/aa-remove-unknown' +--- utils/aa-remove-unknown 1970-01-01 00:00:00 +0000 ++++ utils/aa-remove-unknown 2017-03-24 05:08:01 +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 . ++# ---------------------------------------------------------------------- ++ ++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 05:08:01 +0000 +@@ -0,0 +1,51 @@ ++=pod ++ ++=head1 NAME ++ ++aa-remove-unknown - remove unknown AppArmor profiles ++ ++=head1 SYNOPSIS ++ ++B [option] ++ ++=head1 DESCRIPTION ++ ++B 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. ++ ++=head1 SEE ALSO ++ ++apparmor(7) ++ ++=cut + +=== modified file 'utils/aa-unconfined' +--- utils/aa-unconfined 2016-12-30 20:22:58 +0000 ++++ utils/aa-unconfined 2017-03-02 21:21:53 +0000 +@@ -40,6 +40,7 @@ + + paranoid = args.paranoid + ++aa.init_aa() + aa_mountpoint = aa.check_for_apparmor() + if not aa_mountpoint: + raise aa.AppArmorException(_("It seems AppArmor was not started. Please enable AppArmor and try again.")) + +=== modified file 'utils/apparmor/aa.py' +--- utils/apparmor/aa.py 2017-01-20 00:20:41 +0000 ++++ utils/apparmor/aa.py 2017-03-03 12:14:55 +0000 +@@ -73,14 +73,14 @@ + # Setup logging incase of debugging is enabled + debug_logger = DebugLogger('aa') + +-CONFDIR = '/etc/apparmor' +- + # The database for severity + sev_db = None + # The file to read log messages from + ### Was our + logfile = None + ++CONFDIR = None ++conf = None + cfg = None + repo_cfg = None + +@@ -105,7 +105,7 @@ + extras = hasher() # Inactive profiles from extras + ### end our + log = [] +-pid = dict() ++log_pid = dict() # handed over to ReadLog, gets filled in logparser.py. The only case the previous content of this variable _might_(?) be used is aa-genprof (multiple do_logprof_pass() runs) + + profile_changes = hasher() + prelog = hasher() +@@ -1857,7 +1857,7 @@ + elif os.path.isdir(logfile): + raise AppArmorException(_('%s is a directory. Please specify a file as logfile') % logfile) + +-def do_logprof_pass(logmark='', passno=0, pid=pid): ++def do_logprof_pass(logmark='', passno=0, log_pid=log_pid): + # set up variables for this pass + # transitions = hasher() + global log +@@ -1885,7 +1885,7 @@ + ## if not repo_cfg['repository'].get('enabled', False) or repo_cfg['repository]['enabled'] not in ['yes', 'no']: + ## UI_ask_to_enable_repo() + +- log_reader = apparmor.logparser.ReadLog(pid, logfile, existing_profiles, profile_dir, log) ++ log_reader = apparmor.logparser.ReadLog(log_pid, logfile, existing_profiles, profile_dir, log) + log = log_reader.read_log(logmark) + #read_log(logmark) + +@@ -3741,24 +3741,36 @@ + + ######Initialisations###### + +-conf = apparmor.config.Config('ini', CONFDIR) +-cfg = conf.read_config('logprof.conf') +- +-# prevent various failures if logprof.conf doesn't exist +-if not cfg.sections(): +- cfg.add_section('settings') +- cfg.add_section('required_hats') +- +-if cfg['settings'].get('default_owner_prompt', False): +- cfg['settings']['default_owner_prompt'] = '' +- +-profile_dir = conf.find_first_dir(cfg['settings'].get('profiledir')) or '/etc/apparmor.d' +-if not os.path.isdir(profile_dir): +- raise AppArmorException('Can\'t find AppArmor profiles') +- +-extra_profile_dir = conf.find_first_dir(cfg['settings'].get('inactive_profiledir')) or '/usr/share/apparmor/extra-profiles/' +- +-parser = conf.find_first_file(cfg['settings'].get('parser')) or '/sbin/apparmor_parser' +-if not os.path.isfile(parser) or not os.access(parser, os.EX_OK): +- raise AppArmorException('Can\'t find apparmor_parser') ++def init_aa(confdir="/etc/apparmor"): ++ global CONFDIR ++ global conf ++ global cfg ++ global profile_dir ++ global extra_profile_dir ++ global parser ++ ++ if CONFDIR: ++ return # config already initialized (and possibly changed afterwards), so don't overwrite the config variables ++ ++ CONFDIR = confdir ++ conf = apparmor.config.Config('ini', CONFDIR) ++ cfg = conf.read_config('logprof.conf') ++ ++ # prevent various failures if logprof.conf doesn't exist ++ if not cfg.sections(): ++ cfg.add_section('settings') ++ cfg.add_section('required_hats') ++ ++ if cfg['settings'].get('default_owner_prompt', False): ++ cfg['settings']['default_owner_prompt'] = '' ++ ++ profile_dir = conf.find_first_dir(cfg['settings'].get('profiledir')) or '/etc/apparmor.d' ++ if not os.path.isdir(profile_dir): ++ raise AppArmorException('Can\'t find AppArmor profiles in %s' % (profile_dir)) ++ ++ extra_profile_dir = conf.find_first_dir(cfg['settings'].get('inactive_profiledir')) or '/usr/share/apparmor/extra-profiles/' ++ ++ parser = conf.find_first_file(cfg['settings'].get('parser')) or '/sbin/apparmor_parser' ++ if not os.path.isfile(parser) or not os.access(parser, os.EX_OK): ++ raise AppArmorException('Can\'t find apparmor_parser at %s' % (parser)) + + +=== modified file 'utils/apparmor/cleanprofile.py' +--- utils/apparmor/cleanprofile.py 2016-10-01 17:54:48 +0000 ++++ utils/apparmor/cleanprofile.py 2017-03-02 21:21:53 +0000 +@@ -16,6 +16,7 @@ + + class Prof(object): + def __init__(self, filename): ++ apparmor.init_aa() + self.aa = apparmor.aa + self.filelist = apparmor.filelist + self.include = apparmor.include + +=== modified file 'utils/apparmor/easyprof.py' +--- utils/apparmor/easyprof.py 2015-03-28 12:16:22 +0000 ++++ utils/apparmor/easyprof.py 2017-03-02 21:24:05 +0000 +@@ -259,14 +259,11 @@ + return orig + + +-def verify_policy(policy): ++def verify_policy(policy, exe, base=None, include=None): + '''Verify policy compiles''' +- exe = "/sbin/apparmor_parser" +- if not os.path.exists(exe): +- rc, exe = cmd(['which', 'apparmor_parser']) +- if rc != 0: +- warn("Could not find apparmor_parser. Skipping verify") +- return True ++ if not exe: ++ warn("Could not find apparmor_parser. Skipping verify") ++ return True + + fn = "" + # if policy starts with '/' and is one line, assume it is a path +@@ -279,7 +276,14 @@ + os.write(f, policy) + os.close(f) + +- rc, out = cmd([exe, '-QTK', fn]) ++ command = [exe, '-QTK'] ++ if base: ++ command.extend(['-b', base]) ++ if include: ++ command.extend(['-I', include]) ++ command.append(fn) ++ ++ rc, out = cmd(command) + os.unlink(fn) + if rc == 0: + return True +@@ -302,6 +306,22 @@ + if os.path.isfile(self.conffile): + self._get_defaults() + ++ self.parser_path = '/sbin/apparmor_parser' ++ if opt.parser_path: ++ self.parser_path = opt.parser_path ++ elif not os.path.exists(self.parser_path): ++ rc, self.parser_path = cmd(['which', 'apparmor_parser']) ++ if rc != 0: ++ self.parser_path = None ++ ++ self.parser_base = "/etc/apparmor.d" ++ if opt.parser_base: ++ self.parser_base = opt.parser_base ++ ++ self.parser_include = None ++ if opt.parser_include: ++ self.parser_include = opt.parser_include ++ + if opt.templates_dir and os.path.isdir(opt.templates_dir): + self.dirs['templates'] = os.path.abspath(opt.templates_dir) + elif not opt.templates_dir and \ +@@ -350,8 +370,6 @@ + if not 'policygroups' in self.dirs: + raise AppArmorException("Could not find policygroups directory") + +- self.aa_topdir = "/etc/apparmor.d" +- + self.binary = binary + if binary: + if not valid_binary_path(binary): +@@ -506,9 +524,15 @@ + + def gen_abstraction_rule(self, abstraction): + '''Generate an abstraction rule''' +- p = os.path.join(self.aa_topdir, "abstractions", abstraction) +- if not os.path.exists(p): +- raise AppArmorException("%s does not exist" % p) ++ base = os.path.join(self.parser_base, "abstractions", abstraction) ++ if not os.path.exists(base): ++ if not self.parser_include: ++ raise AppArmorException("%s does not exist" % base) ++ ++ include = os.path.join(self.parser_include, "abstractions", abstraction) ++ if not os.path.exists(include): ++ raise AppArmorException("Neither %s nor %s exist" % (base, include)) ++ + return "#include " % abstraction + + def gen_variable_declaration(self, dec): +@@ -661,7 +685,7 @@ + + if no_verify: + debug("Skipping policy verification") +- elif not verify_policy(policy): ++ elif not verify_policy(policy, self.parser_path, self.parser_base, self.parser_include): + msg("\n" + policy) + raise AppArmorException("Invalid policy") + +@@ -804,6 +828,10 @@ + + def add_parser_policy_args(parser): + '''Add parser arguments''' ++ parser.add_option("--parser", ++ dest="parser_path", ++ help="The path to the profile parser used for verification", ++ metavar="PATH") + parser.add_option("-a", "--abstractions", + action="callback", + callback=check_for_manifest_arg, +@@ -811,6 +839,14 @@ + dest="abstractions", + help="Comma-separated list of abstractions", + metavar="ABSTRACTIONS") ++ parser.add_option("-b", "--base", ++ dest="parser_base", ++ help="Set the base directory for resolving abstractions", ++ metavar="DIR") ++ parser.add_option("-I", "--Include", ++ dest="parser_include", ++ help="Add a directory to the search path when resolving abstractions", ++ metavar="DIR") + parser.add_option("--read-path", + action="callback", + callback=check_for_manifest_arg_append, + +=== modified file 'utils/apparmor/logparser.py' +--- utils/apparmor/logparser.py 2016-12-06 21:24:56 +0000 ++++ utils/apparmor/logparser.py 2017-02-23 00:00:36 +0000 +@@ -243,6 +243,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/rule/dbus.py' +--- utils/apparmor/rule/dbus.py 2016-10-01 18:08:10 +0000 ++++ utils/apparmor/rule/dbus.py 2017-02-28 23:04:24 +0000 +@@ -37,14 +37,16 @@ + RE_FLAG = '(?P<%s>(\S+|"[^"]+"|\(\s*\S+\s*\)|\(\s*"[^"]+"\)\s*))' # string without spaces, or quoted string, optionally wrapped in (...). %s is the match group name + # plaintext version: | * | "* " | ( * ) | ( " * " ) | + ++# XXX this regex will allow repeated parameters, last one wins ++# XXX (the parser will reject such rules) + RE_DBUS_DETAILS = re.compile( + '^' + + '(\s+(?P' + RE_ACCESS_KEYWORDS + '))?' + # optional access keyword(s) +- '(\s+(bus\s*=\s*' + RE_FLAG % 'bus' + '))?' + # optional bus= system | session | AARE, (...) optional +- '(\s+(path\s*=\s*' + RE_FLAG % 'path' + '))?' + # optional path=AARE, (...) optional +- '(\s+(name\s*=\s*' + RE_FLAG % 'name' + '))?' + # optional name=AARE, (...) optional +- '(\s+(interface\s*=\s*' + RE_FLAG % 'interface' + '))?' + # optional interface=AARE, (...) optional +- '(\s+(member\s*=\s*' + RE_FLAG % 'member' + '))?' + # optional member=AARE, (...) optional ++ '((\s+(bus\s*=\s*' + RE_FLAG % 'bus' + '))?|' + # optional bus= system | session | AARE, (...) optional ++ '(\s+(path\s*=\s*' + RE_FLAG % 'path' + '))?|' + # optional path=AARE, (...) optional ++ '(\s+(name\s*=\s*' + RE_FLAG % 'name' + '))?|' + # optional name=AARE, (...) optional ++ '(\s+(interface\s*=\s*' + RE_FLAG % 'interface' + '))?|' + # optional interface=AARE, (...) optional ++ '(\s+(member\s*=\s*' + RE_FLAG % 'member' + '))?|' + # optional member=AARE, (...) optional + '(\s+(peer\s*=\s*\((,|\s)*' + # optional peer=( name=AARE and/or label=AARE ), (...) required + '(' + + '(' + '(,|\s)*' + ')' + # empty peer=() +@@ -57,7 +59,7 @@ + '|' # or + '(' + 'label\s*=\s*' + RE_PROFILE_NAME % 'peerlabel3' + '(,|\s)+' + 'name\s*=\s*' + RE_PROFILE_NAME % 'peername3' + ')' + # peer label + name (match name peername3/peerlabel3) + ')' +- '(,|\s)*\)))?' ++ '(,|\s)*\)))?){0,6}' + '\s*$') + + + +=== modified file 'utils/apparmor/tools.py' +--- utils/apparmor/tools.py 2015-06-06 12:31:03 +0000 ++++ utils/apparmor/tools.py 2017-03-03 12:14:55 +0000 +@@ -24,6 +24,8 @@ + + class aa_tools: + def __init__(self, tool_name, args): ++ apparmor.init_aa() ++ + self.name = tool_name + self.profiledir = args.dir + self.profiling = args.program + +=== modified file 'utils/apparmor/ui.py' +--- utils/apparmor/ui.py 2016-10-03 19:01:29 +0000 ++++ utils/apparmor/ui.py 2017-02-21 17:46:36 +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) + +=== modified file 'utils/test/Makefile' +--- utils/test/Makefile 2016-05-10 12:31:25 +0000 ++++ utils/test/Makefile 2017-03-02 21:24:33 +0000 +@@ -23,11 +23,17 @@ + ifdef USE_SYSTEM + LD_LIBRARY_PATH= + PYTHONPATH= ++ CONFDIR= ++ BASEDIR= ++ PARSER= + else + # PYTHON_DIST_BUILD_PATH based on libapparmor/swig/python/test/Makefile.am + PYTHON_DIST_BUILD_PATH = ../../libraries/libapparmor/swig/python/build/$$($(PYTHON) -c "import distutils.util; import platform; print(\"lib.%s-%s\" %(distutils.util.get_platform(), platform.python_version()[:3]))") + LD_LIBRARY_PATH=../../libraries/libapparmor/src/.libs/ + PYTHONPATH=..:$(PYTHON_DIST_BUILD_PATH) ++ CONFDIR=$(CURDIR) ++ BASEDIR=../../profiles/apparmor.d ++ PARSER=../../parser/apparmor_parser + endif + + .PHONY: __libapparmor +@@ -62,10 +68,10 @@ + rm -rf __pycache__/ .coverage htmlcov + + check: __libapparmor +- export PYTHONPATH=$(PYTHONPATH) ; export LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) ; export LC_ALL=C; $(foreach test, $(wildcard test-*.py), echo ; echo === $(test) === ; $(call pyalldo, $(test))) ++ export PYTHONPATH=$(PYTHONPATH) LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) LC_ALL=C __AA_CONFDIR=$(CONFDIR) __AA_BASEDIR=$(BASEDIR) __AA_PARSER=$(PARSER) ; $(foreach test, $(wildcard test-*.py), echo ; echo === $(test) === ; $(call pyalldo, $(test))) + + .coverage: $(wildcard ../aa-* ../apparmor/*.py test-*.py) __libapparmor +- export PYTHONPATH=$(PYTHONPATH) ; export LD_LIBRARY_PATH=$(LD_LIBRARY_PATH); export LC_ALL=C; $(COVERAGE_IGNORE_FAILURES_CMD) ; $(foreach test, $(wildcard test-*.py), echo ; echo === $(test) === ; $(PYTHON) -m coverage run --branch -p $(test); ) ++ export PYTHONPATH=$(PYTHONPATH) LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) LC_ALL=C __AA_CONFDIR=$(CONFDIR) __AA_BASEDIR=$(BASEDIR) __AA_PARSER=$(PARSER) ; $(COVERAGE_IGNORE_FAILURES_CMD) ; $(foreach test, $(wildcard test-*.py), echo ; echo === $(test) === ; $(PYTHON) -m coverage run --branch -p $(test); ) + $(PYTHON) -m coverage combine + + coverage: .coverage + +=== modified file 'utils/test/common_test.py' +--- utils/test/common_test.py 2016-05-23 21:15:19 +0000 ++++ utils/test/common_test.py 2017-03-02 21:21:53 +0000 +@@ -103,6 +103,17 @@ + stub_test.__doc__ = "test '%s': %s" % (line, desc) + setattr(test_class, 'test_%d' % (i), stub_test) + ++def setup_aa(aa): ++ confdir = os.getenv('__AA_CONFDIR') ++ try: ++ if confdir: ++ aa.init_aa(confdir=confdir) ++ else: ++ aa.init_aa() ++ except AttributeError: ++ # apparmor.aa module versions <= 2.11 do not have the init_aa() method ++ pass ++ + def write_file(directory, file, contents): + '''construct path, write contents to it, and return the constructed path''' + path = os.path.join(directory, file) + +=== modified file 'utils/test/logprof.conf' +--- utils/test/logprof.conf 2014-08-21 00:14:24 +0000 ++++ utils/test/logprof.conf 2017-03-02 21:21:21 +0000 +@@ -10,11 +10,11 @@ + # ------------------------------------------------------------------ + + [settings] +- profiledir = /etc/apparmor.d /etc/subdomain.d +- inactive_profiledir = /usr/share/doc/apparmor-profiles/extras ++ profiledir = ../../profiles/apparmor.d ++ inactive_profiledir = ../../profiles/apparmor/profiles/extra + logfiles = /var/log/audit/audit.log /var/log/syslog /var/log/messages + +- parser = /sbin/apparmor_parser /sbin/subdomain_parser ++ parser = ../../parser/apparmor_parser + ldd = /usr/bin/ldd + logger = /bin/logger /usr/bin/logger + + +=== modified file 'utils/test/minitools_test.py' +--- utils/test/minitools_test.py 2015-06-26 23:29:46 +0000 ++++ utils/test/minitools_test.py 2017-03-02 21:21:53 +0000 +@@ -16,7 +16,7 @@ + import subprocess + import sys + import unittest +-from common_test import AATest, setup_all_loops ++from common_test import AATest, setup_all_loops, setup_aa + + import apparmor.aa as apparmor + from common_test import read_file +@@ -156,6 +156,7 @@ + self.assertEqual(exp_content, real_content, 'Failed to cleanup profile properly') + + ++setup_aa(apparmor) + setup_all_loops(__name__) + if __name__ == '__main__': + unittest.main(verbosity=2) + +=== modified file 'utils/test/test-aa-easyprof.py' +--- utils/test/test-aa-easyprof.py 2016-10-01 18:57:09 +0000 ++++ utils/test/test-aa-easyprof.py 2017-03-02 21:25:01 +0000 +@@ -18,6 +18,8 @@ + import tempfile + import unittest + ++import apparmor.easyprof as easyprof ++ + topdir = None + debugging = False + +@@ -163,6 +165,23 @@ + self.binary = "/opt/bin/foo" + self.full_args = ['-c', self.conffile, self.binary] + ++ # Check __AA_BASEDIR, which may be set by the Makefile, to see if ++ # we should use a non-default base directory path to find ++ # abstraction files ++ # ++ # NOTE: Individual tests can append another --base path to the ++ # args list and override a base path set here ++ base = os.getenv('__AA_BASEDIR') ++ if base: ++ self.full_args.append('--base=%s' % base) ++ ++ # Check __AA_PARSER, which may be set by the Makefile, to see if ++ # we should use a non-default apparmor_parser path to verify ++ # policy ++ parser = os.getenv('__AA_PARSER') ++ if parser: ++ self.full_args.append('--parser=%s' % parser) ++ + if debugging: + self.full_args.append('-d') + +@@ -913,6 +932,94 @@ + raise + raise Exception ("abstraction '%s' should be invalid" % s) + ++ def _create_tmp_base_dir(self, prefix='', abstractions=[], tunables=[]): ++ '''Create a temporary base dir layout''' ++ base_name = 'apparmor.d' ++ if prefix: ++ base_name = '%s-%s' % (prefix, base_name) ++ base_dir = os.path.join(self.tmpdir, base_name) ++ abstractions_dir = os.path.join(base_dir, 'abstractions') ++ tunables_dir = os.path.join(base_dir, 'tunables') ++ ++ os.mkdir(base_dir) ++ os.mkdir(abstractions_dir) ++ os.mkdir(tunables_dir) ++ ++ for f in abstractions: ++ contents = ''' ++ # Abstraction file for testing ++ /%s r, ++''' % (f) ++ open(os.path.join(abstractions_dir, f), 'w').write(contents) ++ ++ for f in tunables: ++ contents = ''' ++# Tunable file for testing ++@{AA_TEST_%s}=foo ++''' % (f) ++ open(os.path.join(tunables_dir, f), 'w').write(contents) ++ ++ return base_dir ++ ++ def test_genpolicy_abstractions_custom_base(self): ++ '''Test genpolicy (custom base dir)''' ++ abstraction = "custom-base-dir-test-abstraction" ++ # The default template #includes the base abstraction and global ++ # tunable so we need to create placeholders ++ base = self._create_tmp_base_dir(abstractions=['base', abstraction], tunables=['global']) ++ args = ['--abstractions=%s' % abstraction, '--base=%s' % base] ++ ++ p = self._gen_policy(extra_args=args) ++ search = "#include " % abstraction ++ self.assertTrue(search in p, "Could not find '%s' in:\n%s" % (search, p)) ++ inv_s = '###ABSTRACTIONS###' ++ self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) ++ ++ def test_genpolicy_abstractions_custom_base_bad(self): ++ '''Test genpolicy (custom base dir - bad base dirs)''' ++ abstraction = "custom-base-dir-test-abstraction" ++ bad = [ None, '/etc/apparmor.d', '/' ] ++ for base in bad: ++ try: ++ args = ['--abstractions=%s' % abstraction] ++ if base: ++ args.append('--base=%s' % base) ++ self._gen_policy(extra_args=args) ++ except easyprof.AppArmorException: ++ continue ++ except Exception: ++ raise ++ raise Exception ("abstraction '%s' should be invalid" % abstraction) ++ ++ def test_genpolicy_abstractions_custom_include(self): ++ '''Test genpolicy (custom include dir)''' ++ abstraction = "custom-include-dir-test-abstraction" ++ # No need to create placeholders for the base abstraction or global ++ # tunable since we're not adjusting the base directory ++ include = self._create_tmp_base_dir(abstractions=[abstraction]) ++ args = ['--abstractions=%s' % abstraction, '--Include=%s' % include] ++ p = self._gen_policy(extra_args=args) ++ search = "#include " % abstraction ++ self.assertTrue(search in p, "Could not find '%s' in:\n%s" % (search, p)) ++ inv_s = '###ABSTRACTIONS###' ++ self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) ++ ++ def test_genpolicy_abstractions_custom_include_bad(self): ++ '''Test genpolicy (custom include dir - bad include dirs)''' ++ abstraction = "custom-include-dir-test-abstraction" ++ bad = [ None, '/etc/apparmor.d', '/' ] ++ for include in bad: ++ try: ++ args = ['--abstractions=%s' % abstraction] ++ if include: ++ args.append('--Include=%s' % include) ++ self._gen_policy(extra_args=args) ++ except easyprof.AppArmorException: ++ continue ++ except Exception: ++ raise ++ raise Exception ("abstraction '%s' should be invalid" % abstraction) ++ + def test_genpolicy_profile_name_bad(self): + '''Test genpolicy (profile name - bad values)''' + bad = [ +@@ -2568,40 +2675,16 @@ + # Main + # + if __name__ == '__main__': +- def cleanup(files): +- for f in files: +- if os.path.exists(f): +- os.unlink(f) +- + absfn = os.path.abspath(sys.argv[0]) + topdir = os.path.dirname(os.path.dirname(absfn)) + + if len(sys.argv) > 1 and (sys.argv[1] == '-d' or sys.argv[1] == '--debug'): + debugging = True + +- created = [] +- +- # Create the necessary files to import aa-easyprof +- init = os.path.join(os.path.dirname(absfn), '__init__.py') +- if not os.path.exists(init): +- open(init, 'a').close() +- created.append(init) +- +- symlink = os.path.join(os.path.dirname(absfn), 'easyprof.py') +- if not os.path.exists(symlink): +- os.symlink(os.path.join(topdir, 'apparmor', 'easyprof.py'), symlink) +- created.append(symlink) +- created.append(symlink + 'c') +- +- # Now that we have everything we need, import aa-easyprof +- import easyprof +- + # run the tests + suite = unittest.TestSuite() + suite.addTest(unittest.TestLoader().loadTestsFromTestCase(T)) + rc = unittest.TextTestRunner(verbosity=2).run(suite) + +- cleanup(created) +- + if not rc.wasSuccessful(): + sys.exit(1) + +=== modified file 'utils/test/test-aa.py' +--- utils/test/test-aa.py 2016-12-30 23:48:41 +0000 ++++ utils/test/test-aa.py 2017-03-02 21:21:53 +0000 +@@ -10,7 +10,7 @@ + # ------------------------------------------------------------------ + + import unittest +-from common_test import AATest, setup_all_loops ++from common_test import AATest, setup_all_loops, setup_aa + from common_test import read_file, write_file + + import os +@@ -784,8 +784,8 @@ + ('/dev/null', {'allow': {'all': {'r', 'w', 'k'}, 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/dev/null'} }), + ('/foo/bar', {'allow': {'all': {'r', 'w'}, 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/foo/bar'} }), # exec perms not included + ('/no/thing', {'allow': {'all': set(), 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': set() }), +- ('/usr/lib/ispell/', {'allow': {'all': {'r'}, 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/usr/lib/ispell/', '/usr/lib{,32,64}/**'} }), # from abstractions/enchant +- ('/usr/lib/aspell/*.so', {'allow': {'all': {'m', 'r'}, 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/usr/lib/aspell/*', '/usr/lib/aspell/*.so', '/usr/lib{,32,64}/**'} }), # from abstractions/aspell via abstractions/enchant ++ ('/usr/lib/ispell/', {'allow': {'all': {'r'}, 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/usr/lib/ispell/', '/{usr/,}lib{,32,64}/**'} }), # from abstractions/enchant ++ ('/usr/lib/aspell/*.so', {'allow': {'all': {'m', 'r'}, 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/usr/lib/aspell/*', '/usr/lib/aspell/*.so', '/{usr/,}lib{,32,64}/**'} }), # from abstractions/aspell via abstractions/enchant + ] + + def _run_test(self, params, expected): +@@ -820,8 +820,8 @@ + (['/usr/share/common-licenses/foo/bar', 'w'], ['/usr/share/common*/foo/* rw,', '/usr/share/common-licenses/** rw,', '/usr/share/common-licenses/foo/bar rw,'] ), + (['/dev/null', 'wk'], ['/dev/null rwk,'] ), + (['/foo/bar', 'rw'], ['/foo/bar rw,'] ), +- (['/usr/lib/ispell/', 'w'], ['/usr/lib{,32,64}/** rw,', '/usr/lib/ispell/ rw,'] ), +- (['/usr/lib/aspell/some.so', 'k'], ['/usr/lib/aspell/* mrk,', '/usr/lib/aspell/*.so mrk,', '/usr/lib{,32,64}/** mrk,', '/usr/lib/aspell/some.so mrk,'] ), ++ (['/usr/lib/ispell/', 'w'], ['/{usr/,}lib{,32,64}/** rw,', '/usr/lib/ispell/ rw,'] ), ++ (['/usr/lib/aspell/some.so', 'k'], ['/usr/lib/aspell/* mrk,', '/usr/lib/aspell/*.so mrk,', '/{usr/,}lib{,32,64}/** mrk,', '/usr/lib/aspell/some.so mrk,'] ), + ] + + def _run_test(self, params, expected): +@@ -855,6 +855,7 @@ + proposals = propose_file_rules(profile, rule_obj) + self.assertEqual(proposals, expected) + ++setup_aa(apparmor.aa) + setup_all_loops(__name__) + if __name__ == '__main__': + unittest.main(verbosity=2) + +=== modified file 'utils/test/test-config.py' +--- utils/test/test-config.py 2016-10-10 21:27:19 +0000 ++++ utils/test/test-config.py 2017-03-02 21:21:21 +0000 +@@ -24,7 +24,7 @@ + conf = ini_config.read_config('logprof.conf') + logprof_sections = ['settings', 'repository', 'qualifiers', 'required_hats', 'defaulthat', 'globs'] + logprof_sections_options = ['profiledir', 'inactive_profiledir', 'logfiles', 'parser', 'ldd', 'logger', 'default_owner_prompt', 'custom_includes'] +- logprof_settings_parser = '/sbin/apparmor_parser /sbin/subdomain_parser' ++ logprof_settings_parser = '../../parser/apparmor_parser' + + self.assertEqual(conf.sections(), logprof_sections) + self.assertEqual(conf.options('settings'), logprof_sections_options) + +=== modified file 'utils/test/test-dbus.py' +--- utils/test/test-dbus.py 2016-11-19 09:55:03 +0000 ++++ utils/test/test-dbus.py 2017-02-28 23:04:24 +0000 +@@ -89,6 +89,10 @@ + ('dbus peer=(, label = bar, name = foo ),' , exp(False, False, False, '', None , True , None, True, None, True, None, True, None, True, None, True, 'foo', False, 'bar,', False)), # XXX peerlabel includes the comma + ('dbus peer=( label = bar , name = foo ),' , exp(False, False, False, '', None , True , None, True, None, True, None, True, None, True, None, True, 'foo', False, 'bar', False)), + ('dbus peer=( label = "bar" name = "foo" ),' , exp(False, False, False, '', None , True , None, True, None, True, None, True, None, True, None, True, 'foo', False, 'bar', False)), ++ ('dbus path=/foo/bar bus=session,' , exp(False, False, False, '', None , True , 'session', False, '/foo/bar', False, None, True, None, True, None, True, None, True, None, True)), ++ ('dbus bus=system path=/foo/bar bus=session,' , exp(False, False, False, '', None , True , 'session', False, '/foo/bar', False, None, True, None, True, None, True, None, True, None, True)), # XXX bus= specified twice, last one wins ++ ('dbus send peer=(label="foo") bus=session,' , exp(False, False, False, '', {'send'}, False, 'session', False, None, True, None, True, None, True, None, True, None, True, 'foo', False)), ++ ('dbus bus=1 bus=2 bus=3 bus=4 bus=5 bus=6,' , exp(False, False, False, '', None , True , '6', False, None, True, None, True, None, True, None, True, None, True, None, True)), # XXX bus= specified multiple times, last one wins + ] + + def _run_test(self, rawrule, expected): +@@ -108,6 +112,8 @@ + ('dbus peer=(label=foo) path=,' , AppArmorException), + ('dbus (invalid),' , AppArmorException), + ('dbus peer=,' , AppArmorException), ++ ('dbus bus=session bind bus=system,', AppArmorException), ++ ('dbus bus=1 bus=2 bus=3 bus=4 bus=5 bus=6 bus=7,', AppArmorException), + ] + + def _run_test(self, rawrule, expected): + +=== modified file 'utils/test/test-libapparmor-test_multi.py' +--- utils/test/test-libapparmor-test_multi.py 2017-01-19 15:52:38 +0000 ++++ utils/test/test-libapparmor-test_multi.py 2017-03-02 21:21:53 +0000 +@@ -10,7 +10,7 @@ + # ------------------------------------------------------------------ + + import unittest +-from common_test import AATest, setup_all_loops, read_file ++from common_test import AATest, setup_all_loops, setup_aa, read_file + + import os + from apparmor.common import open_file_read +@@ -267,6 +267,7 @@ + TestLibapparmorTestMulti.tests = find_test_multi('../../libraries/libapparmor/testsuite/test_multi/') + TestLogToProfile.tests = find_test_multi('../../libraries/libapparmor/testsuite/test_multi/') + ++setup_aa(apparmor.aa) + setup_all_loops(__name__) + if __name__ == '__main__': + unittest.main(verbosity=1) # reduced verbosity due to the big number of tests + +=== modified file 'utils/test/test-mount_parse.py' +--- utils/test/test-mount_parse.py 2016-10-01 18:57:09 +0000 ++++ utils/test/test-mount_parse.py 2017-03-02 21:21:53 +0000 +@@ -11,7 +11,7 @@ + + import apparmor.aa as aa + import unittest +-from common_test import AAParseTest, setup_regex_tests ++from common_test import AAParseTest, setup_regex_tests, setup_aa + + class BaseAAParseMountTest(AAParseTest): + def setUp(self): +@@ -39,6 +39,7 @@ + ('unmount /mnt/external,', 'unmount with mount point'), + ] + ++setup_aa(aa) + if __name__ == '__main__': + setup_regex_tests(AAParseMountTest) + setup_regex_tests(AAParseRemountTest) + +=== modified file 'utils/test/test-parser-simple-tests.py' +--- utils/test/test-parser-simple-tests.py 2016-10-01 18:57:09 +0000 ++++ utils/test/test-parser-simple-tests.py 2017-03-03 12:14:03 +0000 +@@ -10,7 +10,7 @@ + # ------------------------------------------------------------------ + + import unittest +-from common_test import AATest, setup_all_loops ++from common_test import AATest, setup_all_loops, setup_aa + import apparmor.aa as apparmor + + import os +@@ -30,9 +30,6 @@ + 'generated_x/ambiguous-', + 'generated_x/dominate-', + +- # permissions before path +- 'generated_perms_leading/', +- + # 'safe' and 'unsafe' keywords + 'generated_perms_safe/', + +@@ -52,6 +49,7 @@ + 'change_profile/onx_conflict_unsafe1.sd', + 'change_profile/onx_conflict_unsafe2.sd', + ++ 'dbus/bad_modifier_2.sd', + 'dbus/bad_regex_01.sd', + 'dbus/bad_regex_02.sd', + 'dbus/bad_regex_03.sd', +@@ -154,6 +152,8 @@ + 'vars/vars_dbus_bad_01.sd', + 'vars/vars_dbus_bad_02.sd', + 'vars/vars_dbus_bad_03.sd', ++ 'vars/vars_dbus_bad_04.sd', ++ 'vars/vars_dbus_bad_05.sd', + 'vars/vars_dbus_bad_06.sd', + 'vars/vars_dbus_bad_07.sd', + 'vars/vars_file_evaluation_7.sd', +@@ -256,16 +256,75 @@ + 'file/ok_5.sd', # Invalid mode UX + 'file/ok_2.sd', # Invalid mode RWM + 'file/ok_4.sd', # Invalid mode iX ++ 'xtrans/simple_ok_pix_1.sd', # Invalid mode pIx ++ 'xtrans/simple_ok_pux_1.sd', # Invalid mode rPux ++ ++ # unexpected uppercase vs. lowercase in *x rules - generated_perms_leading directory ++ 'generated_perms_leading/exact-re-Puxtarget.sd', ++ 'generated_perms_leading/dominate-ownerCuxtarget2.sd', ++ 'generated_perms_leading/ambiguous-Cux.sd', ++ 'generated_perms_leading/dominate-ownerPux.sd', ++ 'generated_perms_leading/exact-re-ownerPux.sd', ++ 'generated_perms_leading/overlap-ownerCuxtarget.sd', ++ 'generated_perms_leading/exact-re-ownerCuxtarget.sd', ++ 'generated_perms_leading/dominate-Puxtarget2.sd', ++ 'generated_perms_leading/dominate-ownerCuxtarget.sd', ++ 'generated_perms_leading/dominate-ownerPuxtarget.sd', ++ 'generated_perms_leading/ambiguous-Pux.sd', ++ 'generated_perms_leading/ambiguous-Cuxtarget2.sd', ++ 'generated_perms_leading/exact-Puxtarget2.sd', ++ 'generated_perms_leading/ambiguous-ownerCux.sd', ++ 'generated_perms_leading/exact-ownerPux.sd', ++ 'generated_perms_leading/ambiguous-ownerPuxtarget.sd', ++ 'generated_perms_leading/exact-re-ownerPuxtarget.sd', ++ 'generated_perms_leading/exact-re-Cuxtarget.sd', ++ 'generated_perms_leading/exact-re-Puxtarget2.sd', ++ 'generated_perms_leading/dominate-Cux.sd', ++ 'generated_perms_leading/exact-re-ownerCuxtarget2.sd', ++ 'generated_perms_leading/ambiguous-ownerCuxtarget.sd', ++ 'generated_perms_leading/exact-re-Cuxtarget2.sd', ++ 'generated_perms_leading/ambiguous-Puxtarget.sd', ++ 'generated_perms_leading/overlap-Puxtarget.sd', ++ 'generated_perms_leading/ambiguous-Puxtarget2.sd', ++ 'generated_perms_leading/overlap-Puxtarget2.sd', ++ 'generated_perms_leading/exact-Puxtarget.sd', ++ 'generated_perms_leading/overlap-ownerPuxtarget.sd', ++ 'generated_perms_leading/exact-ownerCuxtarget.sd', ++ 'generated_perms_leading/exact-re-ownerCux.sd', ++ 'generated_perms_leading/exact-ownerPuxtarget2.sd', ++ 'generated_perms_leading/exact-ownerCux.sd', ++ 'generated_perms_leading/overlap-Cuxtarget2.sd', ++ 'generated_perms_leading/ambiguous-Cuxtarget.sd', ++ 'generated_perms_leading/ambiguous-ownerPuxtarget2.sd', ++ 'generated_perms_leading/dominate-ownerCux.sd', ++ 'generated_perms_leading/exact-Pux.sd', ++ 'generated_perms_leading/exact-Cuxtarget.sd', ++ 'generated_perms_leading/overlap-ownerCuxtarget2.sd', ++ 'generated_perms_leading/overlap-Pux.sd', ++ 'generated_perms_leading/overlap-ownerPux.sd', ++ 'generated_perms_leading/ambiguous-ownerCuxtarget2.sd', ++ 'generated_perms_leading/exact-re-Cux.sd', ++ 'generated_perms_leading/exact-re-Pux.sd', ++ 'generated_perms_leading/overlap-Cuxtarget.sd', ++ 'generated_perms_leading/exact-re-ownerPuxtarget2.sd', ++ 'generated_perms_leading/exact-Cuxtarget2.sd', ++ 'generated_perms_leading/exact-Cux.sd', ++ 'generated_perms_leading/overlap-Cux.sd', ++ 'generated_perms_leading/overlap-ownerCux.sd', ++ 'generated_perms_leading/exact-ownerPuxtarget.sd', ++ 'generated_perms_leading/dominate-Pux.sd', ++ 'generated_perms_leading/exact-ownerCuxtarget2.sd', ++ 'generated_perms_leading/dominate-Puxtarget.sd', ++ 'generated_perms_leading/ambiguous-ownerPux.sd', ++ 'generated_perms_leading/overlap-ownerPuxtarget2.sd', ++ 'generated_perms_leading/dominate-Cuxtarget2.sd', ++ 'generated_perms_leading/dominate-Cuxtarget.sd', ++ 'generated_perms_leading/dominate-ownerPuxtarget2.sd', ++ ++ # escaping with \ + 'file/ok_embedded_spaces_4.sd', # \-escaped space + 'file/file/ok_embedded_spaces_4.sd', # \-escaped space + 'file/ok_quoted_4.sd', # quoted string including \" +- 'xtrans/simple_ok_pix_1.sd', # Invalid mode pIx +- 'xtrans/simple_ok_pux_1.sd', # Invalid mode rPux +- +- # dbus regex mismatch +- 'vars/vars_dbus_4.sd', +- 'vars/vars_dbus_9.sd', +- 'vars/vars_dbus_2.sd', + + # misc + 'vars/vars_dbus_8.sd', # Path doesn't start with / or variable: {/@{TLDS}/foo,/com/@{DOMAINS}} +@@ -399,6 +458,7 @@ + print('Running %s parser simple_tests...' % len(TestParseParserTests.tests)) + + ++setup_aa(apparmor) + find_and_setup_test_profiles('../../parser/tst/simple_tests/') + + setup_all_loops(__name__) + +=== modified file 'utils/test/test-pivot_root_parse.py' +--- utils/test/test-pivot_root_parse.py 2016-10-01 18:57:09 +0000 ++++ utils/test/test-pivot_root_parse.py 2017-03-02 21:21:53 +0000 +@@ -11,7 +11,7 @@ + + import apparmor.aa as aa + import unittest +-from common_test import AAParseTest, setup_regex_tests ++from common_test import AAParseTest, setup_regex_tests, setup_aa + + class AAParsePivotRootTest(AAParseTest): + def setUp(self): +@@ -24,6 +24,7 @@ + ('pivot_root /old /new -> /usr/bin/child,', 'pivot_root child rule'), + ] + ++setup_aa(aa) + if __name__ == '__main__': + setup_regex_tests(AAParsePivotRootTest) + unittest.main(verbosity=2) + +=== modified file 'utils/test/test-regex_matches.py' +--- utils/test/test-regex_matches.py 2016-10-01 18:57:09 +0000 ++++ utils/test/test-regex_matches.py 2017-03-02 21:21:53 +0000 +@@ -11,7 +11,7 @@ + + import apparmor.aa as aa + import unittest +-from common_test import AATest, setup_all_loops ++from common_test import AATest, setup_all_loops, setup_aa + from apparmor.common import AppArmorBug, AppArmorException + + from apparmor.regex import ( strip_parenthesis, strip_quotes, parse_profile_start_line, re_match_include, +@@ -502,6 +502,7 @@ + + + ++setup_aa(aa) + setup_all_loops(__name__) + if __name__ == '__main__': + # these two are not converted to a tests[] loop yet + +=== modified file 'utils/test/test-unix_parse.py' +--- utils/test/test-unix_parse.py 2016-10-01 18:57:09 +0000 ++++ utils/test/test-unix_parse.py 2017-03-02 21:21:53 +0000 +@@ -11,7 +11,7 @@ + + import apparmor.aa as aa + import unittest +-from common_test import AAParseTest, setup_regex_tests ++from common_test import AAParseTest, setup_regex_tests, setup_aa + + class AAParseUnixTest(AAParseTest): + +@@ -34,6 +34,7 @@ + 'complex unix rule'), + ] + ++setup_aa(aa) + if __name__ == '__main__': + setup_regex_tests(AAParseUnixTest) + unittest.main(verbosity=2) + + +vim:ft=diff From 834d67a5c30c3e1c2b35b1702afc307714319125c1239172cb9074fbc2cb40ad Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sun, 26 Mar 2017 20:38:57 +0000 Subject: [PATCH 2/2] Accepting request 482775 from home:cboltz fix filename in patch name OBS-URL: https://build.opensuse.org/request/show/482775 OBS-URL: https://build.opensuse.org/package/show/security:apparmor/apparmor?expand=0&rev=175 --- apparmor.changes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apparmor.changes b/apparmor.changes index 660621b..58b9b23 100644 --- a/apparmor.changes +++ b/apparmor.changes @@ -1,7 +1,7 @@ ------------------------------------------------------------------- Sat Mar 25 21:42:10 UTC 2017 - suse-beta@cboltz.de -- add upstream-changes-r-3629..3648.diff: +- add upstream-changes-r3629..3648.diff: - preserve unknown profiles when reloading apparmor.service (CVE-2017-6507, lp#1668892, boo#1029696) - add aa-remove-unknown utility to unload unknown profiles (lp#1668892)