2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-22 18:17:09 +00:00

58 Commits

Author SHA1 Message Date
Maxime Bélair
2448655188 logparser: add support for change_onexec logs
Add support for change_onexec logs by converting it to change_profile.
Fix associated test.

Signed-off-by: Maxime Bélair <maxime.belair@canonical.com>
2025-07-24 13:32:13 +02:00
Georgia Garcia
699d7b5c83 utils: fix cleanprof regression on header generation
Commit c9d41a3ebb introduced a regression on profile header
generation.

This commit removes the name parameter from the get_header function
since the ProfileStorage should already contain all the information
required to generate the header for profiles and hats. The tests
needed to be updated as well to make sure the ProfileStorage object
contained the information needed by the get_header method.

Fixes: c9d41a3ebb ("utils: fix profile and hat header generation")
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
2025-03-31 15:50:15 -03:00
Christian Boltz
c93d560f89
Switch test-libapparmor-test_multi.py from aa to active_profiles
Note that the old code assigned dummy_prof to aa[profile][hat] and
active_profiles[profile] (= the main/parent profile) - which is
diffferent when testing a log for a child profile.

aa[profile][hat] was the wrong place - but since we used exactly that
again when checking for added exec rules, this error was hidden.

Now that the test is switched to using active_profiles, only check the
main profile for exec rules added by ask_exec(). (This will need to be
adjusted when we add a test for exec rules/events in nested childs, but
not earlier ;-)
2024-12-17 22:51:12 +01:00
Christian Boltz
8eff7cd98f
test-multi: no longer expect testcase01, 12 and 13 to fail
'testcase01', 'testcase12' and 'testcase13' contain a strange mix of
exec and network events.

Nevertheless, there's enough information to parse them as good-enough
exec events. While this is not perfectly correct, it's better than
skipping these logs in this test.

Stop expecting that these profiles have a wrong content, and adjust them
so that they contain the (somewhat) expected exec rule.
2024-10-23 19:25:35 +02:00
Christian Boltz
02e2ce0ad9
test exec events/rules in test-libapparmor-test_multi.py
So far, exec events were accidentally skipped in
test-libapparmor-test_multi.py because aa[profile][hat] was not
initialized, and ask_exec() exited early because of this.

Initialize aa[profile][hat] in the test to fix this.

To avoid that someone needs to select "inherit" each time the tests run,
add an optional default_ans parameter to ask_exec(), and let the test
call it with 'CMD_ix'.

(In case you wonder - defaulting to CMD_cx would ask to sanitize the
environment. CMD_ix avoids this.)

Also, we have to copy over aa[profile][hat] to log_dict in the test
because ask_exec() modifies aa[...], but the test only checks its local
log_dict.

Finally, add the expected exec rules to the *.profile files
2024-10-23 19:25:35 +02:00
Christian Boltz
5d0fd65a69
test-libapparmor-test_multi.py: use reset_aa()
... instead of resetting various apparmor.aa variables manually.
2024-10-23 19:25:35 +02:00
Christian Boltz
209dd851b3
test_multi: no longer skip testcase31
It is handled correctly in the current codebase.

It would be even better if it would generate a link rule that includes
the source, but let's leave that for a later fix.
2024-10-23 19:25:32 +02:00
Christian Boltz
a4df6cba6a
Add support for asking about pivot_root to aa-logprof 2024-05-20 20:45:19 +02:00
Christian Boltz
b475ed0dec
Handle mount events/log entries without class
audit.log entries for mount events don't always include `class=mount`,
but can still be the base for mount rules.

Change logparser.py to also consider `operation=mount` as a mount event.

Actually we already had such a log and profile in our collection
(testcase_mount_01), but since it existed years before MountRule was
implemented, it was excluded in test-libapparmor-test_multi.py.
Therefore we didn't notice that it failed to produce a profile rule when
MountRule was introduced.

Remove testcase_mount_01 from the list of known failures so that it gets
tested - and fix the syntax error in the hand-written
testcase_mount_01.profile.

