The parser recently changed how/where deny information is applied.
commit 1fa45b7c1 ("parser: dfa minimization prepare for extended
permissions") removed the implicit filtering of explicit denies during
the minimization pass. The implicit clear allowed the explicit
information to be carried into the minimization pass and merged with
implicit denies. The end result being a minimized dfa with the explicit
deny information available to be applied post minimization, and
then dropped later at permission encoding in the accept entries.
Extended permission however enable carrying explicit deny information
into the kernel to fix certain bugs like complain mode not being
able to distinguish between implicit and explicit deny rules (ie.
deny rules get ignored in complain mode). However keeping explicit
deny information when unnecessary result in a larger state machine
than necessary and slower compiles.
commit 179c1c1ba ("parser: fix minimization check for filtering_deny")
Moved the explicit apply_and_clear_deny() pass to before minimization
to restore mnimization's ability to create a minimized dfa with
explicit and implicit deny information merged but this also cleared
the explicit deny information that used to be carried through
minimization. This meant that when the deny information was applied
post minimization it resulted in the audit and quiet information
being cleared.
This resulted in the query_label tests failing as they are checking
for the expected audit infomation in the permissions.
Fixes: 179c1c1ba ("parser: fix minimization check for filtering_deny")
Bug: https://gitlab.com/apparmor/apparmor/-/issues/461
Signed-off-by: John Johansen <john.johansen@canonical.com>
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1408
Approved-by: Ryan Lee <rlee287@yahoo.com>
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
(cherry picked from commit eb365b374d)
Signed-off-by: John Johansen <john.johansen@canonical.com>
If a user specifies a non-existing file to merge into the profiles
(`aa-mergeprof /file/not/found`), this results in a backtrace showing an
AppArmorBug because that file unsurprisingly doesn't end up in the
active_profiles filelist.
Handle this more gracefully by adding a read_error_fatal parameter to
read_profile() that, if set, forwards the exception. With that,
aa-mergeprof doesn't try to list the profiles in this non-existing file.
Note that all other callers of read_profile() continue to ignore read
errors, because aborting just because a single file in /etc/apparmor.d/
(for example a broken symlink) isn't readable would be a bad idea.
This bug was introduced in 4e09f315c3, therefore I propose this patch for 3.0..master
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1403
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
(cherry picked from commit 5ebbe788ea)
Signed-off-by: John Johansen <john.johansen@canonical.com>
Bash will try to read the passwd database to find the shell of a user if
$SHELL is not set. This causes zgrep to trigger
```
apparmor="DENIED" operation="open" class="file" profile="zgrep" name="/etc/nsswitch.conf" comm="zgrep" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
apparmor="DENIED" operation="open" class="file" profile="zgrep" name="/etc/passwd" comm="zgrep" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
```
if called in a sanitized environment. As the functionality of zgrep is
not impacted by a limited Bash environment, add deny rules to avoid the
potentially misleading AVC messages.
Signed-off-by: Georg Pfuetzenreuter <mail@georg-pfuetzenreuter.net>
(cherry picked from commit 48483f2ff8)
Signed-off-by: John Johansen <john.johansen@canonical.com>
Instead of always storing the name of the main profile, store the child
profile/hat name if we are in a child profile or hat.
As a result, we always get the correct "profile xy" header even for
child profiles when dumping the ProfileStorage object.
Also extend the tests to check that the name gets stored correctly.
(cherry picked from commit cb943e4efc)
Signed-off-by: John Johansen <john.johansen@canonical.com>
Seen on various VMs, my guess is that bash wants to translate a uid to a
username.
Log events (slightly shortened)
apparmor="DENIED" operation="open" class="file" profile="zgrep" name="/etc/nsswitch.conf" comm="zgrep" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
apparmor="DENIED" operation="open" class="file" profile="zgrep" name="/etc/passwd" comm="zgrep" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
I propose this patch for 3.0..master
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1357
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
(cherry picked from commit ab16377838)
Signed-off-by: John Johansen <john.johansen@canonical.com>
When the find fails but the insertion also fails, we leak the new node
that we generated. Delete the new node in this case to avoid leaking
memory.
The question remains, however, as to whether we should implement `operator==` in addition to `operator<` so that they are consistent with each other and `find` works correctly.
Signed-off-by: Ryan Lee <ryan.lee@canonical.com>
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1399
Approved-by: Georgia Garcia <georgia.garcia@canonical.com>
Merged-by: John Johansen <john@jjmx.net>
(cherry picked from commit 99261bad11)
Signed-off-by: John Johansen <john.johansen@canonical.com>
As I have read multiple MR mentioning the `nameservice-strict`. Therefore, I thought it would make sense to directly import it here.
To give some context, this abstraction is probably the most commonly included abstraction (after `base`). In `apparmor.d`, it is used by over 700 profiles (only counting direct import). Therefore, adding new rules can have an important impact over a lot of profiles.
Note: the abstraction is a direct import from https://gitlab.com/roddhjav/apparmor.d. The license is the same, I obviously kept Morfikov copyright line. However, I am not sure either or not the SPDX identifier can be used here.
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1368
Approved-by: Georgia Garcia <georgia.garcia@canonical.com>
Approved-by: Christian Boltz <apparmor@cboltz.de>
Approved-by: Ryan Lee <rlee287@yahoo.com>
Merged-by: Georgia Garcia <georgia.garcia@canonical.com>
(cherry picked from commit 68376e7fee)
Signed-off-by: John Johansen <john.johansen@canonical.com>
commit 1fa45b7c1 ("parser: dfa minimization prepare for extended
permissions") removed implicit filtering of explicit denies in the
minimization pass (the information was ignored in building the set of
final accept states).
The filtering of explicit denies reduces the size of the produced
dfa. Since we need to be smarter about when explicit denies are
kept (eg. during complain mode), and most dfas are limited to 65k
states we currently need to filter explicit deny perms by default.
To compensate commit 2737cb2c2 ("parser: minimization - remove
unnecessary second minimization pass") moved the
apply_and_clear_deny() to before minimization. However its check to
apply removal denials before minimization is broken. Remove minimization
triggering apply_and_clear_deny() and just set the FILTER_DENY flag
by default, until we have better selection of rules/conditions where
explicit deny information should be carried through to the backend.
Fixes: 2737cb2c2 ("parser: minimization - remove unnecessary second minimization pass")
Signed-off-by: John Johansen <john.johansen@canonical.com>
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1397
Approved-by: Georgia Garcia <georgia.garcia@canonical.com>
Merged-by: John Johansen <john@jjmx.net>
(cherry picked from commit e9d6e0ba14)
Signed-off-by: John Johansen <john.johansen@canonical.com>
io_uring and userns mediation are encoding permissions on the class
byte. This is a mistake that should never have been allowed.
With the addition of rule priorities the class byte mediates rule,
that ensure the kernel can determine a class is being mediated is
given the highest priority possible, to ensure class mediation can not
be removed by a deny rule. See
61b7568e1 ("parser: bug fix mediates_X stub rules.")
for details.
Unfortunately this breaks rule classes that encode permissions on the
class byte, because those rules will always have a lower priority and
the class mediates rule will always be selected over them resulting in
only the class mediates permission being on the rule class state.
Fix this by adding the mediaties class rules for these rule classes
with the lowest priority possible. This means that any rule mediating
the class will wipe out the mediates class rule. So add a new mediates
class rule at the same priority, as the rule being added.
This is a naive implementation and does result in more mediates rules
being added than necessary. The rule class could keep track of the
highest priority rule that had been added, and use that to reduce the
number of mediates rules it adds for the class.
Technically we could also get away with not adding the rules for allow
rules, as the kernel doesn't actually check the encoded permission but
whether the class state is not the trap state. But it is required with
deny rules to ensure the deny rule doesn't result in permissions being
removed from the class, resulting in the kernel thinking it is
unmediated. We also want to ensure that mediation is encoded for other
rule types like prompt, and in the future the kernel could check the
permission so we do want to guarantee that the class state has the
MAY_READ permission on it.
Note: there is another set of classes (file, mqueue, dbus, ...) which
encodes a default rule permission as
class .* <perm>
this encoding is unfortunate in that it will also add the permission
to the class byte, but also sets up following states with the permission.
thankfully, this accespt anything, including nothing generally isn't
valid in the nothing case (eg. a file without any absolute name). For
this set of classes, the high priority mediates rule just ensures
that the null match case does not have permission.
Fixes: 61b7568e1 parser: bug fix mediates_X stub rules.
Signed-off-by: John Johansen <john.johansen@canonical.com>
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1307
Approved-by: Georgia Garcia <georgia.garcia@canonical.com>
Merged-by: John Johansen <john@jjmx.net>
(cherry picked from commit b6e9df3495)
Signed-off-by: John Johansen <john.johansen@canonical.com>
af_protos.h is a generated table of the protocols created by looking
for definitions of IPPROTO_* in netinet/in.h. Depending on the
architecture, the order of the table may change when using -dM in the
compiler during the extraction of the defines.
This causes an issue because there is more than one IPPROTO defined
by the value 0: IPPROTO_IP and IPPROTO_HOPOPTS which is a header
extension used by IPv6. So if IPPROTO_HOPOPTS was first in the table,
then protocol=0 in the audit logs would be translated to hopopts.
This caused a failure in arm 32bit:
Output doesn't match expected data:
--- ./test_multi/testcase_unix_01.out 2024-08-15 01:47:53.000000000 +0000
+++ ./test_multi/out/testcase_unix_01.out 2024-08-15 23:42:10.187416392 +0000
@@ -12,7 +12,7 @@
Peer Addr: @test_abstract_socket
Network family: unix
Socket type: stream
-Protocol: ip
+Protocol: hopopts
Class: net
Epoch: 1711454639
Audit subid: 322
By the time protocol is resolved in grammar.y, we don't have have
access to the net family to check if it's inet6. Instead of making
protocol dependent on the net family, make the order of the
af_protos.h table consistent between architectures using -dD.
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1309
Approved-by: John Johansen <john@jjmx.net>
Merged-by: Georgia Garcia <georgia.garcia@canonical.com>
(cherry picked from commit 0ec0e2b035)
Signed-off-by: John Johansen <john.johansen@canonical.com>
This enables adding a priority to a rules in policy.
Rules have a default priority of 0. The priority prefix can be added
before the other currently support rule prefixes, ie.
[priority prefix][audit qualifier][rule mode][owner]
If present a numerical priority can be assigned to the rule, where the
greater the number the higher the priority. Eg.
priority=1 audit file r /etc/passwd,
priority=-1 deny file w /etc/**,
Rule priority allows the rule with the highest priority to completely
override lower priority rules where they overlap. Within a given
priority level rules will accumulate in standard apparmor fashion.
Eg. given
priority=1 w /*c,
priority=0 r /a*,
priority=-1 k /*b*,
/abc, /bc, /ac .. will have permissions of w
/ab, /abb, /aaa, .. will have permissions of r
/b, /bcb, /bab, .. will have permissions of k
User specified rule priorities are currently capped at the arbitrary
values of 1000, and -1000.
Notes:
* not all rule types support the priority prefix. Rukes like
- network
- capability
- rlimits
need to be reworked to properly preserve the policy rule structure.
* this patch does not support priority on rule blocks
* this patch does not support using a variable in the priority value.
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1261
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
the ix portion of file, causes x conflicts in regular priority. The
long term goal is to fix this by using dominance for x rules. But in
the mean time we can fix by giving the ix portion of the rule a
reduced priority.
Signed-off-by: John Johansen <john.johansen@canonical.com>
This enables adding a priority to a rules in policy, finishing out the
priority work done to plumb priority support through the internals in
the previous patch.
Rules have a default priority of 0. The priority prefix can be added
before the other currently support rule prefixes, ie.
[priority prefix][audit qualifier][rule mode][owner]
If present a numerical priority can be assigned to the rule, where the
greater the number the higher the priority. Eg.
priority=1 audit file r /etc/passwd,
priority=-1 deny file w /etc/**,
Rule priority allows the rule with the highest priority to completely
override lower priority rules where they overlap. Within a given
priority level rules will accumulate in standard apparmor fashion.
Eg. given
priority=1 w /*c,
priority=0 r /a*,
priority=-1 k /*b*,
/abc, /bc, /ac .. will have permissions of w
/ab, /abb, /aaa, .. will have permissions of r
/b, /bcb, /bab, .. will have permissions of k
User specified rule priorities are currently capped at the arbitrary
values of 1000, and -1000.
Notes:
* not all rule types support the priority prefix. Rukes like
- network
- capability
- rlimits need to be reworked
need to be reworked to properly preserve the policy rule structure.
* this patch does not support priority on rule blocks
* this patch does not support using a variable in the priority value.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Currently mediates_X stub rules are added to the dfa to ensure a valid
transition state will exist if X should be mediated. The kernel uses
this to test whether the dfa supports certain mediation classes.
Unfortunately the mediates stub rules can be removed by other rules,
combined with minimization. In the allow case this is not a problem,
as if the stub rule is removed it will be due to state merging and the
test will still be valid. Unfortunately the deny case can wipe out the
stub rule in a couple of cases, meaning the when the kernel tests that
its in a valid state for mediation it will fail and treat the dfa as
not mediating the rule type, which results in allowing instead of
denying.
Fix this by making sure mediated stub rules can't be overridden by a
deny rule by giving them maximum priority.
Note: there is another issue with stub rule elimination in the allow
case. It will can cause equality tests to fail when combined
with priority rules, because the stub rules where added at
priority 0 and an actual rule of higher priority could
completely override it removing the permission on the stub rule.
This issue will be caught by the equality.sh tests in the
following patch that exposes priority to rules in policy.
Signed-off-by: John Johansen <john.johansen@canonical.com>
The prefix comparison doesn't need to do as many operations as it is
doing, and the operator< can be based on the cmp() fn further reducing
the chance that the code will get out of sync if prefixes are changed.
Signed-off-by: John Johansen <john.johansen@canonical.com>
the parser front end boolean is used for both boolean and integer
values. This is confusing when integer values different than 1 or 0
are being assigned to and from boolean.
Split its uses into the correct semantic boolean and integer cases.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Currently use of extended perms are dependent on prompt rules being present
in policy. Switch to using extended perms if they are supported.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Moving apply_and_clear_deny() before the first minimization pass, which
was necessary to propperly support building accept information for
older none extended permission dfas, allows us to also get rid of doing a
second minimization pass if we want to force clearing explicit deny
info from extended permission tables.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Instead of compressing the permission set into 128 bit and using that
as the index in the permission map, just use the permissions directly
as the index into the permission map.
Note: this will break equality and minimization tests. Because deny
is not being cleared it will result in more partitions in the initial
setup. This will be addressed and the tests will be fixed in a follow
on patch.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Hash minimization was removed in
f0b154528 Fix dfa minimization
however some remnants of minimization remained. A comment and the use
of the hash but only as a 0 value. Drop this dead code and comment.
Signed-off-by: John Johansen <john.johansen@canonical.com>
The hfa stores next/check transitions in 16 bit fields to reduce memory
usage. However this means the state machine can on contain 2^16
states.
Allow the next/check tables to be 32 bit. This theoretically could allow
for 2^32 states however the base table uses the top 8 bits as flags
giving us only 2^24 bits to index into the next/check tables. With
most states having at least 1 transition this effectively caps the
number of states at 2^24.
To obtain 2^32 possible states a flags table needs to be added. Add
a skeleton around supporting a flags table, so we can note the remaining
work that needs to be done. This patch will only allow for 2^24 states.
Bug: https://gitlab.com/apparmor/apparmor/-/issues/419
Signed-off-by: John Johansen <john.johansen@canonical.com>
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1303
Approved-by: Georgia Garcia <georgia.garcia@canonical.com>
Merged-by: John Johansen <john@jjmx.net>
The hfa stores next/check transitions in 16 bit fields to reduce memory
usage. However this means the state machine can on contain 2^16
states.
Allow the next/check tables to be 32 bit. This theoretically could allow
for 2^32 states however the base table uses the top 8 bits as flags
giving us only 2^24 bits to index into the next/check tables. With
most states having at least 1 transition this effectively caps the
number of states at 2^24.
To obtain 2^32 possible states a flags table needs to be added. Add
a skeleton around supporting a flags table, so we can note the remaining
work that needs to be done. This patch will only allow for 2^24 states.
Bug: https://gitlab.com/apparmor/apparmor/-/issues/419
Signed-off-by: John Johansen <john.johansen@canonical.com>
Older kernels do not support an xtable grouped with the policy dfa.
The presence of a policy.dfa does not indicate whether we should create
an xtable with the policy dfa.
Instead the check should be if the kernel supports the extended
permstable32 format.
Signed-off-by: John Johansen <john.johansen@canonical.com>
__uint128 is not supported by gcc on 32 bit architectures so rework
the 128 bit map key to be a pair of 64bit numbers.
Signed-off-by: John Johansen <john.johansen@canonical.com>
switch permission bits to use perm32_t type. This is just annotating
the code as it is no different than uint32_t at this time.
We do not convert the accept values as they may be mapped permission
bits or they may be and index value.
Signed-off-by: John Johansen <john.johansen@canonical.com>
The use of xbits can not pass verification so we need to leave them
off this makes the profile a leaf profile.
Signed-off-by: John Johansen <john.johansen@canonical.com>
v1 of permstable32 has some broken verification checks. By using two
copies of a merged dfa and an xtable the same size of the permstable
we can work around the issue.
Signed-off-by: John Johansen <john.johansen@canonical.com>
There are two distinct declarations of perms_t.
rule.h: typedef uint32_t perms_t
hfa.h: class perms_t
these definitions clash when the front end and backend share more info.
To avoid this rename rule.h to perm32_t, and move the definition into
perms.h and use it in struct aa_perms.
Signed-off-by: John Johansen <john.johansen@canonical.com>
If extended permissions are supported use them. We need to build a
permission table and set the accept state of the chfa up as an index
into the table.
For now map the front end permission layout into the old format and
then convert that to the perms table just as the kernel does.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Add the ability to parse the prompt qualifier but do not provide
functionality because the backend does not currently support prompt
permissions.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Remove conditional logic from the parser and move it to its own class,
that way any improvements or conditional features will make cleaner
changes.
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
I couldn't figure out why the show info window was using a different
font color than the theme default but this forces its use.
Also, add padding when "Show Current Profile" button is not shown.
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
In this change, I'm also removing the messagebox window and reusing
the more info GUI already implemented
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
aa-notify: Enhanced Graphical User Interfaces
- Added support for --prompt-filter=userns: a popup GUI now appears when an unprivileged, unconfined process attempts to create a user namespace, enabling automatic generation of specific unconfined profiles.
- Added GUIs for easy rule addition.
- Upgraded notifications to two-button format, enabling extended information display and direct rule addition.
- Initial support for customized notification messages based on rule type.
Signed-off-by: Maxime Bélair <maxime.belair@canonical.com>
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1281
Approved-by: Georgia Garcia <georgia.garcia@canonical.com>
Merged-by: John Johansen <john@jjmx.net>
Code assumes full username would be printed, but this actually requires an extra command line option:

Please double check that this is the only place where `last` is called as a binary before merging this MR.
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1293
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
POSIX states that d_name has up to NAME_MAX (255) characters, and glibc
stores d_name as an array of size NAME_MAX+1 (256). Thus, supplying
PATH_MAX (4096) as the max length could trigger a buffer overrun. This
could be an even bigger issue on other libcs, as POSIX states that d_name
can be unsized.
Fortunately, this does not seem to cause actual issues, as the length is
only used to compare d_name to a short fixed string. However, it'd be better
to pass the actual correct max length to strnlen.
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1290
Approved-by: Georgia Garcia <georgia.garcia@canonical.com>
Merged-by: Georgia Garcia <georgia.garcia@canonical.com>
POSIX states that d_name has up to NAME_MAX (255) characters, and glibc
stores d_name as an array of size NAME_MAX+1 (256). Thus, supplying
PATH_MAX (4096) as the max length could trigger a buffer overrun. This
could be an even bigger issue on other libcs, as POSIX states that d_name
can be unsized.
Fortunately, this does not seem to cause actual issues, as the length is
only used to compare d_name to a short fixed string. However, it'd be better
to pass the actual correct max length to strnlen.
Signed-off-by: Ryan Lee <ryan.lee@canonical.com>
The linkage of aa-load with the dynamic libapparmor fails with:
aa_load.c:273: undefined reference to `aa_split_overlay_str'
That is because when aa_split_overlay_str was added to libapparmor,
the function was not added to the library map.
Fixes: 50054ff0 ("add aa_split_overlay_str")
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1288
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
The linkage of aa-load with the dynamic libapparmor fails with:
aa_load.c:273: undefined reference to `aa_split_overlay_str'
That is because when aa_split_overlay_str was added to libapparmor,
the function was not added to the library map.
Fixes: 50054ff0 ("add aa_split_overlay_str")
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
Commonly used by applications to determine if Linux is running in
FIPS mode. As we already allow access to FIPS specific library files
as part of base, allow this there as well.
Signed-off-by: Georg Pfuetzenreuter <mail@georg-pfuetzenreuter.net>
If the test ran under a fs mounted with nosuid option, then these bits
would be ignored and the test would fail. In that case, detect it and
run the test in a tmpfs mountpoint without nosuid.
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
When /tmp is of type tmpfs, the test didn't run because you can't
mount a swapfile on it. This patch mounts an ext2 mountpoint on
$tmpdir so that the swapfile can be mounted on top of it instead of
tmpfs.
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
When /tmp is mounted, remounting / as private for tests that don't
work when shared still fail because /tmp remains as shared. The option
-T in findmnt helps determine the mountpoint in a certain directory,
so use that with $tmpdir to determine the root.
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
The tests that use pivot_root or move mountpoints with mount have to
make sure that / is private for the tests to work. Refactor that logic
into a file to be sourced by the test scripts
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
The abi is not being respected by mqueue rules in many cases. If policy
does ot specify an mqueue rule the abi is correctly applied but if
an mqueue rule is specified explicitly or implicitly (eg. allow all).
without setting the mqueue type OR setting the mqueue type to sysv.
The abi will be ignored and mqueue will be enforced for policy regadless.
Known good mqueue rule that respects abi
mqueue type=posix,
# and all variations that keep type=posix
Known bad mqueue rules that do not respect abi
mqueue,
# and all variants that do not specify the type= option
mqueue type=sysv,
# and all variants that specify the type=sysv option
Issue: https://gitlab.com/apparmor/apparmor/-/issues/412
Fixes: d98c5c4cf ("parser: add parser support for message queue mediation")
Signed-off-by: John Johansen <john.johansen@canonical.com>
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1277
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
The kernel does not expect a name and it is not used even within the
parser so drop it. Correct the padding calculation.
sizeof(th_version)
includes the trailing \0 in the count so we should not be adding it
explicitly. Doing so made it seem like we were writing an extra byte
and messing things up, because the string write below did not include
the \0 which we had to add explicitly.
Switch to writing the th_version using size_of() bytes as is used in
the pad calculation, to avoid confusion around the header padding.
Signed-off-by: John Johansen <john.johansen@canonical.com>
The abi is not being respected by mqueue rules in many cases. If policy
does ot specify an mqueue rule the abi is correctly applied but if
an mqueue rule is specified explicitly or implicitly (eg. allow all).
without setting the mqueue type OR setting the mqueue type to sysv.
The abi will be ignored and mqueue will be enforced for policy regadless.
Known good mqueue rule that respects abi
mqueue type=posix,
# and all variations that keep type=posix
Known bad mqueue rules that do not respect abi
mqueue,
# and all variants that do not specify the type= option
mqueue type=sysv,
# and all variants that specify the type=sysv option
Issue: https://gitlab.com/apparmor/apparmor/-/issues/412
Fixes: d98c5c4cf ("parser: add parser support for message queue mediation")
Signed-off-by: John Johansen <john.johansen@canonical.com>
`execpath` allows to reliably store the path of the binary that triggered a log.
This is useful because comm was not sufficient to reliably identify a binary
Signed-off-by: Maxime Bélair <maxime.belair@canonical.com>
This reverts commit 78ae956087.
Commit 78ae956087 causes policy to not
to conform to protocol as determined by the kernel. Technically the
reverted patch is correct and the kernel is wrong but we can not
change 15 years of history.
The reason it breaks the policy in the kernel is because the kernel
does not use the name field, and does not expect it. It just expects
the size with a single trailing 0. This doesn't break because this
section is all padded to 64 bytes so writing the extra 0 doesn't
hurt as it is effectively just manually adding to the padding.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Some applications using the bwrap profile don't function properly due to "Failed name lookup - deleted entry". The following denials trying to start flatpak KeePassXC is an example showing that it happens for both bwrap and unpriv_bwrap profiles:
Jul 12 09:44:37 ubuntu2404 kernel: audit: type=1400 audit(1720741477.106:310): apparmor="DENIED" operation="link" class="file" info="Failed name lookup - deleted entry" error=-2 profile="bwrap" name="/home/\*\*\*\*/.var/app/org.keepassxc.KeePassXC/config/keepassxc/#317211" pid=4021 comm="keepassxc" requested_mask="l" denied_mask="l" fsuid=1000 ouid=1000
Jul 12 09:44:37 ubuntu2404 kernel: audit: type=1400 audit(1720741477.341:317): apparmor="DENIED" operation="link" class="file" profile="unpriv_bwrap" name="/home/**/.var/app/org.keepassxc.KeePassXC/config/keepassxc/keepassxc.ini" pid=4021 comm="keepassxc" requested_mask="l" denied_mask="l" fsuid=1000 ouid=1000 target="/home/**/.var/app/org.keepassxc.KeePassXC/config/keepassxc/#317214"
Fixes: https://launchpad.net/bugs/2072811
I propose this fix for master and apparmor-4.0
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1272
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
Without AA_MAY_MOUNT, mount was not allowed by the allow all
rule. AA_DUMMY_REMOUNT does become AA_MAY_MOUNT, but it fixes the
flags to remount only, so other options are not included. Also, add
allow all rule testcases to the mount regression tests.
Fixes: https://gitlab.com/apparmor/apparmor/-/issues/410
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
By specifying 0 in the unix type, all rules were allowing only the
"none" type, when it wanted to allow all types, so replace it by
0xffffffff. Also, add this testcase to the unix regression tests.
Fixes: https://gitlab.com/apparmor/apparmor/-/issues/410
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
Some applications using the bwrap profile don't function properly due
to "Failed name lookup - deleted entry". The following denials trying
to start flatpak KeePassXC is an example showing that it happens for
both bwrap and unpriv_bwrap profiles:
Jul 12 09:44:37 ubuntu2404 kernel: audit: type=1400 audit(1720741477.106:310): apparmor="DENIED" operation="link" class="file" info="Failed name lookup - deleted entry" error=-2 profile="bwrap" name="/home/****/.var/app/org.keepassxc.KeePassXC/config/keepassxc/#317211" pid=4021 comm="keepassxc" requested_mask="l" denied_mask="l" fsuid=1000 ouid=1000
Jul 12 09:44:37 ubuntu2404 kernel: audit: type=1400 audit(1720741477.341:317): apparmor="DENIED" operation="link" class="file" profile="unpriv_bwrap" name="/home/****/.var/app/org.keepassxc.KeePassXC/config/keepassxc/keepassxc.ini" pid=4021 comm="keepassxc" requested_mask="l" denied_mask="l" fsuid=1000 ouid=1000 target="/home/****/.var/app/org.keepassxc.KeePassXC/config/keepassxc/#317214"
Fixes: https://launchpad.net/bugs/2072811
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
Saw these couple of accesses fail recently on my Ubuntu 22.04 system:
`Jun 3 15:29:24 darkstar kernel: [5401883.070129] audit: type=1107 audit(1717442964.884:9223): pid=729 uid=102 auid=4294967295 ses=4294967295 subj=unconfined msg='apparmor="DENIED" operation="dbus_method_call" bus="system" path="/org/freedesktop/UPower" interface="org.freedesktop.DBus.Properties" member="GetAll" mask="send" name=":1.28" pid=2164500 label="firefox" peer_pid=2502 peer_label="unconfined"`
`Jun 3 15:29:24 darkstar kernel: [5401883.070588] audit: type=1107 audit(1717442964.884:9224): pid=729 uid=102 auid=4294967295 ses=4294967295 subj=unconfined msg='apparmor="DENIED" operation="dbus_method_call" bus="system" path="/org/freedesktop/UPower" interface="org.freedesktop.UPower" member="EnumerateDevices" mask="send" name=":1.28" pid=2164500 label="firefox" peer_pid=2502 peer_label="unconfined"`
Also, I noticed that the `firefox` profile in the Ubuntu 24.04 package has a rule for `/etc/writable/timezone` that is not present in Git. Figured that should be in here.
Fixes: https://gitlab.com/apparmor/apparmor/-/issues/409Closes#409
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1253
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
This is needed to avoid a "Conflicting profiles" error if there are two
profiles for an application, with one of them disabled.
This is not a theoretical usecase - for example, apparmor.d ships some
profiles that replace our "userns+unconfined" profiles. These profiles
use a different filename, and apparmor.d also creates a disable symlink
for the "userns+unconfined" profile it replaces.
I propose this patch for 4.0 and master.
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1264
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
... and not only for events in missing hats.
This fixes a crash if the log contains exec events for a hat where not
even the parent profile exists.
I propose this patch for master, 4.0 and 3.1.
(In 3.0, `aa` is still a `hasher` which avoids the crash, therefore it doesn't really need this patch.)
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1265
Approved-by: Georgia Garcia <georgia.garcia@canonical.com>
Merged-by: Christian Boltz <apparmor@cboltz.de>
Contrary to what the name would imply aa-unconfined displays info for
both confined and unconfined processes. Add a --short option that only
output processes that are not confined. Eg.
$ ./utils/aa-unconfined
17192 /snap/chromium/2890/usr/lib/chromium-browser/chrome (/snap/chromium/2890/usr/lib/chromium-browser/chrome --password-store=basic --disable-features=TFLiteLanguageDetectionEnabled) confined by 'snap.chromium.chromium (enforce)'
17395 /snap/chromium/2890/usr/lib/chromium-browser/chrome (/snap/chromium/2890/usr/lib/chromium-browser/chrome --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --crashpad-handler-pid=17337 --enable-crash-reporter=,snap --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,16674663885832976354,18417931519279121981,262144 --disable-features=TFLiteLanguageDetectionEnabled --variations-seed-version) confined by 'snap.chromium.chromium (enforce)'
17981 /snap/firefox/4451/usr/lib/firefox/firefox confined by 'snap.firefox.firefox (enforce)'
1353664 /tmp/.mount_OrcaSl7G1va5/bin/orca-slicer not confined
is trimmed to
$ ./utils/aa-unconfined --short
1353664 /tmp/.mount_OrcaSl7G1va5/bin/orca-slicer not confined
Signed-off-by: John Johansen <john.johansen@canonical.com>
The prompt/user upcall mode shows up as a mode of (user). And for
stacked policy with different modes (mixed) is used. Add these to the
list of modes to screen.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Add the ability to list applications that are unconfined and have
any open network socket open, both listening and non-listening.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Add the abiity to list applications that are unconfined and have
open connection ports that are not listening.
Signed-off-by: John Johansen <john.johansen@canonical.com>
The documentation of --paranoid is wrong. It lists all processes and
does not exclude based on whether it has a network port open.
Signed-off-by: John Johansen <john.johansen@canonical.com>
This is needed to avoid a "Conflicting profiles" error if there are two
profiles for an application, with one of them disabled.
This is not a theoretical usecase - for example, apparmor.d ships some
profiles that replace our "userns+unconfined" profiles. These profiles
use a different filename, and apparmor.d also creates a disable symlink
for the "userns+unconfined" profile it replaces.
* UnixRule: Fix handling of peers with a ? and peers that are/need to be quoted
`?` is a valid AARE char, add it to the regexes that match the AARE.
Also add some tests to ensure this is really fixed, and make the error
output of the tests more useful/verbose.
* Fix handling of quoted peers in UnixRule (and others)
In UnixRule (and probably also in other rules that use
print_dict_values()` and `initialize_cond_dict()`), the handling of
peers with a value that is quoted and/or needs to be quoted was broken
because
- quotes didn't get stripped in `initialize_cond_dict()`
- `print_dict_values()` didn't use `quote_if_needed()`
Note: print_dict_values also handles integers (like network ports).
Convert them to a string so that `if ' ' in data` in `quote_if_needed()`
doesn't explode.
Also enable the test that uncovered this bug.
Fixes: https://gitlab.com/apparmor/apparmor/-/issues/404Closes#404
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1262
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
In UnixRule (and probably also in other rules that use
print_dict_values()` and `initialize_cond_dict()`), the handling of
peers with a value that is quoted and/or needs to be quoted was broken
because
- quotes didn't get stripped in `initialize_cond_dict()`
- `print_dict_values()` didn't use `quote_if_needed()`
Note: print_dict_values also handles integers (like network ports).
Convert them to a string so that `if ' ' in data` in `quote_if_needed()`
doesn't explode.
Also enable the test that uncovered this bug.
`?` is a valid AARE char, add it to the regexes that match the AARE.
Also add some tests to ensure this is really fixed, and make the error
output of the tests more useful/verbose.
Note: One of the added tests (with a space in the peer name) uncovered a
bug in quote handling. This will be fixed in the next commit.
Fixes: https://gitlab.com/apparmor/apparmor/-/issues/404
Update the state machine readme to better reflect how the chfa is
encoded and works. It still needs a lot more but fixes several errors
in the doc and adds some info about state differential encoding, oobs,
and comb compression.
In addition fix an off by own error during chfa encoding. This has
likely never triggered as it gets hidden by being in a section that
is being in a section that is padded to an 8 byte boundary.
Signed-off-by: John Johansen <john.johansen@canonical.com>
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1244
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
Expression simplification can get into an infinite loop due to eps
pairs hiding behind and alternation that can't be caught by
normalize_eps() (which exists in the first place to stop a similar
loop).
The loop in question happens in AltNode::normalize when a subtree has
the following structure.
1. elseif (child[dir]->is_type(ALT_NODE)) rotate_node too
alt
/\
/ \
/ \
eps alt
/\
/ \
/ \
alt eps
/\
/ \
/ \
eps eps
2. if (normalize_eps(dir)) results in
alt
/\
/ \
/ \
alt eps
/\
/ \
/ \
alt eps
/\
/ \
/ \
eps eps
3. elseif (child[dir]->is_type(ALT_NODE)) rotate_node too
alt
/\
/ \
/ \
alt alt
/\ /\
/ \ / \
/ \ / \
eps eps eps eps
4. elseif (child[dir]->is_type(ALT_NODE)) rotate_node too
alt
/\
/ \
/ \
eps alt
/\
/ \
/ \
eps alt
/\
/ \
/ \
eps eps
5. if (normalize_eps(dir)) results in
alt
/\
/ \
/ \
alt eps
/\
/ \
/ \
eps alt
/\
/ \
/ \
eps eps
6. elseif (child[dir]->is_type(ALT_NODE)) rotate_node too
alt
/\
/ \
/ \
eps alt
/\
/ \
/ \
alt eps
/\
/ \
/ \
eps eps
back to beginning of cycle
Fix this by detecting the creation of an eps_pair in rotate_node(),
that pair can be immediately eliminated by simplifying the tree in that
step.
In the above cycle the pair creation is caught at step 3 resulting
in
3. elseif (child[dir]->is_type(ALT_NODE)) rotate_node too
alt
/\
/ \
/ \
alt eps
/\
/ \
/ \
eps eps
4. elseif (child[dir]->is_type(ALT_NODE)) rotate_node too
alt
/\
/ \
/ \
eps alt
/\
/ \
/ \
eps eps
which gets reduced to
alt
/\
/ \
/ \
eps eps
breaking the normalization loop. The degenerate alt node will be caught
in turn when its parent is dealt with.
This needs to be backported to all releases
Closes: https://gitlab.com/apparmor/apparmor/-/issues/398
Fixes: 846cee506 ("Split out parsing and expression trees from regexp.y")
Reported-by: Christian Boltz <apparmor@cboltz.de>
Signed-off-by: John Johansen <john.johansen@canonical.com>
Closes#398
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1252
Approved-by: Georgia Garcia <georgia.garcia@canonical.com>
Merged-by: John Johansen <john@jjmx.net>
Expression simplification can get into an infinite loop due to eps
pairs hiding behind and alternation that can't be caught by
normalize_eps() (which exists in the first place to stop a similar
loop).
The loop in question happens in AltNode::normalize when a subtree has
the following structure.
1. elseif (child[dir]->is_type(ALT_NODE)) rotate_node too
alt
/\
/ \
/ \
eps alt
/\
/ \
/ \
alt eps
/\
/ \
/ \
eps eps
2. if (normalize_eps(dir)) results in
alt
/\
/ \
/ \
alt eps
/\
/ \
/ \
alt eps
/\
/ \
/ \
eps eps
3. elseif (child[dir]->is_type(ALT_NODE)) rotate_node too
alt
/\
/ \
/ \
alt alt
/\ /\
/ \ / \
/ \ / \
eps eps eps eps
4. elseif (child[dir]->is_type(ALT_NODE)) rotate_node too
alt
/\
/ \
/ \
eps alt
/\
/ \
/ \
eps alt
/\
/ \
/ \
eps eps
5. if (normalize_eps(dir)) results in
alt
/\
/ \
/ \
alt eps
/\
/ \
/ \
eps alt
/\
/ \
/ \
eps eps
6. elseif (child[dir]->is_type(ALT_NODE)) rotate_node too
alt
/\
/ \
/ \
eps alt
/\
/ \
/ \
alt eps
/\
/ \
/ \
eps eps
back to beginning of cycle
Fix this by detecting the creation of an eps_pair in rotate_node(),
that pair can be immediately eliminated by simplifying the tree in that
step.
In the above cycle the pair creation is caught at step 3 resulting
in
3. elseif (child[dir]->is_type(ALT_NODE)) rotate_node too
alt
/\
/ \
/ \
alt eps
/\
/ \
/ \
eps eps
4. elseif (child[dir]->is_type(ALT_NODE)) rotate_node too
alt
/\
/ \
/ \
eps alt
/\
/ \
/ \
eps eps
whch gets reduces to
alt
/\
/ \
/ \
eps eps
breaking the normalization loop. The degenerate alt node will be caught
in turn when its parent is dealt with.
This needs to be backported to all releases
Closes: https://gitlab.com/apparmor/apparmor/-/issues/398
Fixes: 846cee506 ("Split out parsing and expression trees from regexp.y")
Reported-by: Christian Boltz <apparmor@cboltz.de>
Signed-off-by: John Johansen <john.johansen@canonical.com>
Adding mediation classes in unconfined profiles caused nested profiles
to be mediated, inside a container for example.
As a first step, skip the addition of mediation classes into the dfa.
The creation of unprivileged user namespaces is an exception, where we
always want to mediate it.
Fixes: https://bugs.launchpad.net/apparmor/+bug/2067900
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
technically a # leading a value in an assignment expression is allowed,
however people are also using it to a comment at the end of a line.
ie.
```
@{var1}=value1 # comment about this value or for a given system
```
this unsurprisingly leads to odd/unexpected behavior when the variable
is used.
```
allow rw /@{var1},
```
expands into
```
allow rw /{value1,#,comment,about,this,value,or,for,a,given,system},
```
change a leading # of a value in an assignment expression to a comment.
If the # is really supposed to lead the value, require it to be escaped
or in quotes.
ie.
```
@{var1}=value1 \#not_a_comment
```
Note: this could potentially break som policy if the # was used as the
leading character for a value in an assignment expression, but
is worth it to avoid the confusion.
Signed-off-by: John Johansen <john.johansen@canonical.com>
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1255
Approved-by: Georgia Garcia <georgia.garcia@canonical.com>
Merged-by: John Johansen <john@jjmx.net>
The parser writes
sizeof(th)) + th_version + (char)0 + name + (char)0;
but the padding currently is computed as
sizeof(th)) + th_version + name + (char)0;
missing the internal (char)0, add 1 to the pad and fill to ensure
this is correct.
Reported-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
Update the state machine readme to better reflect how the chfa is
encoded and works. It still needs a lot more but fixes several errors
in the doc and adds some info about state differential encoding, oobs,
and comb compression.
Signed-off-by: John Johansen <john.johansen@canonical.com>
technically a # leading a value in an assignment expression is allowed,
however people are also using it to a comment at the end of a line.
ie.
@{var1}=value1 # comment about this value or for a given system
this unsurprisingly leads to odd/unexpected behavior when the variable
is used.
allow rw /@{var1},
expands into
allow rw /{value1,#,comment,about,this,value,or,for,a,given,system},
change a leading # as value in an assignment expression to a comment.
If the # is really supposed to lead the value, require it to be escaped
or in quotes.
ie.
@{var1}=value1 \#not_a_comment
Note: this could potentially break som policy if the # was used as the
leading character for a value in an assignment expression, but
is worth it to avoid the confusion.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Similarly to https://gitlab.com/apparmor/apparmor/-/merge_requests/689, use the
global CFLAGS when building Python library, so we honor extra flags set by
distributions, such
as -fstack-protector-strong -fstack-clash-protection -Werror=format-security -fcf-protection.
Spotted by blhc on Debian.
Gbp-Pq: Name Honor-global-CFLAGS-when-building-Python-library.patch
This file contains the same kind of information as @{PROC}/@{pid}/net/route
and both files are world readable:
```
$ ls -l /proc/self/net/*route
-r--r--r-- 1 root root 0 Jun 3 15:33 /proc/self/net/ipv6_route
-r--r--r-- 1 root root 0 Jun 3 15:33 /proc/self/net/route
```
Signed-off-by: Simon Deziel <simon.deziel@canonical.com>
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1246
Approved-by: Christian Boltz <apparmor@cboltz.de>
Merged-by: Christian Boltz <apparmor@cboltz.de>
This file contains the same kind of information as @{PROC}/@{pid}/net/route
and both files are world readable:
```
$ ls -l /proc/self/net/*route
-r--r--r-- 1 root root 0 Jun 3 15:33 /proc/self/net/ipv6_route
-r--r--r-- 1 root root 0 Jun 3 15:33 /proc/self/net/route
```
Signed-off-by: Simon Deziel <simon.deziel@canonical.com>
aa-remove-unknown doesn't deal properly with profiles that contain
spaces in their names.
Using profile "MongoDB Compass" as an example, awk's sub returns the
number of matches - either 1 or 0 and replaces the actual string ($0)
with the substitution. By accessing the return of sub with $, awk
would be accessing $1 which would return only "MongoDB".
Fix this by using $0 instead of $str.
Fixes: https://gitlab.com/apparmor/apparmor/-/issues/395
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
Closes#395
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1243
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
In the course of preparing !1207, I found that the validation rules in `profiles/Makefile` did not take kindly to the new `profiles/apparmor/profiles/extras/abstractions/` directory. I tried a couple rounds of quick fixes, but it became clear that the rules as currently written were just not amenable to the new addition, and needed more attention than I could give it by-the-by.
So I separated out that commit, and revised the makefile more thoroughly. The updated rules now rely more on `find(1)` than `$(wildcard)`, and have a number of [what I believe to be] small quality-of-life improvements. Taken together, `make check` passes cleanly with the new files from my other MR present.
One thing I noticed was that the profiles under `apparmor.d/` were not previously being checked for the `include if exists <local/*>` bit---only the ones under `extras/`. I've thus included a fix to the `sbuild-shell` profile, which fortunately was the only one that failed the check.
Note that at present, you'll get a couple of harmless `find: ‘./apparmor/profiles/extras/abstractions’: No such file or directory` errors when running the checks, since that directory won't appear until the other MR is merged. I figure, better to bear that for now, and not have to touch the makefile again later.
NOTE: The CI pipeline here will need to be updated to invoke the `check-local` target instead of `check-extras`. This target was renamed as it is no longer limited in scope to the profiles under `extras/`.
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1214
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
aa-remove-unknown doesn't deal properly with profiles that contain
spaces in their names.
Using profile "MongoDB Compass" as an example, awk's sub returns the
number of matches - either 1 or 0 and replaces the actual string ($0)
with the substitution. By accessing the return of sub with $, awk
would be accessing $1 which would return only "MongoDB".
Fix this by using $0 instead of $str.
Fixes: https://gitlab.com/apparmor/apparmor/-/issues/395
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
Without this patch, aa-remove-unknown uses 'profile_name (unconfined)'
when trying to unload unconfined profiles, which fails for obvious
reasons with (picking a random example)
Removing 'busybox (unconfined)'
/sbin/aa-remove-unknown: line 112: echo: write error: No such file or directory
I propose this patch for 4.0 and master.
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1240
Approved-by: Georgia Garcia <georgia.garcia@canonical.com>
Merged-by: Georgia Garcia <georgia.garcia@canonical.com>
Without this patch, aa-remove-unknown uses 'profile_name (unconfined)'
when trying to unload unconfined profiles, which fails for obvious
reasons with (picking a random example)
Removing 'busybox (unconfined)'
/sbin/aa-remove-unknown: line 112: echo: write error: No such file or directory
... and tests for it.
This replaces the old code that just stores the full rule as text.
We also get rid of the old ['allow'] and ['deny'] items in
ProfileStorage, the handling of old write functions, and the last usage
of _Raw_Rule (and therefore _Raw_Rule itsself).
Also delete the old test-pivot_root_parse.py which relied on the ancient
code, and even used a wrong syntax in its test rules.
Oh, and aa-logprof can now ask about pivot_root events.
See the individual commits for details.
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1232
Approved-by: Georgia Garcia <georgia.garcia@canonical.com>
Merged-by: Christian Boltz <apparmor@cboltz.de>
Mount Rules with options in { remount, [make-] { [r]unbindable, [r]shared, [r]private, and [r]slave }} do not support specifying a source. This commit aligns utils implementation to apparmor_parser's, which prohibits having a both source and a destination simultaneously, instad of just prohibiting source.
Therefore, both `mount options=(unbindable) /a,` and `mount options=(unbindable) -> /a,` are now supported (and equivalent for apparmor_parser). However, `mount options=(unbindable) /a -> /b,` is invalid.
For the same reason, specifying a fstype in these cases is also prohibited.
Similarly, we prohibit to specify a fstype for bind mount rules.
Fixes: https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/2065685
Signed-off-by: Maxime Bélair <maxime.belair@canonical.com>
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1236
Approved-by: Georgia Garcia <georgia.garcia@canonical.com>
Merged-by: Georgia Garcia <georgia.garcia@canonical.com>
Mount Rules with options in { remount, [make-] { [r]unbindable, [r]shared, [r]private, and [r]slave }} do not support specifying a source. This commit aligns utils implementation to apparmor_parser's, which prohibits having a both source and a destination simultaneously, instad of just prohibiting source.
Therefore, both `mount options=(unbindable) /a,` and `mount options=(unbindable) -> /a,` are now supported (and equivalent for apparmor_parser). However, `mount options=(unbindable) /a -> /b,` is invalid.
For the same reason, specifying a fstype in these cases is also prohibited.
Similarly, we prohibit to specify a fstype for bind mount rules.
Fixes: https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/2065685
Signed-off-by: Maxime Bélair <maxime.belair@canonical.com>
... for handling pivot_root rules.
This replaces the old code that just stores the full rule as text.
We also get rid of the old ['allow'] and ['deny'] items in
ProfileStorage, the handling of old write functions, and the last usage
of _Raw_Rule (and therefore _Raw_Rule itsself).
Also delete the old test-pivot_root_parse.py which relied on the ancient
code, and even used a wrong syntax in its test rules.
The following exceptions were added to flake8 since they have several
expected uses in the tools and their tests:
E501: Line lengths are recommended to be no greater than 79 characters.
E241: Multiple spaces after ','
W503: Line break occurred before a binary operator
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
ProfileStorage knows a whole profile, therefore it should also include the profile header in `__repr__()`.
Also add a test for this.
While on it, add a test for an invalid type change for a type that doesn't have special handling in `__setitem__()` to increase test coverage.
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1233
Approved-by: Georgia Garcia <georgia.garcia@canonical.com>
Merged-by: Christian Boltz <apparmor@cboltz.de>
Since musl 1.2.5, basename(3) prototype is only provided in libgen.h
(as mandated by POSIX) and not in strings.h. Also there is a major
difference between the gnu basename and the one defined in libgen.h,
the latter modify the argument string making them incompatible.
Fix this by defining a portable version of basename using strchr.
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1234
Approved-by: Georgia Garcia <georgia.garcia@canonical.com>
Merged-by: Georgia Garcia <georgia.garcia@canonical.com>
Since musl 1.2.5, basename(3) prototype is only provided in libgen.h
(as mandated by POSIX) and not in strings.h. Also there is a major
difference between the gnu basename and the one defined in libgen.h,
the latter modify the argument string making them incompatible.
Fix this by defining a portable version of basename using strchr.
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.
I propose this fix for 4.0 and master.
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1229
Approved-by: Georgia Garcia <georgia.garcia@canonical.com>
Merged-by: Georgia Garcia <georgia.garcia@canonical.com>
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.
Did some testing on a fresh post-release image of noble, and uncovered some new denials:
#### Xorg
`2024-05-06T19:55:36.782484-04:00 image-ubuntu64 kernel: audit: type=1400 audit(1715039736.765:174): apparmor="DENIED" operation="link" class="file" profile="Xorg" name="/tmp/.X0-lock" pid=1366 comm="Xorg" requested_mask="r" denied_mask="r" fsuid=0 ouid=0 target="/tmp/.tX0-lock"`
#### chromium_browser
`2024-05-06T21:17:09.674963-04:00 image-ubuntu64 kernel: audit: type=1400 audit(1715040834.256:168): apparmor="DENIED" operation="userns_create" class="namespace" profile="chromium_browser" pid=2133 comm="chromium" requested="userns_create" denied="userns_create"`
#### firefox
`2024-05-06T21:33:09.387356-04:00 image-ubuntu64 kernel: audit: type=1400 audit(1715045589.369:505): apparmor="DENIED" operation="userns_create" class="namespace" profile="firefox" pid=3610 comm="firefox" requested="userns_create" denied="userns_create"`
`2024-05-06T21:36:48.911280-04:00 image-ubuntu64 kernel: audit: type=1400 audit(1715045808.884:682): apparmor="DENIED" operation="open" class="file" profile="firefox" name="/sys/fs/cgroup/user.slice/user-1000.slice/session-c2.scope/cpu.max" pid=4348 comm="firefox" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0`
`2024-05-06T21:42:34.152955-04:00 image-ubuntu64 dbus-daemon[1628]: apparmor="DENIED" operation="dbus_bind" bus="session" name="org.mpris.MediaPlayer2.firefox.instance_1_82" mask="bind" pid=4348 label="firefox"`
#### Xorg (second commit)
I neglected to set `abi/4.0` when this went in originally. (I was using the profile on jammy, hence the `3.0`.)
Also, testing on an older laptop that *doesn't* support KMS revealed that Xorg needs some pretty serious permissions then. I've added them in commented-out form, with an explanatory comment. (The `#nokms#` bit is meant to simplify uncommenting those two lines mechanically, e.g. `sed -i 's/#nokms#//'`)
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1227
Approved-by: Georgia Garcia <georgia.garcia@canonical.com>
Approved-by: Christian Boltz <apparmor@cboltz.de>
Merged-by: Christian Boltz <apparmor@cboltz.de>
Balena Etcher runs in a degraded sandbox mode when unprivileged userns
is not available. Add an unconfined profile so it's properly
sandboxed.
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
Shellcheck is complaining that some of the functions are never called,
but they are called from rc.apparmor.functions, causing a false
positive.
This issue only appears in shellcheck version 0.9.0, which is the one
used in ubuntu 24.04, that's why it only failed in the pipeline now.
Fixes: https://gitlab.com/apparmor/apparmor/-/issues/388
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
Since we are using ubuntu:latest, and noble was released, some tests
are failing.
shellcheck needs python3 to run, which was possibly installed by
default in previous ubuntu images and is no longer the case.
Ignore dist-packages python files during our coverage tests.
Fixes: https://gitlab.com/apparmor/apparmor/-/issues/388
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
Rename the "check-extras" target to "check-local" as it is no longer
limited to the extra profiles, and also fix a local include in the
sbuild-shell profile so that it passes the newly-applied CI check.
Add a flag that allows setting the error code AppArmor will send when
an operation is denied. This should not be used normally.
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
This is a profile to contain the Xorg X11 server, which still runs as root in many scenarios (not least under [LightDM](https://github.com/canonical/lightdm/issues/18)).
I've tested this under every X display manager available in Debian/Ubuntu, as well as plain `startx(1)`. Both rootful and rootless modes are covered. The hardware I've tried this on predominantly uses Intel integrated graphics, with one Nouveau system represented. If someone has an Nvidia GPU running the proprietary driver, that would be a good data point to double-check, owing to the different driver architecture.
As you can see, I avoided going too far into the weeds enumerating everything the X server needs to run. The general pattern I found was that it needs read access to a lot of things, but write access to relatively few.
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1075
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
This updates the man page for the recent inet mediation patch.
This is an extension of MR 1202, it adds a patch that changes the anonymous ip address anon to be ip address none which is a better fit.
This patch adds documentation of the recent network changes which extended all network rules to support access permissions, and added address and port matching for inet and inet6 families.
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1213
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
inet mediation allows specifying rules for sockets that don't have
a known address, whether because it is unbound or because the
kernel doesn't make the address available.
The current code uses the word anon for anonymous, but that has
proven to be unclear. Switch from using anon to none, to emphasize
that this is a case where there just isn't an address to use as
part of mediation.
Signed-off-by: John Johansen <john.johansen@canonical.com>
When a family is specified in the network rules, we have to make sure
the conditionals match the family. A netlink rule should not be able
to specify ip and port for local and remote (peer) sockets, for example.
When type or protocol is specified in network rules along with inet
conditionals, we should only generate rules for the families that
support those conditionals.
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
The bwrap and unshare profiles are special profiles in the same
vein as the unconfined profiles but they actual enforce restrictions
on the applications that are launched.
As such they have come to late in the 4.0 dev cycle to consider enabling
by default. Disable them but ship them so users or distros can easily
enable them.
Signed-off-by: John Johansen <john.johansen@canonical.com>
This adds a bwrap profile to allow it to function on a system with
user namespace restrictions enabled.
The child task of bwrap will enter into a profile without capabilities
thus preventing bwrap from being able to be used to arbitrarily
by-pass user namespace restrictions.
This profile does prevent applications launch with privilege (eg.
sudo bwrap ...) from functioning so it may break some use cases.
Note: The unpriv_bwrap profile is deliberately stacked against the
bwrap profile due to bwraps uses of no-new-privileges.
Fixes: https://bugs.launchpad.net/ubuntu/+source/pageedit/+bug/2046844
Signed-off-by: John Johansen <john.johansen@canonical.com>
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1205
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
This adds a bwrap profile to allow it to function on a system with
user namespace restrictions enabled.
The child task of bwrap will enter into a profile without capabilities
thus preventing bwrap from being able to be used to arbitrarily
by-pass user namespace restrictions.
This profile does prevent applications launch with privilege (eg.
sudo bwrap ...) from functioning so it may break some use cases.
Note: The unpriv_bwrap profile is deliberately stacked against the
bwrap profile due to bwraps uses of no-new-privileges.
Fixes: https://bugs.launchpad.net/ubuntu/+source/pageedit/+bug/2046844
Signed-off-by: John Johansen <john.johansen@canonical.com>
The version of tarball version of firefox downloaded from mozilla.org
installs to /opt/firefox/firefox. Support this location so that the
firefox from the tarball works.
Note this does not support running firefox from the users home directory
in this case the user must update the profile accordingly.
Signed-off-by: John Johansen <john.johansen@canonical.com>
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1203
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
This adds an unshare profile to allow it to function on a system
with user namespace restrictions enabled.
The child task of unshare will enter into a profile without capabilities
thus preventing unshare from being able to arbitrarily being used to
by-pass the user namespace restriction.
This profile does prevent applications launch with privilege (eg.
sudo unshare ...) from functioning so it may break some use cases.
Signed-off-by: John Johansen <john.johansen@canonical.com>
The version of tarball version of firefox downloaded from mozilla.org
installs to /opt/firefox/firefox. Support this location so that the
firefox from the tarball works.
Note this does not support running firefox from the users home directory
in this case the user must update the profile accordingly.
Signed-off-by: John Johansen <john.johansen@canonical.com>
In some cases, ldd might obtain information by executing the given
binary (see ldd(1)) - which is not something we should do on potentially
unknown binaries, especially because aa-genprof and aa-autodep (and
therefore also ldd) are often started as root.
Additionally, the ldd result typically listed libraries already covered
by abstractions/base, which makes the ldd call superfluous.
While on it,
- remove all references to ldd
- remove code only used for calling ldd and handling its results
- remove tests checking ldd results, and the fake_ldd script
- adjust a test where fake_ldd had added some libraries
- remove ldd path from logprof.conf [settings]
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1201
Approved-by: Georgia Garcia <georgia.garcia@canonical.com>
Merged-by: Christian Boltz <apparmor@cboltz.de>
- Before this commit, fstype had to match a known fs. However, having and maintaining the exhaustive list of fstypes proved challenging (see !1195 and !1176). Therefore, we add support for any filesystem name.
- Completing AARE support for fstype (brace expressions like ext{3,4} are now supported).
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1198
Approved-by: Christian Boltz <apparmor@cboltz.de>
Merged-by: Christian Boltz <apparmor@cboltz.de>
- Before this commit, fstype had to match a known fs. However, having and maintaining the exhaustive list of fstypes proved challenging (see !1195 and !1176). Therefore, we add support for any filesystem name.
- Completing AARE support for fstype (brace expressions like ext{3,4} are now supported).
In some cases, ldd might obtain information by executing the given
binary (see ldd(1)) - which is not something we should do on potentially
unknown binaries, especially because aa-genprof and aa-autodep (and
therefore also ldd) are often started as root.
Additionally, the ldd result typically listed libraries already covered
by abstractions/base, which makes the ldd call superfluous.
While on it,
- remove all references to ldd
- remove code only used for calling ldd and handling its results
- remove tests checking ldd results, and the fake_ldd script
- adjust a test where fake_ldd had added some libraries
- remove ldd path from logprof.conf [settings]
Give access to @{HOMEDIRS}, just like in usr.sbin.smbd, so that
usershares in /home/ can be accessed.
apparmor="DENIED" operation="open" class="file" profile="samba-rpcd-classic" name="/home/user/path/to/usershare/" pid=4781 comm="rpcd_classic" requested_mask="r" denied_mask="r" fsuid=0 ouid=1000
- Adding support for --output-dir in aa-logprof and aa-genprof, allowing to work on profiles without applying the modified version
- Adding support for --allow-all in aa-logprof that creates non-interactively 'allow' rules for all logs
- Adding support for --no-abstraction in aa-logprof and aa-genprof
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1177
Approved-by: Christian Boltz <apparmor@cboltz.de>
Merged-by: Christian Boltz <apparmor@cboltz.de>
When the setup of the notify options failed, they were exiting the
program without cleaning up the mqueue. Fix this by returning instead
of exiting, since the main function does the cleanup in case of any
failures. If the test succeeds, then it exits successfully.
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
mq_notify only notifies if the queue is empty, so if the sender wins
the race and sends a message before mq_notify is set up, mq_notify
will timeout.
Adding synchronization using pipes the same way it was used in the
setns tests should fix it. The pipe now needs rw permissions, so add
that to the tests.
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
The child which sends the message was winning the race and causing a
timeout when the receiver was waiting for the message.
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
net_inet makes more sense since other finegrained network types can be
added in the future.
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
The abstraction lxc/start-container shipped by the liblxc-common
package uses the following mount rule which was not allowed by our
regexes:
mount options=(rw, make-slave) -> **,
mount options=(rw, make-rslave) -> **,
Since in AppArmor regex ** includes '/' but * by itself doesn't, I'm
adding explicit support for **.
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1195
Approved-by: Christian Boltz <apparmor@cboltz.de>
Merged-by: Georgia Garcia <georgia.garcia@canonical.com>
The abstraction lxc/start-container shipped by the liblxc-common
package uses the following mount rule which was not allowed by our
regexes:
mount options=(rw, make-slave) -> **,
mount options=(rw, make-rslave) -> **,
Since in AppArmor regex ** includes '/' but * by itself doesn't, I'm
adding explicit support for **.
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.