If the audit.log contains an event for a non-existing profile (this can
happen when running with a foreign log or if the user manually deleted a
profile or hat), propose_file_rules() crashes because rule_obj is None
instead of a profile_storage() struct.
This patch adds a check that skips events for non-existing profiles and
hats.
Note: I'm quite sure this happens only for file events (because the
other rule types don't have something similar to propose_file_rules()),
therefore no backport to older versions is needed.
Acked-by: Steve Beattie <steve@nxnw.org>
Add set_options_audit_mode() to switch the audit mode in all options
offered by aa-logprof and aa-mergeprof, not only the "original" rule
(in aa-logprof, this means the non-globbed rule_obj).
As usual, add some tests to ensure the function works as expected.
Acked-by: Steve Beattie <steve@nxnw.org>
aa.py:
- add propose_file_rules() - will propose matching paths from existing
rules in the profile or one of the includes
- save user_globs if user selects '(N)ew' (will be re-used when
proposing rules)
- change user_globs to a dict so that it can carry the human-readable
path and an AARE object for it
- change order_globs() to ensure the original path (given as parameter)
is always the last item in the resulting list
- add a ruletype switch to ask_the_questions() so that it uses
propose_file_rules() for file events (I don't like this
ruletype-specific solution too much, but everything else would make
things even more complicated)
Also keep aa-mergeprof ask_the_questions() in sync with aa.py.
In FileRule, add original_perms (might be set by propose_file_rules())
Finally, add some tests to ensure propose_file_rules() does what it promises.
Acked-by: Steve Beattie <steve@nxnw.org>
get_file_perms() collects the existing permissions for a file from
various rules (exact matches, wildcards) in the main profile and the
included abstractions.
It will be used to get displaying the current permissions back, and
also to propose rules with merged permissions (next patch).
Also add some tests to make sure it does what it promises ;-)
Acked-by: Steve Beattie <steve@nxnw.org>
- get_rules_for_path() returns all rules matching the given path
(both exact matches and AARE matches)
- get_perms_for_path() returns the merged permissions for the given
path and a list of paths used in the matching rules
Also add tests for these two functions.
Acked-by: Steve Beattie <steve@nxnw.org>
Also add a rank_path() function to severity.py and change rank() to call
rank_path() for paths.
Long-term goal: get rid of the type "guessing" in rank()
Finally add some tests, mostly based on test-severity.py SeverityTest
Acked-by: Steve Beattie <steve@nxnw.org>
This brings back the edit option for the path of file rules.
Also add it to aa-mergeprof to keep ask_the_questions() in sync.
Note: aa-mergeprof will ask about path mismatchs basically always.
That's because AARE is too careful on the matching - something to be
fixed in a later patch.
Acked-by: Steve Beattie <steve@nxnw.org>
This means adding
- self.can_edit - True if editing via '(N)ew' should be possible (will
be False for bare file rules)
- edit_header() - returns the prompt text and the current path
- validate_edit() - checks if the new path matches the original one
- store_edit() - changes the path to the new one (even if it doesn't
match the old one)
self.can_edit and the 3 functions are also added to BaseRule:
- can_edit is False by default
- the functions raise a NotImplementedError
Also add tests for the added code.
Acked-by: Steve Beattie <steve@nxnw.org>
This change also needs some other changes in ask_the_questions():
- set q.options and q.selected inside the loop (because glob() and
glob_ext() add another option)
- set 'selection' outside the if block to avoid doing it in nearly every
if branch
- make sure to add the selected rule, not just rule_obj (which doesn't
contain a modified, for example globbed, rule)
- skip 'deny' if an #include is selected
- re-add handling for CMD_GLOB and CMD_GLOB_EXT (was lost when switching
to FileRule)
- add selection_to_rule_obj() helper function
- add glob and glob with ext buttons in available_buttons() if
rule_obj.can_glob or rule_obj.can_glob_ext
Also apply the changes in ask_the_questions() to aa-mergeprof to keep it
in sync with aa.py, and disable the old path handling in aa-mergeprof.
Note: in its current state, aa-mergeprof will ask for some "superfluous"
file permissions, and doesn't check for 'x' conflicts. One of the
following patches will fix that.
Acked-by: Steve Beattie <steve@nxnw.org>
Add the glob() and glob_ext() functions to FileRule, and set
self.can_glob and self.can_glob_ext. Also add some tests (just enough to
make sure the FileRule integration works - the globbing is handled
inside AARE,and the AARE tests contain more testcases).
Note that the implementation differs from the original plan (which was
to have globbing in *Ruleset). Therefore add can_glob and can_glob_ext
to BaseRule (both default to False), and add a comment to BaseRuleset
that globbing needs to be removed from all *Ruleset classes.
Acked-by: Steve Beattie <steve@nxnw.org>
As discussed, I added a pointer to the test-aare.py globbing tests in
test-file.py.
glob_path() and glob_path_ext() modify a (path) regex, so move them to
AARE. Also change them to use self.regex instead of the newpath
parameter, and to return a new AARE object.
While on it, also add several tests to test-aare.py.
Note: There are still glob_path() and glob_path_ext() calls in aa.py,
but those calls are in a (since the middle of this patch series) dead
code section. pyflakes will complain about them nevertheless ;-)
Acked-by: Steve Beattie <steve@nxnw.org>
This patch changes handle_children() (which asks about exec events) and
ask_the_questions() (which asks everything else) to FileRule. This
solves the "brain split" introduced by the previous patch.
This means aa-logprof and aa-genprof ask useful questions again, and
store the answers at the right place.
In detail, this means (with '-' line number from the diff)
- (391) handle_binfmt(): use FileRule. Also avoid breakage if glob_common()
returns an empty result.
- (484) profile_storage(): drop profile['allow']['path'] and
profile['deny']['path']
- (510) create_new_profile(): switch to FileRule
- (1190..1432) lots of changes in handle_children():
- drop escaping (done in FileRule)
- don't add events with 'x' perms to prelog
- use is_known_rule() instead of profile_known_exec()
- replace several regexes for the selected CMD_* with more readable
'in' clauses. While on it, drop unused parts of the regex.
- use plain 'ix', 'px' (as str) instead of str_to_mode() format
- call handle_binfmt() for the interpreter in ix, Pix and Cix rules
- (1652) ask_the_questions(): disable the old file-specific code
(not dropped because some features aren't ported to FileRule yet)
- (2336) collapse_log():
- convert file log events to FileRule (and add some workarounds and
TODOs for logparser.py behaviour that needs to change)
- disable the old file-specific code (not dropped because merging of
existing permissions isn't ported to FileRule yet)
- (2403) drop now unused validate_profile_mode() and the regexes it used
- (3374) drop now unused profile_known_exec()
Test changes:
- adjust fake_ldd to handle /bin/bash
- change test-aa.py AaTest_create_new_profile to expect FileRule instead
of a path hasher. Also copy the profiles to the tempdir and load the
abstractions that are needed by the test.
(These tests get skipped on py2 because changing
apparmor.aa.cfg['settings']['ldd'] doesn't work for some unknown reason)
Important: Some nice-to-have features are not yet implemented for
FileRule:
- globbing
- (N)ew (allowing the user to enter a custom path)
- displaying and merging of permissions already existing in the profile
This means: aa-logprof works, but it's not as user-friendly as before.
The next patches will fix that ;-)
Also note that pyflakes will fail for ask_the_questions_OLD_FILE_CODE()
because of undefined symbols (aamode, profile, hat). This will be fixed
when the old code gets dropped in one of the later patches.
Acked-by: Steve Beattie <steve@nxnw.org>
Bug: https://launchpad.net/bugs/1569316
Change aa.py to use FileRule and FileRuleset for parsing and saving
profiles.
In detail, this means:
- add 'file' to the list of rule classes to enable it at various places
- store file rules in aa[profile][hat]['file'] (not 'path' as before)
to be consistent with the FileRule name
- drop the no longer needed delete_path_duplicates() - this is now
handled by FileRuleset like in all other rule classes.
(same change in cleanprofile.py)
- replace usage of RE_PROFILE_BARE_FILE_ENTRY and RE_PROFILE_PATH_ENTRY
with FileRule.match()
- drop write_path_rules() and write_paths() and replace them with the
new write_file() function.
- adjust several code sections to use write_file() and 'file' instead of
'path'
FileRule doesn't drop optional keywords ('allow' and 'file'), therefore
adjust cleanprof_test.out to the changed behaviour. (If someone insists
on dropping optional keywords in aa-cleanprof, that's something for a
future patch.)
Also adjust the list of known failures in test-parser-simple-tests.py -
switching to FileRule avoids several test failures (and introduces a few
new ones ;-)
IMPORTANT:
This patch introduces a "brain split" which means
- parsing and writing the profile and aa-cleanprof use the new location
(aa[profile][hat]['file'])
- aa-logprof and aa-genprof still save data to the old location
(aa[profile][hat]['allow']['path']) and probably ask superfluous
questions because there are no rules existing in the old location
TL;DR: don't try aa-logprof or aa-genprof with only this patch applied.
I know this isn't ideal, but still better than an even bigger and
totally unreadable patch ;-)
Acked-by: Steve Beattie <steve@nxnw.org>
aa-logprof needs to check if an exec rule for a given path exists.
This patch adds a __FileAnyExec class to FileRule, as well as ANY_EXEC
(which should be used externally, similar to ALL), and adjusts several
checks to allow it as a special execute mode.
This will allow to use is_covered() (or aa.py is_known_rule()) to find
out if execute is permitted, which replaces aa.py profile_known_exec()
in one of the following patches.
As usual, also add some tests.
Acked-by: Steve Beattie <steve@nxnw.org>
Note: as discussed, I adjusted the comment for 'pass' around line 240.
Patch 14 will drop the RE_PROFILE_PATH_ENTRY and
RE_PROFILE_BARE_FILE_ENTRY import from apparmor.aa.
This would break test-regex_matches.py, therefore
import these regexes from apparmor.regex.
Acked-by: Steve Beattie <steve@nxnw.org>
The parser accepts duplicated execute permissions as long as they don't
conflict. For example,
/bin/foo pxpxpxpx,
is a valid rule.
This patch changes FileRule to also accept those duplicated permissions,
even if it's unlikely to hit them outside of the parser tests ;-)
Also add some tests to make sure the parsing works as expected.
Acked-by: Steve Beattie <steve@nxnw.org>
RE_PATH expected (simplified) '/.+', however this excludes a plain '/'
that can appear in path rules.
This patch changes the regex so that it also matches '/'.
Acked-by: Seth Arnold <seth.arnold@canonical.com>
After dropping the dead code in handle_children(), there's only one use
of contains() left in log_str_to_mode().
This patch changes log_str_to_mode to use mode_contains() and drops the
now unused contains() function.
Acked-by: Seth Arnold <seth.arnold@canonical.com>
The 'exec' handling in handle_children starts with
if do_execute:
if profile_known_exec(...)
continue
which means if profile_known_exec() returns True, the rest of the loop
will be skipped. profile_known_exec() will return True if it finds an
exec rule in the profile or an include (independent of the exec type,
and (thanks to rematchfrag()) even if the path is globbed.
Later in the loop, there are checks for various exec modes - but those
checks can only be reached without an existing x rule, so they'll never
be hit.
This patch removes the dead code in the handle_children() / 'exec' / 'no
existing x rule found' section.
I confirmed that this code is really dead by
a) reading the code and, after being confused
b) two manual aa-logprof runs with coverage enabled - in one of them, I
added some ix, Px and Cx rules, and in the second one, no more exec
rules were needed/asked.
After dropping the dead code, combinedmode and combinedaudit are no
longer used, so we can also drop the code that sets those variables.
Sidenote: this patch drops 2% of the lines in aa.py ;-)
Acked-by: Seth Arnold <seth.arnold@canonical.com>
These classes handle file rules, including file rules with leading
perms, and are meant to replace lots of file rule code in aa.py and
aa-mergeprof.
Note: get_glob() and logprof_header_localvars() don't even look
finalized and will be changed in a later patch. (Some other things will
also be changed or added with later patches - but you probably won't
notice them while reviewing this patch.)
Acked-by: Seth Arnold <seth.arnold@canonical.com>
Acked-by: Kshitij Gupta <kgupta8592@gmail.com> (with some suggestions for a follow-up patch)
v1.1: remove 'and not deny' from a condition in split_perms() to get
more helpful error messages for rules like "deny /foo pix,"
Acked-by: Steve Beattie <steve@nxnw.org>
_is_covered_list() has a sanity check that raises an exception if both
other_value and other_all evaluate to False. This breaks when using
_is_covered_list() for FileRule.perms which can be empty if exec_perms
are specified.
This patch adds an optional parameter that allows to skip the sanity
check.
Acked-by: Seth Arnold <seth.arnold@canonical.com>
For now, use an additional regex RE_PROFILE_FILE_ENTRY to avoid
breakage of the existing code by the added match groups.
The regex includes support for file rules with leading and trailing
permissions as well as bare file rules.
Note: even with the restriction to the permission letters we actually
use, it's in theory still possible that a future additional rule type or
permission letter might lead to additional matches for other rule types.
Therefore the parsing code should check for all other rule types before
matching for file rules.
Acked-by: Seth Arnold <seth.arnold@canonical.com>
File permissions can be an empty list (if only exec permissions are
specified). This patch adds the optional allow_empty_list parameter so
that the function can handle this case.
Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
File rules contain some optional details (like leading permissions and
the file keyword) which should be ignored in non-strict mode.
This patch passes through the 'strict' parameter to is_equal_localvars
and adds it as function parameter in all existing rule classes.
It also adjusts test-baserule.py to test with the additional parameter.
Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
For reasons that aren't entirely clear, the action to set
apparmor.aa.cfg['settings']['ldd'] to './fake_ldd' does not actually
work on python2.7, get_reqs() tries to use /usr/bin/ldd anyway (printing
out the contents of apparmor.aa.cfg['settings']['ldd'] after the set
operation shows it to still contain '/usr/bin/ldd' o.O). Therefore, skip
these two tests when running under python2.7.
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Christian Boltz <apparmor@cboltz.de>
Bug: https://launchpad.net/bugs/1522938
This turned out to be a simple case of misinterpreting the promptUser()
result - it returns the answer and the selected option, and
"surprisingly" something like
('CMD_ADDHAT', 0)
never matched
'CMD_ADDHAT'
;-)
I also noticed that the new hat doesn't get initialized as
profile_storage(), and that the changed profile doesn't get marked as
changed. This is also fixed by this patch.
References: https://bugs.launchpad.net/apparmor/+bug/1538306
Acked-by: Steve Beattie <steve@nxnw.org> for trunk, 2.10 and 2.9
pyflakes3 doesn't check sys.version and therefore complains about
'unicode' being undefined.
This patch defines unicode as alias of str to make pyflakes3 happy, and
as a side effect, simplifies type_is_str().
Acked-by: Seth Arnold <seth.arnold@canonical.com> for trunk and 2.10.
By calling self.delete() inside the delete_duplicates() loop, the
self.rules list was modified. This resulted in some rules not being
checked and therefore (some, not all) superfluous rules not being
removed.
This patch switches to a temporary variable to loop over, and rebuilds
self.rules with the rules that are not superfluous.
This also fixes some strange issues already marked with a "Huh?" comment
in the tests.
Acked-by: Seth Arnold <seth.arnold@canonical.com> for trunk and 2.10.
Note that in 2.10 cleanprof_test.* doesn't contain a ptrace rule,
therefore the cleanprof_test.out change doesn't make sense for 2.10.
Network events can come with an operation= that looks like a file event.
Nevertheless, if the event has a typical network parameter (like
net_protocol) set, make sure to store the network-related flags in ev.
This fixes the test failure introduced in my last commit.
Acked-by: Kshitij Gupta <kgupta8592@gmail.com> for trunk, 2.10 and 2.9
We already ignore network events that look like file events (based on
the operation keyword) if they have a request_mask of 'send' or
'receive' to avoid aa-logprof crashes because of "unknown" permissions.
It turned out that both can happen at once, so we should also ignore
this case.
Also add the now-ignored log event as test_multi testcase.
References: https://bugs.launchpad.net/apparmor/+bug/1577051#13
Acked-by: Tyler Hicks <tyhicks@canonical.com> for trunk, 2.10 and 2.9.
https://launchpad.net/bugs/1584069
This patch adds support for the safe and unsafe exec modes for
change_profile rules. The logic is pretty simple at this point because
the kernel's default for exec modes changed in newer versions.
Therefore, this patch simply retains any specified exec mode in parsed
rules. If an exec mode is not specified in a rule, there is no attempt
to force the usage of "safe" because older kernels do not support it.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
Acked-by: Christian Boltz <apparmor@cboltz.de>
This behaviour makes sense (for example to force the confined program to
use a fallback path), but is probably surprising for users, so we should
document it.
References: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=826218#37
Acked-by: John Johansen <john.johansen@canonical.com> for trunk, 2.10 and 2.9
Thanks to reading the wrong directory in read_inactive_profiles()
(profile_dir instead of extra_profile_dir), aa-genprof never asked about
using a profile from the extra_profile_dir.
Sounds like an easy fix, right? ;-)
After fixing this (last chunk), several other errors popped up, one
after the other:
- get_profile() missed a required parameter in a serialize_profile() call
- when saving the profile, it was written to extra_profile_dir, not to
profile_dir where it (as a now-active profile) should be. This is
fixed by removing the filename from existing_profiles{} so that it can
pick up the default name.
- CMD_FINISHED (when asking if the extra profile should be used or a new
one) behaved exactly like CMD_CREATE_PROFILE, but this is surprising
for the user. Remove it to avoid confusion.
- displaying the extra profile was only implemented in YaST mode
- get_pager() returned None, not an actual pager. Since we have 'less'
hardcoded at several places, also return it in get_pager()
Finally, also remove CMD_FINISHED from the get_profile() test in
test-translations.py.
(test-translations.py is only in trunk, therefore this part of the patch
is obviously trunk-only.)
Acked-by: Seth Arnold <seth.arnold@canonical.com> for trunk
Acked-by: John Johansen <john.johansen@canonical.com> for trunk + a 50% ACK for 2.10 and 2.9
Acked-by: Kshitij Gupta <kgupta8592@gmail.com> for trunk, 2.10 and 2.9
This patch includes several changes and fixes in change_profile highlighting:
- allow audit and deny keywords
- allow bare change_profile rules
- allow change_profile rules without '-> ...' part
- allow usage of the new 'safe' and 'unsafe' keywords
- ensure the exec condition starts with / or @
Acked-by: Seth Arnold <seth.arnold@canonical.com>
This commit touches up the .po files that generate warnings
when msgfmt processes them to create .mo files, at least with gettext
0.19.7-2ubuntu3 in Ubuntu 16.04 LTS. Example warning types cleaned up
include:
ce.po:7: warning: header field 'Last-Translator' still has the initial default value
ce.po:7: warning: header field 'Language' missing in header
de.po:6: warning: header field 'Language-Team' still has the initial default value
This commit also fixes up po files where the Report-Msgid-Bugs-To:
field had not been updated, setting it with the email address
'AppArmor list <apparmor@lists.ubuntu.com>'
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
Acked-by: Christian Boltz <apparmor@cboltz.de>
Those events are actually network events, so ideally we should map them
as such. Unfortunately this requires bigger changes, so here is a hotfix
that ignores those events and thus avoids crashing aa-logprof.
References: https://bugs.launchpad.net/apparmor/+bug/1577051https://bugs.launchpad.net/apparmor/+bug/1582374
Acked-by: Seth Arnold <seth.arnold@canonical.com> for trunk, 2.10 and 2.9
In detail, this means:
- handle ptrace events in logparser.py
- "translate" those events in aa.py - from log (logparser.py readlog())
to prelog (handle_children()) to log_dict (collapse_log()))
- finally ask the user about the ptrace in ask_the_questions()
(no code change needed there)
Note that these changes are not covered by tests, however they worked in
a manual test with the log examples in the libapparmor testsuite.
Unfortunately there's no example log for eavesdrop, so it might be a
good idea to a) add such a log line and b) test with it
Acked-by: Seth Arnold <seth.arnold@canonical.com>
Note: as discussed on #apparmor, I changed the mapping of peer_profile so
that it ends up in peer=(label=...) instead of the wrong peer=(name=...).
"Everywhere" means aa-mergeprof and aa-cleanprof. In theory also
aa-logprof, but that needs some code that parses dbus log events ;-)
Also add some dbus rules to the aa-cleanprof test profiles to ensure
superfluous dbus rules get deleted.
Acked-by: Seth Arnold <seth.arnold@canonical.com>
DBUS_Rule (in rules.py) was added in r2424 as a "this is how it should
look like" proof of concept, but was never used.
We have a "real" class for dbus rules now, so we can drop the proof of
concept class.
Also remove a commented, old version of RE_DBUS_ENTRY from aa.py
Acked-by: Seth Arnold <seth.arnold@canonical.com>
Change aa.py to use DbusRule and DbusRuleset in profile_storage,
parse_profile_data() and write_dbus. This also means we can drop the
now unused parse_dbus_rule() and write_dbus_rules() functions.
Raw_DBUS_Rule in rules.py is now also unused and can be dropped.
Also shorten the list of known-failing tests in
test-parser-simple-tests.py. Even if the list of removals doesn't look
too long, the generated_dbus/* removals mean 1989 tests now cause the
expected failures.
OTOH, I had to add 4 tests to the known-failing list:
- 3 tests with a "wrong" order of the conditionals which the parser
accepts (which is slightly surprising, because usually we enforce the
order of rule parts)
- one test fails because the path in the path= conditional doesn't start
with / or a variable. Instead, it starts with an alternation, which
wouldn't be allowed in file rules.
Those 4 failures need more investigation, but shouldn't block this
patchset.
Finally, adjust test-regex_matches.py to import RE_PROFILE_DBUS from
apparmor.regex instead of apparmor.aa.
Acked-by: Seth Arnold <seth.arnold@canonical.com>
The tests include the two tests from test-dbus_parse.py, therefore
delete this file.
As usual, we have 100% coverage :-)
Also addd an explicit str() conversion to common_test.py to avoid
TypeError: not all arguments converted during string formatting
Acked-by: Seth Arnold <seth.arnold@canonical.com>