Also add testcase_mount_02 which is a mount event without fstype,
srcname and class.
2024-05-08 21:56:42 +02:00
Maxime Bélair
34821d16ce Adding userspace support for unix mediation 2024-03-29 13:09:06 +00:00
Mark Grassi
844a4dc393 Change string formatting method in Python tests 2023-02-19 16:54:38 -05:00
Georgia Garcia
4fb9b3d42b utils: add userns python tool support
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
2022-11-04 12:39:18 +00:00
Georgia Garcia
e492eb34b1 libapparmor tests: add userns denied logs
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
2022-10-27 18:24:55 +00:00
Mark Grassi
380bed3c9b Replace exit() with sys.exit(). 2022-08-28 22:40:28 -04:00
Mark Grassi
c57138f255 Order imports and module-level dunder name assignments. 2022-08-21 11:15:07 -04:00
Mark Grassi
dc384c48a8 Use triple double-quoted strings for docstrings. 2022-08-21 11:15:07 -04:00
Mark Grassi
96f7121944 Fix most PEP 8 whitespace, indentation, and major line length violations. 2022-08-21 11:15:07 -04:00
Mark Grassi
aff9bb8f81 Ensure no bool comparisons use equality comparisons. 2022-08-21 11:15:07 -04:00
Mark Grassi
7581c9e113 Speed up list creations, and change lists to tuples where appropriate.. 2022-06-26 22:18:56 -04:00
Mark Grassi
ca9920cf92 Avoid unnecessary memory copies when enlarging lists. 2022-06-26 12:06:22 +00:00
Christian Boltz
0ee225b498
import hasher from apparmor.common
... instead of indirectly using it via apparmor.aa
2021-08-24 22:48:19 +02:00
Christian Boltz
2a97d6b6bc
ProfileStorage: change 'profile' to 'is_hat'
The 'profile' flag means "this profile is a profile or a child profile,
but not a hat". Since that's true for most cases, rename the flag to
'is_hat'.

Note that `'profile' == True` translates to `'is_hat' == False`

Also adjust all code to switch from 'profile' to 'is_hat'.
2021-05-16 18:15:03 +02:00
Christian Boltz
e1af0cdeca
parse_profile_start(): get rid of pps_set_profile
This value is True if we are in a child profile (not: hat), but that's
information we get "for free", so there's no need to hand it around.
Besides that, it was wrongly set to False for main profiles (which are
not hats).

Remove the pps_set_profile return value from parse_profile_start(), and
always assume True unless we were parsing a hat. For completeness,
explicitely set it to False when parsing a hat.

To make sure child profiles and hats don't get mixed up, add a child
profile to cleanprof_test.{in,out}.

test-libapparmor-test_multi.py always interpreted foo//bar as being
a hat, therefore explicitely mark them as such. (Technically not really
needed since this is the default, but it helps to make things clear.)
2021-04-28 21:22:08 +02:00
Christian Boltz
0e5dca1083
serialize_profile(): use merged profile names in parameter
... and adjust all callers accordingly.
2021-04-15 12:53:08 +02:00
Christian Boltz
b1a1b5dc1b
ProfileList: allow storing actual profile data
Add a prof_storage parameter to add_profile() to hand over the actual
profile data/rules as ProfileStorage.

Also adjust several tests to hand over a (dummy) ProfileStorage object.

Note: For now, the parameter is optional because it needs some more changes
in aa.py to be really useable. This will change in a later commit.
2021-04-15 12:53:08 +02:00
Christian Boltz
a20865008f
collapse_log(): return merged profile names
... instead of the old [profile][hat] structure.

This needs changes in do_logprof_pass() when calling ask_the_questions()
(using merged_to_split() for now).

Also adjust test-libapparmor-test_multi.py logfile_to_profile() to
expect the merged structure.
2021-04-15 12:53:08 +02:00
Steve Beattie
461d9c2294
treewide: spelling/typo fixes in comments and docs
With the exception of the documentation fixes, these should all be
invisible to users.

