454b681e13
- 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
1737 lines
68 KiB
Diff
1737 lines
68 KiB
Diff
------------------------------------------------------------
|
|
revno: 3648
|
|
fixes bug: https://launchpad.net/bugs/1668892
|
|
committer: Tyler Hicks <tyhicks@canonical.com>
|
|
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 <tyhicks@canonical.com>
|
|
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
|
Acked-by: John Johansen <john.johansen@canonical.com>
|
|
------------------------------------------------------------
|
|
revno: 3647
|
|
fixes bug: https://launchpad.net/bugs/1668892
|
|
committer: Tyler Hicks <tyhicks@canonical.com>
|
|
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 <tyhicks@canonical.com>
|
|
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
|
Acked-by: John Johansen <john.johansen@canonical.com>
|
|
------------------------------------------------------------
|
|
revno: 3646
|
|
committer: Seth Arnold <seth.arnold@canonical.com>
|
|
branch nick: apparmor
|
|
timestamp: Tue 2017-03-21 12:09:59 -0700
|
|
message:
|
|
parser: Fix delete after new[] -- patch from Oleg Strikov <oleg.strikov@gmail.com>
|
|
------------------------------------------------------------
|
|
revno: 3645 [merge]
|
|
committer: Tyler Hicks <tyhicks@canonical.com>
|
|
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 <tyhicks@canonical.com>
|
|
Acked-by: Jamie Strandboge <jamie@ubuntu.com>
|
|
------------------------------------------------------------
|
|
revno: 3644
|
|
committer: Christian Boltz <apparmor@cboltz.de>
|
|
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 <tyhicks@canonical.com>
|
|
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
|
------------------------------------------------------------
|
|
revno: 3643
|
|
committer: Christian Boltz <apparmor@cboltz.de>
|
|
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 <seth.arnold@canonical.com>
|
|
------------------------------------------------------------
|
|
revno: 3642
|
|
committer: Tyler Hicks <tyhicks@canonical.com>
|
|
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 <tyhicks@canonical.com>
|
|
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
|
Acked-by: Christian Boltz <apparmor@cboltz.de>
|
|
------------------------------------------------------------
|
|
revno: 3641
|
|
committer: Tyler Hicks <tyhicks@canonical.com>
|
|
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 <tyhicks@canonical.com>
|
|
Acked-by: Christian Boltz <apparmor@cboltz.de>
|
|
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
|
------------------------------------------------------------
|
|
revno: 3640
|
|
committer: Tyler Hicks <tyhicks@canonical.com>
|
|
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 <tyhicks@canonical.com>
|
|
Acked-by: Christian Boltz <apparmor@cboltz.de>
|
|
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
|
------------------------------------------------------------
|
|
revno: 3639
|
|
committer: Tyler Hicks <tyhicks@canonical.com>
|
|
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 <tyhicks@canonical.com>
|
|
Acked-by: Christian Boltz <apparmor@cboltz.de>
|
|
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
|
------------------------------------------------------------
|
|
revno: 3638
|
|
fixes bug: https://launchpad.net/bugs/1521031
|
|
committer: Tyler Hicks <tyhicks@canonical.com>
|
|
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 <tyhicks@canonical.com>
|
|
Acked-by: Christian Boltz <apparmor@cboltz.de>
|
|
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
|
------------------------------------------------------------
|
|
revno: 3637
|
|
committer: Tyler Hicks <tyhicks@canonical.com>
|
|
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 <tyhicks@canonical.com>
|
|
Suggested-by: Christian Boltz <apparmor@cboltz.de>
|
|
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
|
Acked-by: Christian Boltz <apparmor@cboltz.de>
|
|
------------------------------------------------------------
|
|
revno: 3636
|
|
committer: Tyler Hicks <tyhicks@canonical.com>
|
|
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 <tyhicks@canonical.com>
|
|
Acked-by: Christian Boltz <apparmor@cboltz.de>
|
|
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
|
------------------------------------------------------------
|
|
revno: 3635
|
|
committer: Tyler Hicks <tyhicks@canonical.com>
|
|
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 <tyhicks@canonical.com>
|
|
Acked-by: Christian Boltz <apparmor@cboltz.de>
|
|
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
|
------------------------------------------------------------
|
|
revno: 3634
|
|
fixes bug: https://launchpad.net/bugs/1628286
|
|
committer: Tyler Hicks <tyhicks@canonical.com>
|
|
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 <tyhicks@canonical.com>
|
|
Acked-by: Christian Boltz <apparmor@cboltz.de>
|
|
------------------------------------------------------------
|
|
revno: 3633
|
|
committer: Tyler Hicks <tyhicks@canonical.com>
|
|
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 <tyhicks@canonical.com>
|
|
Acked-by: Christian Boltz <apparmor@cboltz.de>
|
|
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
|
------------------------------------------------------------
|
|
revno: 3632
|
|
committer: Christian Boltz <apparmor@cboltz.de>
|
|
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 <seth.arnold@canonical.com> for trunk, 2.10 and 2.9.
|
|
------------------------------------------------------------
|
|
revno: 3631
|
|
committer: Christian Boltz <apparmor@cboltz.de>
|
|
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 <steve@nxnw.org> for trunk, 2.10 and 2.9
|
|
------------------------------------------------------------
|
|
revno: 3630
|
|
committer: Steve Beattie <sbeattie@ubuntu.com>
|
|
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 <steve@nxnw.org>
|
|
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
|
------------------------------------------------------------
|
|
revno: 3629
|
|
committer: Christian Boltz <apparmor@cboltz.de>
|
|
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 <john.johansen@canonical.com>
|
|
------------------------------------------------------------
|
|
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 <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 05:08:01 +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/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 <abstractions/%s>" % 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<access>' + 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 <abstractions/%s>" % 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 <abstractions/%s>" % 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
|