aa-logprof doesn't ask anything for
type=AVC msg=audit(1427633461.202:281): apparmor="DENIED" operation="chmod" profile="/usr/lib64/firefox/plugin-container" name="/home/cb/.config/ibus/bus/" pid=7779 comm="plugin-containe" requested_mask="w" denied_mask="w" fsuid=1000 ouid=1000
This patch fixes this by adding 'chmod' to the list of file operation
types in logparser.py.
Acked-by: Seth Arnold <seth.arnold@canonical.com>
for both trunk and 2.9.
Rewrite parse_profile_start() in aa.py to a more readable version.
The behaviour remains unchanged (and is covered by tests).
The patch also updates the comment about the internal struct of
aa[profile][hat] - initial_comment was missing.
Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
Change the write_header tests so that the 'profile_keyword' and
'header_comment' parameters can be (and are) tested:
- add a None for both to the existing tests
- add some tests that come with the profile keyword and/or a comment
Acked-by: Steve Beattie <steve@nxnw.org>
- add support for prof_data['header_comment'] (comment after '{')
and prof_data['profile_keyword'] (to force the 'profile' keyword, even
if it isn't needed) to write_header().
(set_profile_flags() will be the only user of these two for now)
- fix a crash if depth is not an integer - for example,
len(' ')/2 # 3 spaces = 1.5
would cause a crash.
Also add a test for 1.5 and 1.3 spaces.
- rewrite the handling of flags to avoid we have to maintain two
different template lines.
- update the tests to set 'profile_keyword' and 'header_comment' to None.
This avoids big changes in the test code. I'll send another patch that
makes sure profile_keyword and header_comment are tested ;-)
Acked-by: Steve Beattie <steve@nxnw.org>
Add the attachment to the parse_profile_start() and
serialize_parse_profile_start() return values, and adjust the functions
calling the *parse_profile_start() functions to save the attachment in
the "attachment" variable (which isn't used yet).
Also adjust the tests for the added return value.
(Sorry for not getting the resultset right from the beginning!)
Acked-by: Steve Beattie <steve@nxnw.org>
Also fix a little bug that added the profile keyword if the path needed
quotes (profile "/foo bar" - but "/foo bar" is enough). This was caused
by a regex that always matched on quoted paths (hint: "/ matches
^[^/] ;-)
Also add some tests with attachments and update the test for the bugfix
mentioned above.
Now the remaining part is to make sure that prof_data['attachment'] gets
set when parsing the profiles :-)
Acked-by: Steve Beattie <steve@nxnw.org>
Also add loop support to test-aa.py.
BTW: In case you wonder - the need to replace unittest.TestCase with
AATest is intentional. It might look annoying, but it makes sure that
a test-*.py file doesn't contain a test class where tests = [...] is
ignored because it's still unittest.TestCase.
(Technically, setup_all_tests() will error out if a test class doesn't
contain tests = [...] - either explicit or via its parent AATest.)
Acked-by: Steve Beattie <steve@nxnw.org>
Add various tests for set_profile_flags, and document various
interesting[tm] things I discovered while writing the tests (see
the inline comments for details).
Also adds a read_file() function to common_test.py.
The most interesting[tm] thing I found is:
regex_hat_flag = re.compile('^([a-z]*)\s+([A-Z]*)\s*(#.*)?$')
which matches various unexpected things - but not a hat :-/
(see mailinglist for all funny details)
Acked-by: Steve Beattie <steve@nxnw.org>
Convert serialize_parse_profile_start() to use
parse_profile_start_line(), and adjust a test to expect an AppArmorBug
instead of an AttributeError exception.
Also add two tests (they succeed with the old and the new code).
Note that these tests document interesting[tm] behaviour - I tend to
think that those cases should raise an exception, but I'm not sure about
this because serialize_profile_from_old_profile() is a good example for
interesting[tm] code :-/
I couldn't come up with a real-world test profile that would hit those
cases without erroring out aa-logprof earlier - maybe the (more
sane-looking) parse_profiles() / serialize_parse_profile_start()
protects us from hitting this interesting[tm] behaviour.
Acked-by: Steve Beattie <steve@nxnw.org>
The commit message for r2976 says:
[...]
The patch also adds test-example.py, which is
- a demo of the code added to common_test.py
- a template file that we can copy for future test-*.py
Acked-by: Steve Beattie <steve@nxnw.org>
but I forgot to add test-example.py to bzr, which I hereby do.
The previous patch slightly changed the behaviour of parse_profile_start()
and get_profile_flags() - they raise AppArmorBug instead of
AppArmorException when specifying a line that is not the start of a
profile and therefore doesn't match RE_PROFILE_START_2.
This patch updates test-aa.py to expect the correct exceptions, and adds
another test with quoted profile name to ensure that stripping the
quotes works as expected.
Acked-by: Steve Beattie <steve@nxnw.org>
Add the parse_profile_start_line() function to regex.py, which is a
wrapper for RE_PROFILE_START_2 and returns an array with named matches.
Also change some places in aa.py from using RE_PROFILE_START to the
parse_profile_start_line() function.
Notes:
- until everything is migrated to the new function, I'll keep the old
RE_PROFILE_START unchanged - that's the reason to add the new regex
as RE_PROFILE_START_2
- the patch changes only aa.py sections that are covered by tests already
(which means some users of RE_PROFILE_START are remaining)
- parse_profile_start_line() merges 'profile' and 'attachment' into
'profile' (aka the old, broken behaviour) until aa.py can handle the
attachment properly. The alternative would be to ignore 'attachment',
which would be worse.
Acked-by: Steve Beattie <steve@nxnw.org>
Add better support for looping over a tests[] array to common_test.py:
- class AATest - a base class we can use for all tests, and that will
probably get more features in the future (for example tempdir
handling)
- setup_all_tests() - a function that iterates over all classes in the
given file and calls setup_test_loops() for each of them
- setup_tests_loop() - a function that creates tests based on tests[]
in the given class. Those tests call the class' _run_test() method for
each test specified in tests[] (inspired by setup_regex_tests() ;-)
This means we can get rid of the manually maintained tests list in
test-regex_matches.py and just need to call setup_all_tests() once in
each file.
The patch also adds test-example.py, which is
- a demo of the code added to common_test.py
- a template file that we can copy for future test-*.py
Acked-by: Steve Beattie <steve@nxnw.org>
serialize_profile_from_old_profile() in aa.py, as a preparation to add
tests and then switch to the upcoming RE_PROFILE_START wrapper function.
Besides moving the code, I replaced write_prof_data[profile][hat]['profile']
and write_prof_data[profile][hat]['external'] with function parameters
to avoid that I have to pass around the full write_prof_data.
Note: The "lineno" parameter is technically superfluous - I kept it to
have the parameters as close to parse_profile_start() as possible and
hope that I can merge those functions later (when we have test coverage).
Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9.
and change the code to use them.
Also add a comment to act() that it's only used by aa-cleanprof.
Note: The new functions add the --base parameter to the apparmor_parser
calls, which also means the disable directory inside the given profile
dir (and not always /etc/apparmor.d/disable) is now honored.
Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9.
logparser.py / add_event_to_tree() has 5 places to handle 'path' events.
This patch merges most if conditions to reduce that to 2 places.
It also makes the matching a bit more strict - instead of using 'in',
'xattr' has to be an exact match and 'file_' is matched with startswith().
Also, 'getattr' is added to the list of file events.
Acked-by: Steve Beattie <steve@nxnw.org>
---------- trunk only, unclear for 2.9 --------------
Without it, aa-disable
- didn't error out when hitting a broken profile directory
- didn't find a profile if it doesn't use the default naming scheme
(for example /bin/true profile hiding in bin.false)
Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9
aa-status was crashing when parsing through /proc/mounts looking to see
if and where the securityfs synthetic file system is mounted if there
was a mount point that contained characters outside of the charset in
use in the environment of aa-status. This patch fixes the issue by
converting the read of /proc/mounts into a binary read and then uses
decode on the elements.
Patch by Alain BENEDETTI.
Acked-by: Steve Beattie <steve@nxnw.org>
As a follow-up to the logparser.py change that converts disconnected
path events to an error, add a testcase to test-logparser.py.
Acked-by: Steve Beattie <steve@nxnw.org> for both trunk and 2.9.
The upcoming function parse_profile_start() (which is a wrapper around
the updated RE_PROFILE_START, and will live in regex.py) needs
strip_profile(), but importing it from aa.py fails with an import loop.
Therefore this patch moves strip_quotes() from aa.py to regex.py and
re-imports it into aa.py.
As a bonus, the patch also adds some tests for strip_quotes() ;-)
Also add TestStripQuotes to the test_suite list because it won't run
otherwise.
Acked-by: Steve Beattie <steve@nxnw.org> for both trunk and 2.9
Move the code for parsing the profile start ("/foo {") from aa.py
parse_profile_data() to a separate function parse_profile_start().
Most of the changes are just moving around code, with some small
exceptions:
- instead of handing over profile_data to parse_profile_start() to
modify it, it sets two variables (pps_set_profile and
pps_set_hat_external) as part of its return value, which are then
used in parse_profile_data() to set the flags in profile_data.
- existing_profiles[profile] = file is executed later, which means
it used the strip_quotes() version of profile now
- whitespace / tab level changes
The patch also adds some tests for the parse_profile_start() function.
Acked-by: Steve Beattie <steve@nxnw.org>
Also adds a check to get_profile_flags() to catch an invalid syntax:
/foo ( ) {
was accepted by get_profile_flags, while
/foo () {
failed.
When testing with the parser, both result in a syntax error, therefore
the patch makes sure it also fails in get_profile_flags().
Acked-by: Steve Beattie <steve@nxnw.org>
This means that aa-logprof will ignore the event instead of crashing with
AppArmorException: 'Unexpected rank input: var/run/nscd/passwd'
Note that I made the check as specific as possible to be sure it doesn't
hide other events.
References: https://bugzilla.opensuse.org/show_bug.cgi?id=918787
Acked-by: Steve Beattie <steve@nxnw.org>
Also update test-capability.py - it contains a test that needs
'error_code': 0,
added to avoid a failure.
Patch by: Steve Beattie <steve@nxnw.org>
Acked-by: Christian Boltz <apparmor@cboltz.de>
Remove the check if the disable directory exists. If it's really
missing, it will be auto-created by create_symlink(), so we
automagically fix things instead of annoying the user with an
error message ;-)
Acked-by: Steve Beattie <steve@nxnw.org> for both trunk and 2.9.
Make sure most tools (for example aa-complain) don't error out if
no logfile can be found. (For obvious reasons, aa-logprof and
aa-genprof will still require a logfile ;-)
This is done by moving code from the global area in aa.py to the new
function set_logfile(), which is called by aa-logprof and aa-genprof.
While on it,
- rename apparmor.filename to apparmor.logfile
- move the error handling for user-specified logfile from aa-genprof
and aa-logprof to aa.py set_logfile()
Note: I'd have prefered to hand over the logfile as parameter to
do_logprof_pass(), but that would break last_audit_entry_time() in
aa-genprof which requires the log filename before do_logprof_pass()
is called.
References: https://bugs.launchpad.net/apparmor/+bug/1423702
Acked-by: Seth Arnold <seth.arnold@canonical.com>
libapparmor _aa_is_blacklisted() - some extensions were missing in the
python code.
Also make the code more readable and add some testcases.
Notes:
- the original code additionally ignored *.swp. I didn't include that -
*.swp looks like vim swap files which are also dot files
- the python code ignores README files, but the C code doesn't
(do we need to add README in the C code?)
Acked-by: Kshitij Gupta <kgupta8592@gmail.com> for 2.9 and trunk
Acked-by: Steve Beattie <steve@nxnw.org>
string or if a mode_char is not in MODE_HASH.
Also update the testcase for "asdf42" (which raises AppArmorBug now)
and add a test that simulates MODE_HASH and MODE_MAP_SET getting out
of sync (tests the second part of the if condition).
Acked-by: Steve Beattie <steve@nxnw.org>
Since the Makefile cleanup, the _clean target is only used to delete
manpages etc. generated from *.pod files.
This patch renames the _clean target to pod_clean to make it obvious
what it does.
Acked-by: John Johansen <john.johansen@canonical.com>
- drop the symlink magic of the common/ directory, and just include
files directly from there.
- update comments indicating required steps to take when including
common/Make.rules
- drop make clean steps that refer to no longer generated tarballs,
specfiles, and symlinks to the common directory/Make.rules.
- don't silence clean steps if VERBOSE is set
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Christian "Ghostbuster" Boltz <apparmor@cboltz.de>
https://bugs.launchpad.net/apparmor/+bug/1399027
Also move some existing tests from aa_test.py to test-logparser.py and
adds checks for RE_LOG_v2_6_audit and RE_LOG_v2_6_syslog to them.
Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9
Split is_covered() in capability.py into
- is_covered_localparts() for rule-specific code
- is_covered() for common code - located in __init__.py
The object type comparison now uses type(self) and a slightly different
error message to make it usable everywhere.
Also rename rule_obj to other_rule which is more self-explaining
(inspired by the parameter name in the is_covered() dummy in __init__.py).
v2:
- remove check_allow_deny and check_audit parameters from
is_covered_localvars()
Acked-by: Steve Beattie <steve@nxnw.org>
If one of the testcases fail, this goes unnoticed in "make coverage".
This patch changes the Makefile so that test failures let
"make coverage" fail.
You can use make COVERAGE_IGNORE_FAILURES=true coverage to build
coverage data even if some tests fail.
Signed-off-by: Steve Beattie <steve@nxnw.org>
(which was most probably meant as an Acked-by)
Also Acked-by: <timeout> ;-)
For reasons that are unclear, python's setuptools doesn't install
recursively from a directory, meaning that on make install, the new
Rules/Ruleset classes were not being installed. This patch causes
the rule subdirectory to be included.
Bug: https://bugs.launchpad.net/bugs/1407437
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Tyler Hicks <tyhicks@canonical.com>
adds some tests for severity.py and improves the test coverage to
nearly 100% (only 3 partial left).
Added tests and details (all in SeverityVarsTest):
- move writing the tunables file from setUp() into _init_tunables() for
more flexibility (allows to specify other file content)
- test adding to a variable (+=)
- test #include
- make sure double definition of a variable fails
- make sure redefinition of non-existing variable fails
BTW: even the comment added to VARIABLE_DEFINITIONS contributes to
the coverage ;-)
severity.py passes all added tests, however I should note that including
a non-existing file is silently ignored.
Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
This patch hides raw_rule within the BaseRule class by making parse() be
a class method for all the rule types, implemented via a rule-specific
abstract method _parse() that returns a parsed Rule object.
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Christian Boltz <apparmor@cboltz.de>