Signed-off-by: Steve Beattie <steve.beattie@canonical.com>
Acked-by: Christian Boltz <apparmor@cboltz.de>
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/687
2020-12-01 12:47:11 -08:00
Christian Boltz
7918d8980b
Add change_profile support to aa-logprof
Note that the log doesn't include enough information for EXEC MODE and
EXEC COND, therefore aa-logprof will always propose ALL as EXEC COND
(comm= might give a hint about EXEC COND, but isn't good enough).

With the added support in aa-logprof, remove the changeprofile tests
from the known-failing list in test-libapparmor-test_multi.py.

Also add another test log (from darix) / expected profile to the
libapparmor testsuite.
2020-09-20 17:07:18 +02:00
Christian Boltz
fe3c0b0ef8
Get rid of the 'filelist' hasher()
Everything handled in 'filelist' gets handled in active_profiles now.

Note: the 'elif' branch in delete_all_duplicates() was probably never
hit because `if include.get(...)` always matched. The only possible
exception might be non-existing include files, but those cause a 'file
not found' error anyway.
2020-05-27 13:32:44 +02:00
Christian Boltz
874d3385a3
Stop writing to filelist[file]['profiles']
... because after the previous three commits, nothing reads/needs this
anymore

Note: file_name in ask_exec() was only used in the (dropped) filelist
usage.
2020-05-08 23:00:35 +02:00
Christian Boltz
5983598ef5
ProfileList: rename add() to add_profile()
This makes the syntax more clear, and is a preparation to allow adding
some more things (like global includes and variable definitions)
2020-05-03 22:37:20 +02:00
John Johansen
0349cf2d0a libapparmor: logparse: fix RECORD_INVALID for valid log
v2:
- parse partial log line broken at \n
- add testcase_dbus_10.* for partial log line
- remove quotes from  testcasw_dbus_09.profile

The following log format has been seen in the wild, and currently results
in a RECORD_INVALID

    [4835959.046111] audit: type=1107 audit(1561053426.749:186): pid=640 uid=103 auid=4294967295 ses=4294967295 msg='apparmor="ALLOWED" operation="dbus_method_call"  bus="system" path="/org/freedesktop/systemd1" interface="org.freedesktop.systemd1.Manager" member="LookupDynamicUserByName" mask="send" name="org.freedesktop.systemd1" pid=20596 label="/usr/sbin/sshd" peer_pid=1 peer_label="unconfined"
                      exe="/usr/bin/dbus-daemon" sauid=103 hostname=? addr=? terminal=?'

Test parsing the above message with and without the \n embedded between
peer_label= and exec=

Acked-by: Seth Arnold <seth.arnold@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
2019-07-02 01:01:37 -07:00
Christian Boltz
836caca462
collapse_log: ignore events from null-* profiles
If final_name still includes null-*, that's most likely caused by nested
execs which aren't supported by the tools yet. Ignoring them is better
than creating a useless null-* hat.

Note: The tools always had this restriction, so this is not a regression ;-)

Also note that test-libapparmor-test_multi expects that null-* hats get
created (which makes sense because the one-line log sniplets don't have
any exec indication), therefore add an optional parameter to keep this
behaviour for the tests.
2019-05-09 18:14:18 +02:00
Christian Boltz
387d1646c8
Merge handle_hashlog() into collapse_log()
Now that all log events arrive in hashlog, having a separate 'prelog' no
longer makes sense. Changing collapse_log() to accept 'hashlog' directly
removes that level of indirection.
2019-05-09 17:29:26 +02:00
Christian Boltz
c5f0097f65
make 'prelog' non-global
It's only used by two functions:
- handle_hashlog() - writes to prelog, and now returns it
- collapse_log() - reads prelog, and now gets it as parameter
2019-05-09 17:29:26 +02:00
Christian Boltz
c77426ed62
Introduce 'final_name' to hashlog and handle exec choices
'final_name' by default is the profile name, but ask_exec() will change
it for the target profile (which is a null-* profile at this stage)
based on exec mode choice. ask_addhat() will also change it based on the
chosen hat.

Choosing "deny" or "unconfined" will result in an empty final_name and
ignoring these log events.

All other choices set final_name to the full profile name ("foo" for Px,
"foo//bar" for Cx, current profile for ix).

Also fix the order of handling log events - since ask_exec() changes the
hashlog final_name, it has to run first so that ask_addhat() (which
"only" adjusts the hat name in final_name) and handle_hashlog() can work
with the updated profile name.

Finally, update test-libapparmor-test_multi.py to ignore final_name when
checking if hashlog is empty, and fix the call order of ask_exec() etc.
2019-05-09 17:29:26 +02:00
Christian Boltz
48cc1b2837
add a split_name() function to split a profile name
... into profile and hat.

Also change several places to use split_name().
2019-05-09 17:15:35 +02:00
Christian Boltz
45a3d8920a
Drop unused 'pid' parameter from ReadLog.__init__()
... and self.pid which is also unused.

This simple change also means to adjust all the code that uses ReadLog.
We get rid of log_pid in aa.py, and have to change lots of test-*
2019-05-09 17:15:35 +02:00
Christian Boltz
9a92909a89
Change read_log to return only hashlog
self.log is unused, drop it.

Also change all places that call read_log() to match the simplified
return value.
2019-05-09 17:15:35 +02:00
Christian Boltz
d2663b148a
Transform handle_children() to ask_exec()
The only remaining job of handle_children() was to handle exec events.
(And recursively calling itsself if it hits nested log events, but
logparser.py never created such a log structure.)

Therefore:
- drop the dead code handling nested log (type != str)
- rename the remaining function to ask_exec()
- drop checks for typ = 'exec' (now done as part of the for loop
- drop the "else" branch for unknown event types
- change 'return' to 'continue' because ask_exec handles all exec events
  in a loop instead of being called multiple times
- oh, and of course switch over to using hashlog

Finally, change do_logprof_pass() and the tests to call ask_exec()
instead of handle_children().

While on it, update a comment in test-translations.py which held the
last reference to handle_children().
2019-05-09 17:15:35 +02:00
Christian Boltz
560fb6fabe
Use hashlog for change_hat log events
Adjust logparser.py to store change_hat events in hashlog.

In aa.py,
- split off ask_addhat() from handle_children()
- change ask_addhat() to use hashlog
- call ask_addhat() from do_logprof_pass()

Also call ask_addhat() in test-libapparmor-test_multi.py to keep it in
sync with do_logprof_pass().
2019-05-03 00:12:46 +02:00
Christian Boltz
3d3667f38b
move path log event handling to hashlog
In logparser.py parse_event_for_tree, convert path handling to hashlog.
While on it, include 'owner' as part of hashlog so that aa.py doesn't
need to guess.

Also switch to a simple for loop instead of using log_str_to_mode() from
aamode.py to convert denied_mask to hasher keys (which would have been
needed to allow merging of several log events for the same path anyway).
Note that the check for 'mrawlk' (intentionally without 'x') is more
strict than the validate_log_mode(), but it should still cover all file
permissions. (validate_log_mode() also allows things like 'Px', which
we'll never hit in a logfile.)

In aa.py collapse_log() update the handling of path events to match the
additional [owner] key in hashlog/prelog. This makes the owner detection
in collapse_log() superfluous.

In aa.py handle_children(), remove 'path' handling from the 'path' or
'exec' section, and add an 'if True:' to avoid lots of whitespace
changes.

In aamode.py, drop the now unused split_mode() function, and
AA_OTHER_REMOVE() that was only used by split_mode().

Finally, remove sample log events with null-* hats from the list of
known failures in test-libapparmor-test_multi.py (we no longer filter
out null-* hats), and fix whitespace in two expected profiles.
2019-05-02 01:10:18 +02:00
Christian Boltz
6b63f49ad4
Remove a level of indirection on logparser.py
logparser.py puts each log event on a big "stack" in self.pid. Later,
handle_children() in aa.py then converts that (named 'log' in aa.py) to
the prelog hasher.

This commit changes logparser.py to create the prelog structure itsself
(named hashlog), which
- removes one level of indirection
- probably saves some memory because the hashlog automatically
  de-duplicates events

This commit does this for capability, network and signal events, and
adds the infrastructure needed for all event/rule types.

In aa.py, the new function handle_hashlog() copies the hashlog content
to prelog. OTOH, the now superfluous code handling capability, network
and signal events gets removed from handle_children().
Long-term, hashlog will replace log in aa.py. When this is done,
handle_hashlog() will be replaced by a simple prelog = hashlog.

logparser.py gets a new function init_hashlog() to initialize hashlog
for each profile. It also gets changed to store capability, network and
signal events into hashlog instead of storing them in self.pid.

hashlog uses the full profile name as key, which is the first baby step
to support nested child profiles. (for now, handle_hashlog() still
splits the profile name into profile and hat.)

Known issue: The new implementation doesn't handle exec yet, which means
that events get lost at the exec boundary (= in cases aa-logprof asks
which execute mode to use). This will be fixed in a later commit.
2019-05-01 21:22:36 +02:00
Christian Boltz
4d722f1839
Replace existing_profiles & fix minitools for named profiles
Technical stuff first:

Replace existing_profiles (a dict with the filenames for both active and
inactive profiles) with active_profiles and extra_profiles which are
ProfileList()s and store the active profiles and those in the extra
directory separately. Thanks to ProfileList, now also the relation
between attachments and filenames is easily available.

Also replace all usage of existing_profiles with active_profiles and
extra_profiles, and adjust it to the ProfileList syntax everywhere.

With this change, several bugs in aa-complain and the other minitools
get fixed:
- aa-complain etc. never found profiles that have a profile name
  (the attachment wasn't checked)
- even if the profile name was given as parameter to aa-complain, it
  first did "which $parameter" so it never matched on named profiles
- profile names with alternations (without attachment specification)
  also never matched because the old code didn't use AARE.

References: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=882047#92
(search for "As usual" ;-)

Just for completeness - the matching still doesn't honor/expand
variables in the profile name.
2018-10-23 00:28:37 +02:00
Christian Boltz
cf33ec99fc
test-libapparmor-test_multi.py: test for known-empty log
Add a check to logfile_to_profile() that checks the parsed log against a
list of input logs (log_to_profile_known_empty_log) that produce an
empty output.
2018-10-01 20:55:03 +02:00
Christian Boltz
7e42135010
fix serialize_profile() calls to always use a dict for options 2018-06-25 21:42:29 +02:00
Christian Boltz
79d9ee5c3b
test-libapparmor-test_multi: initialize parent profiles
If a log line contains a denial for a child profile, log_dict will
(obviously) only contain the child profile. However, serialize_profile()
expects that the parent profile is also initialized as ProfileStorage.

This patch makes sure the parent profile gets initialized.

It also removes 26 of the 37 reasons in the TODO note in aa.py :-)
2018-05-10 12:44:04 +02:00
Christian Boltz
0bc6078cfd
test-libapparmor-test_multi.py: allow to parse a specific logfile
test-libapparmor-test_multi.py converts the libapparmor test_multi log
examples to profiles.

This patch allows to call test-libapparmor-test-multi.py with a logfile
(containing a single log line) as parameter. It will then print the
resulting profile.

Example:

  # python3 test-libapparmor-test_multi.py /path/to/libraries/libapparmor/testsuite/test_multi/testcase_dbus_01.in
  /tmp/apparmor-2.8.0/tests/regression/apparmor/dbus_service {
    dbus send bus=session path=/org/freedesktop/DBus interface=org.freedesktop.DBus member=Hello peer=(label=unconfined),

  }
2018-05-06 17:59:18 +02:00
Christian Boltz
45922c6d21
make utils tests less verbose
Given the big number of tests, printing a dot for each test (instead of
multiple lines) is enough ;-)
2018-04-08 20:18:30 +02:00
Christian Boltz
ae692bfb3b Drop 'log' parameter from ReadLog
This parameter is always [], so we can simplify the ReadLog __init__()
parameters.

Note that some tests handed over '' instead of []. This was a bug, but
didn't matter because those tests only use a small portion of ReadLog.


Acked-by: Seth Arnold <seth.arnold@canonical.com>
2017-08-28 23:15:51 +02:00