2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-31 22:35:35 +00:00

Compare commits

...

31 Commits

Author SHA1 Message Date
Georgia Garcia
6ac6524beb Prepare for AppArmor 3.0.13 release
- update version file

Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
2024-02-02 19:35:48 -03:00
John Johansen
3955b5a499 Merge Prevent ANSI terminal injection in aa-unconfined
/proc/$pid/cmdline can be changed by an application, therefore escape it
before printing.

The program name in /proc/$pid/exe can also contain any characters
(except \0 and shashes) and needs escaping.

Note: repr() wraps the string into single quotes, which we have to
remove to avoid changing the output format.

The test program from issue 364 now gets displayed as

    28443 /path/to/issue364 (/\x1b]0;X\x07) not confined

Fixes: https://gitlab.com/apparmor/apparmor/-/issues/364

I propose this patch for 2.13..master

Closes #364
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1142
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>

(cherry picked from commit e63c1e3a76)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2024-01-30 01:48:33 -08:00
John Johansen
b7d0b5e0e4 Merge doc(fix): Fix wrong syntax for profile stacking
Add missing change_profile entry required for the example

Signed-off-by: Mostafa Emami <mustafaemami@gmail.com>

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1141
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
(cherry picked from commit 3e28d0a254)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2024-01-30 01:48:20 -08:00
John Johansen
1fb230f11f Merge manpages: Add ENOPROTOOPT error in aa_getcon() manpage
The call aa_getpeercon() can return ENOPROTOOPT error in some cases, specifically when the kernel lacks 'fine grained unix mediation'. Currently, this capability isn't available in upstream kernels, but only in patched ones (for example, the regular Ubuntu kernels). Unfortunately, the manpage lacks this info. This patch fixes this.

Fixes: https://gitlab.com/apparmor/apparmor/-/issues/366
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1143
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
(cherry picked from commit b03abbd75f)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2024-01-30 01:48:11 -08:00
Georgia Garcia
68930e61d8 Merge [3.0] ask_exec(): no longer skip exec events in hats
Instead of ignoring all exec events that happen in a hat/child profile, only disallow child exec. ix and px are valid options inside a hat and are now offered to the user.

(When the tools support nested child profiles one day, we can even allow child exec again.)

Backported from dfb6f90aee / https://gitlab.com/apparmor/apparmor/-/merge_requests/1133 to match the 3.1 branch

For 3.0, this also needed backporting another commit:

Fix crash caused by ask_exec()

ask_exec still uses aa[profile][hat], therefore
- use full_profile when accessing hashlog
- correctly split the merged profile name to profile and hat
- avoid accidently initializing non-existing aa[profile][hat]

This fixes a regression from converting lots of code to use flat
profile//hat array keys.

(cherry picked from commit 755b5d11e1)

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1135
Approved-by: Georgia Garcia <georgia.garcia@canonical.com>
Merged-by: Georgia Garcia <georgia.garcia@canonical.com>
2024-01-03 13:40:38 +00:00
Christian Boltz
0a26ce3acd ask_exec(): no longer skip exec events in hats
Instead of ignoring all exec events that happen in a hat/child profile,
only disallow child exec. ix and px are valid options inside a hat and
are now offered to the user.

(When the tools support nested child profiles one day, we can even allow
child exec again.)

Backported from dfb6f90aee /
https://gitlab.com/apparmor/apparmor/-/merge_requests/1133 to match the
3.1 branch

(cherry picked from commit 0e70ad9b7c)
2023-12-28 23:51:31 +01:00
Christian Boltz
abcf4a8756 Fix crash caused by ask_exec()
ask_exec still uses aa[profile][hat], therefore
- use full_profile when accessing hashlog
- correctly split the merged profile name to profile and hat
- avoid accidently initializing non-existing aa[profile][hat]

This fixes a regression from converting lots of code to use flat
profile//hat array keys.

(cherry picked from commit 755b5d11e1)
2023-12-28 23:49:56 +01:00
John Johansen
caccb88a9b Merge Fix typo in apparmor_parser manpage
man apparmor_parser gives examples for the --warn command line option as

             apparmor_parser --warn=rules-not-enforced ...
and
             apparmor_parser --warn=no-rules-not-enforced ...

but the actual --warn options are rule-not-enforced / no-rule-not-enforced
(without s)

Fixes: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1057453

I propose this fix for 2.13..master

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1128
Merged-by: John Johansen <john@jjmx.net>


(cherry picked from commit 15d8e21945)

3ee47af4 Fix typo in apparmor_parser manpage
2023-12-05 15:04:59 +00:00
John Johansen
ff455062a1 Merge fix subprofile name in profile serialization
Given the following profile:

profile foo {
  profile bar {
    profile baz {
    }
  }
}

The parser would correctly serialize the "foo" profile and the
"foo//bar" profile, but it would incorrectly name "bar//baz" when it
should be "foo//bar//baz". This would cause issues loading the profile
in certain kernels causing a "parent does not exist" error.

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1127
Merged-by: John Johansen <john@jjmx.net>
(cherry picked from commit eb6fa02251)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2023-12-04 01:11:17 -08:00
Christian Boltz
0be90d66be Merge Allow reading /run/systemd/sessions/
Several applications use it now that utmp and wtmp are
being removed because they are not Y2038 compliant

This is the case for example in openSUSE Tumbleweed and
openSUSE MicroOS:
https://microos.opensuse.org/blog/2023-11-06-utmp-and-wtmp-are-gone/

Closes https://gitlab.com/apparmor/apparmor/-/issues/360

Closes #360

Fixes: https://bugzilla.opensuse.org/show_bug.cgi?id=1216878

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1121
Approved-by: Christian Boltz <apparmor@cboltz.de>
Merged-by: Christian Boltz <apparmor@cboltz.de>


(cherry picked from commit 9bba464d93)

96b1aa54 Allow reading /run/systemd/sessions/
2023-11-08 18:17:17 +00:00
John Johansen
dc614a04cb Merge tests: fix regression tests to run on kernels that only have network_v8
upstream kernels only have network_v8 unfortunately the tcp tests were
only being run against kernels that had network (which is v7). Kernels
that support both (Ubuntu) would be tested against v8, so v8 has been
tested but pure upstream kernels were failing to be tested correctly.

This patch will only make sure one of the supported verserions are
tested. This is determined by the parser which prefers v8. In the
future the tests need to be extended to run the tests against all
kernel supported versions.

Signed-off-by: John Johansen <john.johansen@canonical.com>

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1120
Approved-by: Christian Boltz <apparmor@cboltz.de>
Merged-by: John Johansen <john@jjmx.net>
(cherry picked from commit dcc719c69c)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2023-11-08 06:26:04 -08:00
John Johansen
c509d9e3cc Merge Allow reading /etc/authselect/nsswitch.conf
On systems with authselect installed, /etc/nsswitch.conf is a symlink to
/etc/authselect/nsswitch.conf.

Fixes: https://gitlab.com/apparmor/apparmor-profiles/-/issues/13

I propose this patch for 3.0..master.

Closes apparmor-profiles#13
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1119
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>

(cherry picked from commit 54915dabc4)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2023-11-02 20:24:31 -07:00
John Johansen
afe0226e67 Merge ubuntu-browsers.d/kde: fix plasma-browser-integration
Out of the box the KDE plasma-browser-integration package does not work
after a user installed the corresponding Firefox extension: The browser
can't start the native host binary. The same is probably true for
Chromium.

This was originally reported to KDE at https://bugs.kde.org/show_bug.cgi?id=397399

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1115
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
(cherry picked from commit 1e7f63415a)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2023-11-02 19:53:19 -07:00
John Johansen
1ada934819 Merge abstractions: pipewire rt conf
Pipewire also uses the client-rt.conf file, add this to the audio abstraction.

See pipewire source: https://github.com/PipeWire/pipewire/blob/master/src/daemon/client-rt.conf.in

Hit this during normal usage of Firefox.

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1113
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
(cherry picked from commit 28f336cb91)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2023-10-13 17:56:46 -07:00
John Johansen
4d3831d1d5 Merge parser/rc.apparmor: Handle Incus
Add init function support to skip incus prefixed policy like is done for lxc and lxd

Signed-off-by: Stéphane Graber <stgraber@stgraber.org>

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1112
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
(cherry picked from commit 7eff621fc7)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2023-10-11 22:54:10 -07:00
Christian Boltz
b8094eb9fa Merge [3.0] Fix aa-cleanprof to work with named profiles
This needed replacement of "program" with "profile" at various places in
tools.py (of course this description is over-simplified).

The changes in get_next_to_profile() (which is used by several aa-*
minitools) are restricted to cleanprof to avoid side effects in the
other aa-* minitools.

However, the other aa-* minitools possibly also suffer from problems
with named profiles, but checking and fixing that is left for another
commit ;-)

Fixes: https://gitlab.com/apparmor/apparmor/-/issues/351

.

The fix needs an additional function in ProfileList (`profile_from_attachment()`) to get the profile name for a given attachment.

Since this is not very different from filename_from_attachment(), move
most of the code into a thing_from_attachment() function, and make
{profile,filename}_from_attachment wrappers for it.

Also adjust the tests to the changed internal data structure, and add
tests for profile_from_attachment().

Closes #351

This is the 3.0 version of https://gitlab.com/apparmor/apparmor/-/merge_requests/1108

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1110
Approved-by: Georgia Garcia <georgia.garcia@canonical.com>
Merged-by: Christian Boltz <apparmor@cboltz.de>
2023-10-11 16:39:07 +00:00
Christian Boltz
fa60f195a6 Fix aa-cleanprof to work with named profiles
This needed replacement of "program" with "profile" at various places in
tools.py (of course this description is over-simplified).

The changes in get_next_to_profile() (which is used by several aa-*
minitools) are restricted to cleanprof to avoid side effects in the
other aa-* minitools.

However, the other aa-* minitools possibly also suffer from problems
with named profiles, but checking and fixing that is left for another
commit ;-)

Fixes: https://gitlab.com/apparmor/apparmor/-/issues/351

(cherry picked from commit 151bf26bb9,
 adjusted for 3.0 branch)
2023-10-10 19:30:18 +02:00
Christian Boltz
a769ed11de ProfileList: add profile_from_attachment()
... to get the profile name for a given attachment.

Since this is not very different from filename_from_attachment(), move
most of the code into a thing_from_attachment() function, and make
{profile,filename}_from_attachment wrappers for it.

Also adjust the tests to the changed internal data structure, and add
tests for profile_from_attachment().

(cherry picked from commit 26903320fd,
 adjusted to 3.0 branch)
2023-10-10 19:24:23 +02:00
John Johansen
f87fb39108 Merge [2.13..3.1] Ignore ´//null-` peers in signal and ptrace events
Ideally we'd update them to the chosen exec target - but until this is
implemented, it doesn't make sense to ask about adding a //null-* peer
to a profile.

This commit is a manual backport of 41df2ca366 /
https://gitlab.com/apparmor/apparmor/-/merge_requests/1090
(with indentation changed to match the 3.1 branch)

I propose this patch for 2.13..3.1

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1107
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>


(cherry picked from commit 719251cac2)

7301aae2 Ignore ´//null-` peers in signal and ptrace events
2023-09-15 16:27:22 +00:00
John Johansen
c4f58178ec Merge profiles: allow for the default dovecot libexecdir
Though many Linux distros choose to pass _/usr/lib_ as the libexecdir while configuring dovecot, such as [Debian](https://sources.debian.org/src/dovecot/1%3A2.3.20%2Bdfsg1-1/debian/rules/#L132) and [Arch](https://gitlab.archlinux.org/archlinux/packaging/packages/dovecot/-/blob/main/PKGBUILD#L76), others like Alpine Linux and Gentoo don't pass anything as libexecdir, allowing it to default to _/usr/libexec_.

Both appear to be valid. From [FHS 3.0, Chapter 4.7](https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch04s07.html):
> Some previous versions of this document did not support _/usr/libexec_, despite it being standard practice in a number of environments. To accomodate this restriction, it became common practice to use _/usr/lib_ instead. Either practice is now acceptable, but each application must choose one way or the other to organize itself.

Allow for the default libexec subdir _/usr/libexec/dovecot_ as well as the more common
_/usr/lib/dovecot_.

Signed-off-by: Peter Levine <plevine457@gmail.com>

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1080
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>


(cherry picked from commit 941118c699)

37ffc6ea profiles: allow for the default dovecot libexecdir
2023-09-12 18:30:24 +00:00
Georgia Garcia
570e26b720 Merge tests/regression/apparmor/capabilities.sh: fail iopl/ioperm with lockdown
In MR #1063 the tests/regression/apparmor/syscall.sh script was updated to
account for kernel lockdown, but the capabilities.sh script also exercises these
system calls so this also needs to be updated as well.

Also required to fix issue #226.

Signed-off-by: Alex Murray <alex.murray@canonical.com>

Closes #226
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1064
Approved-by: Georgia Garcia <georgia.garcia@canonical.com>
Merged-by: Georgia Garcia <georgia.garcia@canonical.com>


(cherry picked from commit 3b832dd313)

eafae0dd tests/regression/apparmor/capabilities.sh: fail iopl/ioperm with lockdown
2023-07-10 13:10:25 +00:00
John Johansen
3b7078ac16 Merge tests/regression/apparmor/syscall.sh: fail iopl/ioperm with lockdown
When kernel lockdown is enabled the ioperm and iopl tests will fail regardless
since lockdown prevents these syscalls before AppArmor has a chance to mediate
them. So workaround this by detecting when lockdown is enabled and expect the
tests to fail in that case.

Fixes issue #226.

Signed-off-by: Alex Murray <alex.murray@canonical.com>

Closes #226
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1063
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>

(cherry picked from commit 7393aaac21)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2023-07-03 23:56:09 -07:00
John Johansen
f4f6dd970e Merge abstractions/fonts: allow writing to fontconfig user cache files
Apologies for the second push; this change is made with the understanding that the abstraction is not intended to be solely read-only.

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1059
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
(cherry picked from commit 5b7e637872)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2023-06-30 18:10:57 -07:00
John Johansen
22deec81f5 Merge abstractions/fonts: allow locking fontconfig user cache files
Got this after allowing `rw` access to `~/.cache/fontconfig/**`:

`Jun 20 00:41:26 testvm kernel: [3280307.358614] audit: type=1400 audit(1687236086.210:127519): apparmor="DENIED" operation="file_lock" profile="firefox" name="/home/username/.cache/fontconfig/a41116dafaf8b233ac2c61cb73f2ea5f-le64.cache-7" pid=1758224 comm="firefox" requested_mask="k" denied_mask="k" fsuid=1002 ouid=1002`

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1057
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
(cherry picked from commit 162aa447d2)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2023-06-30 10:52:59 -07:00
John Johansen
50dff3a507 Merge abstactions/kde: allow reading global Debian KDE settings
New denials detected on Debian Sid:

```
type=AVC msg=audit(1687372581.246:738): apparmor="DENIED" operation="open" class="file" profile="qtox" name="/usr/share/desktop-base/kf5-settings/kdeglobals" pid=17988 comm="qtox" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0FSUID="vincas" OUID="root"
```

Debian package `desktop-base` contains some global KDE settings files:

```
$ dpkg -L desktop-base | fgrep kf5
/usr/share/desktop-base/kf5-settings
/usr/share/desktop-base/kf5-settings/baloofilerc
/usr/share/desktop-base/kf5-settings/kdeglobals
/usr/share/desktop-base/kf5-settings/kscreenlockerrc
```

Add file rules to allow reading global KDE settings.

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1056
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
(cherry picked from commit 1ff74fed4b)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2023-06-30 00:05:13 -07:00
John Johansen
bc27a33d3e Prepare for AppArmor 3.0.12 release
- update version file

Signed-off-by: John Johansen <john.johansen@canonical.com>
2023-06-21 14:11:59 -07:00
John Johansen
a61f2802cb Merge fix mount regression in 3.1.5
Mount has regressed in two ways. That are affecting snapd confinement,
since landing the mount fixes for CVE-2016-1585 in 3.1.4 and the fix
for the mount ch ange type regression in 3.1.5

    Bug Reports:

    https://bugs.launchpad.net/apparmor/+bug/2023814

    https://bugzilla.opensuse.org/show_bug.cgi?id=1211989

Issue 1: Denial of Mount
    ```
    [ 808.531909] audit: type=1400 audit(1686759578.010:158): apparmor="DENIED" operation="mount" class="mount" info="failed mntpnt match" error=-13 profile="snap-update-ns.test-snapd-lp-1803535" name="/tmp/.snap/etc/" pid=14529 comm="5" srcname="/etc/" flags="rw, rbind"
    ```

    when the profile contains a rule that should match
    ```
    mount options=(rw, rbind) "/etc/" -> "/tmp/.snap/etc/",
    ```

Issue 2: change_type failure.

Denial of Mount in log
    ```
    type=AVC msg=audit(1686977968.399:763): apparmor="DENIED" operation="mount" class="mount" info="failed flags match" error=-13 profile="snap-update-ns.authy" name="/var/cache/fontconfig/" pid=26702 comm="5" srcname="/var/lib/snapd/hostfs/var/cache/fontconfig/" flags="rw, bind"
    ...
    ```

snapd error
    ```
    - Run configure hook of "chromium" snap if present (run hook "configure":
    -----
    update.go:85: cannot change mount namespace according to change mount (/var/lib/snapd/hostfs/usr/share/doc /usr/share/doc none bind,ro 0 0): permission denied
    update.go:85: cannot change mount namespace according to change mount (/var/lib/snapd/hostfs/usr/share/fonts /usr/share/fonts none bind,ro 0 0): permission denied
    update.go:85: cannot change mount namespace according to change mount (/var/snap/cups/common/run /var/cups none bind,rw 0 0): permission denied
    cannot update snap namespace: cannot create writable mimic over "/snap/chromium/2475": permission denied
    snap-update-ns failed with code 1
    ```

and NO mount rules in the profiles.

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1054
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
2023-06-21 01:21:02 -07:00
John Johansen
b85046648b parser: fix rule flag generation change_mount type rules
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1048
made it so rules like

  mount slave /snap/bin/** -> /**,

  mount /snap/bin/** -> /**,

would get passed into change_mount_type rule generation when they
shouldn't have been. This would result in two different errors.

1. If kernel mount flags were present on the rule. The error would
   be caught causing an error to be returned, causing profile compilation
   to fail.

2. If the rule did not contain explicit flags then rule would generate
   change_mount_type permissions based on souly the mount point. And
   the implied set of flags. However this is incorrect as it should
   not generate change_mount permissions for this type of rule. Not
   only does it ignore the source/device type condition but it
   generates permissions that were never intended.

   When used in combination with a deny prefix this overly broad
   rule can result in almost all mount rules being denied, as the
   denial takes priority over the allow mount rules.

Fixes: https://bugs.launchpad.net/apparmor/+bug/2023814
Fixes: https://bugzilla.opensuse.org/show_bug.cgi?id=1211989
Fixes: 9d3f8c6cc ("parser: fix parsing of source as mount point for propagation type flags")
Fixes: MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1048

Signed-off-by: John Johansen <john.johansen@canonical.com>
(cherry picked from commit 86d193e183)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2023-06-21 01:20:34 -07:00
John Johansen
0c52805b3d parser: Deprecation warning should not have been backported
Outputing the deprecation warning is a change in behavior that is not
a bug fix.

Signed-off-by: John Johansen <john.johansen@canonical.com>
(cherry picked from commit ca7f79174e)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2023-06-21 01:20:19 -07:00
John Johansen
d6db84b120 Merge abstractions/base: Add transparent hugepage support
Found in testing a slimmed-down `usr.sbin.sshd` profile:
```
Jun  8 21:09:38 testvm kernel: [   54.847014] audit: type=1400 audit(1686272978.009:68): apparmor="DENIED" operation="open" profile="/usr/sbin/sshd" name="/sys/kernel/mm/transparent_hugepage/hpage_pmd_size" pid=1035 comm="sshd" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
```
Not sure what glibc/system call uses this, but it seems pretty broadly applicable, and read access is presumably harmless. [THP reference](https://www.kernel.org/doc/html/latest/admin-guide/mm/transhuge.html)

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1050
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
(cherry picked from commit ad3750058d)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2023-06-09 01:48:45 -07:00
John Johansen
419541d5c8 Merge abstractions/authentication: Add GSSAPI mechanism modules config
Found in testing a slimmed-down `usr.sbin.sshd` profile:
```
Jun  8 21:09:37 testvm kernel: [   54.770501] audit: type=1400 audit(1686272977.933:67): apparmor="DENIED" operation="open" profile="/usr/sbin/sshd" name="/etc/gss/mech.d/" pid=1036 comm="sshd" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
```
([Reference](https://web.mit.edu/kerberos/krb5-1.21/doc/admin/host_config.html#gssapi-mechanism-modules) for  GSSAPI mechanism modules)

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1049
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
(cherry picked from commit b41fcdce16)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2023-06-09 01:48:39 -07:00
57 changed files with 329 additions and 130 deletions

View File

@@ -1 +1 @@
3.0.11
3.0.13

View File

@@ -116,6 +116,14 @@ The specified I<file/task> does not exist or is not visible.
The confinement data is too large to fit in the supplied buffer.
=item B<ENOPROTOOPT>
The kernel doesn't support the SO_PEERLABEL option in sockets. This happens
mainly when the kernel lacks 'fine grained unix mediation' support. It also
can happen on LSM stacking kernels where another LSM has claimed this
interface and decides to return this error, although this is really a
corner case.
=back
=head1 NOTES

View File

@@ -109,12 +109,12 @@ To immediately stack a profile named "profile_a", as performed with
aa_stack_profile("profile_a"), the equivalent of this shell command can be
used:
$ echo -n "stackprofile profile_a" > /proc/self/attr/current
$ echo -n "stack profile_a" > /proc/self/attr/current
To stack a profile named "profile_a" at the next exec, as performed with
aa_stack_onexec("profile_a"), the equivalent of this shell command can be used:
$ echo -n "stackexec profile_a" > /proc/self/attr/exec
$ echo -n "stack profile_a" > /proc/self/attr/exec
These raw AppArmor filesystem operations must only be used when using
libapparmor is not a viable option.
@@ -184,6 +184,7 @@ with apparmor_parser(8):
/etc/passwd r,
# Needed for aa_stack_profile()
change-profile -> &i_cant_be_trusted_anymore,
/usr/lib/libapparmor*.so* mr,
/proc/[0-9]*/attr/current w,
}

View File

@@ -299,11 +299,11 @@ Enable various warnings during policy compilation. A single warn flag
can be specified per --warn option, but the --warn flag can be passed
multiple times.
apparmor_parser --warn=rules-not-enforced ...
apparmor_parser --warn=rule-not-enforced ...
A specific warning can be disabled by prepending I<no>- to the flag
apparmor_parser --warn=no-rules-not-enforced ...
apparmor_parser --warn=no-rule-not-enforced ...
Use --help=warn to see a full list of which warn flags are supported.

View File

@@ -838,8 +838,6 @@ int mnt_rule::gen_policy_change_mount_type(Profile &prof, int &count,
"same time for propagation type flags");
goto fail;
} else if (device && !mnt_point) {
pwarn(WARN_DEPRECATED, _("The use of source as mount point for "
"propagation type flags is deprecated.\n"));
mountpoint = device;
}
if (!convert_entry(mntbuf, mountpoint))
@@ -984,7 +982,7 @@ int mnt_rule::gen_flag_rules(Profile &prof, int &count, unsigned int flags,
if (!dev_type && !opts &&
gen_policy_bind_mount(prof, count, flags, opt_flags) == RULE_ERROR)
return RULE_ERROR;
if (!dev_type && !opts &&
if ((!device || !mnt_point) && !dev_type && !opts &&
gen_policy_change_mount_type(prof, count, flags, opt_flags) == RULE_ERROR)
return RULE_ERROR;
if (!dev_type && !opts &&
@@ -1000,7 +998,7 @@ int mnt_rule::gen_flag_rules(Profile &prof, int &count, unsigned int flags,
return gen_policy_bind_mount(prof, count, flags, opt_flags);
} else if ((allow & AA_MAY_MOUNT) &&
(flags & (MS_MAKE_CMDS))
&& !dev_type && !opts) {
&& (!device || !mnt_point) && !dev_type && !opts) {
return gen_policy_change_mount_type(prof, count, flags, opt_flags);
} else if ((allow & AA_MAY_MOUNT) && (flags & MS_MOVE)
&& !dev_type && !opts) {

View File

@@ -274,7 +274,7 @@ static inline void sd_write_aligned_blob(std::ostringstream &buf, void *b, int b
buf.write((const char *) b, b_size);
}
static void sd_write_strn(std::ostringstream &buf, char *b, int size, const char *name)
static void sd_write_strn(std::ostringstream &buf, const char *b, int size, const char *name)
{
sd_write_name(buf, name);
sd_write8(buf, SD_STRING);
@@ -282,7 +282,7 @@ static void sd_write_strn(std::ostringstream &buf, char *b, int size, const char
buf.write(b, size);
}
static inline void sd_write_string(std::ostringstream &buf, char *b, const char *name)
static inline void sd_write_string(std::ostringstream &buf, const char *b, const char *name)
{
sd_write_strn(buf, b, strlen(b) + 1, name);
}
@@ -401,11 +401,7 @@ void sd_serialize_profile(std::ostringstream &buf, Profile *profile,
sd_write_struct(buf, "profile");
if (flattened) {
assert(profile->parent);
autofree char *name = (char *) malloc(3 + strlen(profile->name) + strlen(profile->parent->name));
if (!name)
return;
sprintf(name, "%s//%s", profile->parent->name, profile->name);
sd_write_string(buf, name, NULL);
sd_write_string(buf, profile->get_name(false).c_str(), NULL);
} else {
sd_write_string(buf, profile->name, NULL);
}

View File

@@ -99,11 +99,12 @@ is_container_with_internal_policy() {
return 1
fi
# LXD and LXC set up AppArmor namespaces starting with "lxd-" and
# "lxc-", respectively. Return non-zero for all other namespace
# identifiers.
# LXD, Incus and LXC set up AppArmor namespaces starting with "lxd-",
# "incus-" and "lxc-", respectively. Return non-zero for all other
# namespace identifiers.
read -r ns_name < "$ns_name_path"
if [ "${ns_name#lxd-*}" = "$ns_name" ] && \
[ "${ns_name#incus-*}" = "$ns_name" ] && \
[ "${ns_name#lxc-*}" = "$ns_name" ]; then
return 1
fi

View File

@@ -643,6 +643,16 @@ verify_binary_equality "attachment slash filtering" \
@{FOO}=/foo
/t @{BAR}/@{FOO} { }"
# This can potentially fail as ideally it requires a better dfa comparison
# routine as it can generates hormomorphic dfas. The enumeration of the
# dfas dumped will be different, even if the binary is the same
# Note: this test in the future will require -O filter-deny and
# -O minimize and -O remove-unreachable.
verify_binary_equality "mount specific deny doesn't affect non-overlapping" \
"/t { mount options=bind /e/ -> /**, }" \
"/t { audit deny mount /s/** -> /**,
mount options=bind /e/ -> /**, }"
if [ $fails -ne 0 ] || [ $errors -ne 0 ]
then
printf "ERRORS: %d\nFAILS: %d\n" $errors $fails 2>&1

View File

@@ -0,0 +1,6 @@
#
#=Description test we fail make rules with source and mntpnt associated with MR 1054
#=EXRESULT FAIL
/usr/bin/foo {
mount options=(slave) /snap/bin/** -> /**,
}

View File

@@ -0,0 +1,6 @@
#
#=Description test we fail make rules with source and mntpnt associated with MR 1054
#=EXRESULT FAIL
/usr/bin/foo {
mount options=(rslave) /snap/bin/** -> /**,
}

View File

@@ -0,0 +1,6 @@
#
#=Description test we fail make rules with source and mntpnt associated with MR 1054
#=EXRESULT FAIL
/usr/bin/foo {
mount options=(unbindable) /snap/bin/** -> /**,
}

View File

@@ -0,0 +1,6 @@
#
#=Description test we fail make rules with source and mntpnt associated with MR 1054
#=EXRESULT FAIL
/usr/bin/foo {
mount options=(runbindable) /snap/bin/** -> /**,
}

View File

@@ -0,0 +1,6 @@
#
#=Description test we fail make rules with source and mntpnt associated with MR 1054
#=EXRESULT FAIL
/usr/bin/foo {
mount options=(private) /snap/bin/** -> /**,
}

View File

@@ -0,0 +1,6 @@
#
#=Description test we fail make rules with source and mntpnt associated with MR 1054
#=EXRESULT FAIL
/usr/bin/foo {
mount options=(rprivate) /snap/bin/** -> /**,
}

View File

@@ -0,0 +1,6 @@
#
#=Description test we fail make rules with source and mntpnt associated with MR 1054
#=EXRESULT FAIL
/usr/bin/foo {
mount options=(shared) /snap/bin/** -> /**,
}

View File

@@ -0,0 +1,6 @@
#
#=Description test we fail make rules with source and mntpnt associated with MR 1054
#=EXRESULT FAIL
/usr/bin/foo {
mount options=(rshared) /snap/bin/** -> /**,
}

View File

@@ -0,0 +1,8 @@
#
#=Description test we can parse rules associated with MR 1054
#=EXRESULT PASS
/usr/bin/foo {
mount options=(slave) /**,
mount options=(slave) -> /**,
mount /snap/bin/** -> /**,
}

View File

@@ -86,7 +86,7 @@ owner @{HOME}/.local/share/openal/hrtf/{,**} r,
/etc/wildmidi/wildmidi.cfg r,
# pipewire
/usr/share/pipewire/client.conf r,
/usr/share/pipewire/client{,-rt}.conf r,
# Include additions to the abstraction
include if exists <abstractions/audio.d>

View File

@@ -31,6 +31,11 @@
/{usr/,}lib/@{multiarch}/security/pam_*.so mr,
/{usr/,}lib/@{multiarch}/security/ r,
# gssapi
@{etc_ro}/gss/mech r,
@{etc_ro}/gss/mech.d/ r,
@{etc_ro}/gss/mech.d/*.conf r,
# kerberos
include <abstractions/kerberosclient>
# SuSE's pwdutils are different:

View File

@@ -104,6 +104,9 @@
@{sys}/devices/system/cpu/online r,
@{sys}/devices/system/cpu/possible r,
# transparent hugepage support
@{sys}/kernel/mm/transparent_hugepage/hpage_pmd_size r,
# glibc's *printf protections read the maps file
@{PROC}/@{pid}/{maps,auxv,status} r,

View File

@@ -47,7 +47,7 @@
owner @{HOME}/.local/share/fonts/** r,
owner @{HOME}/.fonts.cache-2 mr,
owner @{HOME}/.{,cache/}fontconfig/ rw,
owner @{HOME}/.{,cache/}fontconfig/** mrl,
owner @{HOME}/.{,cache/}fontconfig/** mrwkl,
owner @{HOME}/.fonts.conf.d/ r,
owner @{HOME}/.fonts.conf.d/** r,
owner @{HOME}/.config/fontconfig/ r,

View File

@@ -27,6 +27,9 @@ include <abstractions/qt5>
/etc/kde4rc r,
/etc/xdg/kdeglobals r,
/etc/xdg/Trolltech.conf r,
/usr/share/desktop-base/kf5-settings/baloofilerc r,
/usr/share/desktop-base/kf5-settings/kdeglobals r,
/usr/share/desktop-base/kf5-settings/kscreenlockerrc r,
/usr/share/knotifications5/*.notifyrc r, # KNotification::sendEvent()
/usr/share/kubuntu-default-settings/kf5-settings/* r,

View File

@@ -23,6 +23,9 @@
@{etc_ro}/passwd r,
@{etc_ro}/protocols r,
# On systems with authselect installed, /etc/nsswitch.conf is a symlink to /etc/authselect/nsswitch.conf
@{etc_ro}/authselect/nsswitch.conf r,
# libtirpc (used for NIS/YP login) needs this
@{etc_ro}/netconfig r,

View File

@@ -7,3 +7,6 @@
include <abstractions/kde>
/usr/bin/kde4-config Cx -> sanitized_helper,
# https://bugs.kde.org/show_bug.cgi?id=397399
/usr/bin/plasma-browser-integration-host Cx -> sanitized_helper,

View File

@@ -18,5 +18,8 @@
/var/log/btmp rwk,
@{run}/utmp rwk,
# Some read the list of sessions from systemd
/run/systemd/sessions/ r,
# Include additions to the abstraction
include if exists <abstractions/wutmp.d>

View File

@@ -13,7 +13,7 @@ abi <abi/3.0>,
include <tunables/global>
profile dovecot-anvil /usr/lib/dovecot/anvil {
profile dovecot-anvil /usr/lib*/dovecot/anvil {
include <abstractions/base>
include <abstractions/dovecot-common>
@@ -24,7 +24,7 @@ profile dovecot-anvil /usr/lib/dovecot/anvil {
@{run}/dovecot/anvil rw,
@{run}/dovecot/anvil-auth-penalty rw,
/usr/lib/dovecot/anvil mr,
/usr/lib*/dovecot/anvil mr,
# Site-specific additions and overrides. See local/README for details.
include if exists <local/usr.lib.dovecot.anvil>

View File

@@ -14,7 +14,7 @@ abi <abi/3.0>,
include <tunables/global>
profile dovecot-auth /usr/lib/dovecot/auth {
profile dovecot-auth /usr/lib*/dovecot/auth {
include <abstractions/authentication>
include <abstractions/base>
include <abstractions/mysql>
@@ -34,7 +34,7 @@ profile dovecot-auth /usr/lib/dovecot/auth {
/etc/my.cnf.d/*.cnf r,
/etc/dovecot/* r,
/usr/lib/dovecot/auth mr,
/usr/lib*/dovecot/auth mr,
/var/lib/dovecot/auth-chroot/* r,
# kerberos replay cache

View File

@@ -13,7 +13,7 @@ abi <abi/3.0>,
include <tunables/global>
profile dovecot-config /usr/lib/dovecot/config {
profile dovecot-config /usr/lib*/dovecot/config {
include <abstractions/base>
include <abstractions/nameservice>
include <abstractions/dovecot-common>
@@ -24,8 +24,8 @@ profile dovecot-config /usr/lib/dovecot/config {
/etc/dovecot/** r,
/usr/bin/doveconf rix,
/usr/lib/dovecot/config mr,
/usr/lib/dovecot/managesieve Px,
/usr/lib*/dovecot/config mr,
/usr/lib*/dovecot/managesieve Px,
/usr/share/dovecot/** r,
/var/lib/dovecot/ssl-parameters.dat r,

View File

@@ -16,7 +16,7 @@ abi <abi/3.0>,
include <tunables/global>
include <tunables/dovecot>
profile dovecot-deliver /usr/lib/dovecot/deliver {
profile dovecot-deliver /usr/lib*/dovecot/deliver {
include <abstractions/base>
include <abstractions/nameservice>
include <abstractions/dovecot-common>
@@ -32,7 +32,7 @@ profile dovecot-deliver /usr/lib/dovecot/deliver {
/etc/dovecot/dovecot-postfix.conf r, # ???
@{HOME} r, # ???
/usr/lib/dovecot/deliver mr,
/usr/lib*/dovecot/deliver mr,
# Site-specific additions and overrides. See local/README for details.
include if exists <local/usr.lib.dovecot.deliver>

View File

@@ -13,7 +13,7 @@ abi <abi/3.0>,
include <tunables/global>
profile dovecot-dict /usr/lib/dovecot/dict {
profile dovecot-dict /usr/lib*/dovecot/dict {
include <abstractions/base>
include <abstractions/mysql>
include <abstractions/nameservice>
@@ -27,7 +27,7 @@ profile dovecot-dict /usr/lib/dovecot/dict {
/etc/dovecot/dovecot-database.conf.ext r,
/etc/dovecot/dovecot-dict-sql.conf.ext r,
/etc/my.cnf r,
/usr/lib/dovecot/dict mr,
/usr/lib*/dovecot/dict mr,
# Site-specific additions and overrides. See local/README for details.
include if exists <local/usr.lib.dovecot.dict>

View File

@@ -11,7 +11,7 @@
include <tunables/global>
profile dovecot-director /usr/lib/dovecot/director flags=(attach_disconnected) {
profile dovecot-director /usr/lib*/dovecot/director flags=(attach_disconnected) {
include <abstractions/base>
include <abstractions/dovecot-common>
include <abstractions/nameservice>
@@ -20,7 +20,7 @@ profile dovecot-director /usr/lib/dovecot/director flags=(attach_disconnected) {
capability sys_chroot,
/run/dovecot/login/proxy-notify rw,
/usr/lib/dovecot/director mr,
/usr/lib*/dovecot/director mr,
# Site-specific additions and overrides. See local/README for details.
include if exists <local/usr.lib.dovecot.director>

View File

@@ -11,11 +11,11 @@
include <tunables/global>
profile dovecot-doveadm-server /usr/lib/dovecot/doveadm-server flags=(attach_disconnected) {
profile dovecot-doveadm-server /usr/lib*/dovecot/doveadm-server flags=(attach_disconnected) {
include <abstractions/base>
include <abstractions/dovecot-common>
/usr/lib/dovecot/doveadm-server mr,
/usr/lib*/dovecot/doveadm-server mr,
# Site-specific additions and overrides. See local/README for details.
include if exists <local/usr.lib.dovecot.doveadm-server>

View File

@@ -14,7 +14,7 @@ abi <abi/3.0>,
include <tunables/global>
profile dovecot-dovecot-auth /usr/lib/dovecot/dovecot-auth {
profile dovecot-dovecot-auth /usr/lib*/dovecot/dovecot-auth {
include <abstractions/authentication>
include <abstractions/base>
include <abstractions/nameservice>
@@ -25,7 +25,7 @@ profile dovecot-dovecot-auth /usr/lib/dovecot/dovecot-auth {
capability dac_override,
@{PROC}/@{pid}/mounts r,
/usr/lib/dovecot/dovecot-auth mr,
/usr/lib*/dovecot/dovecot-auth mr,
@{run}/dovecot/** rw,
# required for postfix+dovecot integration
/var/spool/postfix/private/dovecot-auth w,

View File

@@ -14,7 +14,7 @@ abi <abi/3.0>,
include <tunables/global>
include <tunables/dovecot>
profile dovecot-dovecot-lda /usr/lib/dovecot/dovecot-lda flags=(attach_disconnected) {
profile dovecot-dovecot-lda /usr/lib*/dovecot/dovecot-lda flags=(attach_disconnected) {
include <abstractions/base>
include <abstractions/nameservice>
include <abstractions/dovecot-common>
@@ -30,7 +30,7 @@ profile dovecot-dovecot-lda /usr/lib/dovecot/dovecot-lda flags=(attach_disconnec
@{run}/dovecot/mounts r,
@{run}/dovecot/auth-userdb rw,
/usr/bin/doveconf mrix,
/usr/lib/dovecot/dovecot-lda mrix,
/usr/lib*/dovecot/dovecot-lda mrix,
/usr/{bin,sbin}/sendmail Cx -> sendmail,
/usr/share/dovecot/protocols.d/ r,
/usr/share/dovecot/protocols.d/** r,

View File

@@ -15,7 +15,7 @@ abi <abi/3.0>,
include <tunables/global>
include <tunables/dovecot>
profile dovecot-imap /usr/lib/dovecot/imap {
profile dovecot-imap /usr/lib*/dovecot/imap {
include <abstractions/base>
include <abstractions/nameservice>
include <abstractions/dovecot-common>
@@ -37,7 +37,7 @@ profile dovecot-imap /usr/lib/dovecot/imap {
@{PROC}/@{pid}/attr/{apparmor/,}current rw,
@{PROC}/@{pid}/stat r,
/usr/bin/doveconf rix,
/usr/lib/dovecot/imap mrix,
/usr/lib*/dovecot/imap mrix,
/usr/share/dovecot/** r,
@{run}/dovecot/login/imap rw,
@{run}/dovecot/auth-master rw,

View File

@@ -14,7 +14,7 @@ abi <abi/3.0>,
include <tunables/global>
profile dovecot-imap-login /usr/lib/dovecot/imap-login {
profile dovecot-imap-login /usr/lib*/dovecot/imap-login {
include <abstractions/base>
include <abstractions/dovecot-common>
include <abstractions/openssl>
@@ -26,7 +26,7 @@ profile dovecot-imap-login /usr/lib/dovecot/imap-login {
network inet6 stream,
network unix stream,
/usr/lib/dovecot/imap-login mr,
/usr/lib*/dovecot/imap-login mr,
@{run}/dovecot/anvil rw,
@{run}/dovecot/login-master-notify* rw,
@{run}/dovecot/login/ r,

View File

@@ -14,7 +14,7 @@ abi <abi/3.0>,
include <tunables/global>
include <tunables/dovecot>
profile dovecot-lmtp /usr/lib/dovecot/lmtp {
profile dovecot-lmtp /usr/lib*/dovecot/lmtp {
include <abstractions/base>
include <abstractions/nameservice>
include <abstractions/dovecot-common>
@@ -35,7 +35,7 @@ profile dovecot-lmtp /usr/lib/dovecot/lmtp {
owner @{PROC}/@{pid}/stat r,
@{PROC}/*/mounts r,
/tmp/dovecot.lmtp.* rw,
/usr/lib/dovecot/lmtp mr,
/usr/lib*/dovecot/lmtp mr,
@{run}/dovecot/mounts r,
# Site-specific additions and overrides. See local/README for details.

View File

@@ -13,11 +13,11 @@ abi <abi/3.0>,
include <tunables/global>
profile dovecot-log /usr/lib/dovecot/log flags=(attach_disconnected) {
profile dovecot-log /usr/lib*/dovecot/log flags=(attach_disconnected) {
include <abstractions/base>
include <abstractions/dovecot-common>
/usr/lib/dovecot/log mr,
/usr/lib*/dovecot/log mr,
# Site-specific additions and overrides. See local/README for details.
include if exists <local/usr.lib.dovecot.log>

View File

@@ -15,7 +15,7 @@ abi <abi/3.0>,
include <tunables/global>
include <tunables/dovecot>
profile dovecot-managesieve /usr/lib/dovecot/managesieve {
profile dovecot-managesieve /usr/lib*/dovecot/managesieve {
include <abstractions/base>
include <abstractions/dovecot-common>
@@ -29,7 +29,7 @@ profile dovecot-managesieve /usr/lib/dovecot/managesieve {
/etc/dovecot/** r,
/usr/bin/doveconf rix,
/usr/lib/dovecot/managesieve mrix,
/usr/lib*/dovecot/managesieve mrix,
# Site-specific additions and overrides. See local/README for details.
include if exists <local/usr.lib.dovecot.managesieve>

View File

@@ -16,7 +16,7 @@ abi <abi/3.0>,
include <tunables/global>
profile dovecot-managesieve-login /usr/lib/dovecot/managesieve-login {
profile dovecot-managesieve-login /usr/lib*/dovecot/managesieve-login {
include <abstractions/base>
include <abstractions/dovecot-common>
include <abstractions/openssl>
@@ -28,7 +28,7 @@ profile dovecot-managesieve-login /usr/lib/dovecot/managesieve-login {
network inet6 stream,
network unix stream,
/usr/lib/dovecot/managesieve-login mr,
/usr/lib*/dovecot/managesieve-login mr,
@{run}/dovecot/login-master-notify* rw,
@{run}/dovecot/login/ r,
@{run}/dovecot/login/* rw,

View File

@@ -15,7 +15,7 @@ abi <abi/3.0>,
include <tunables/global>
include <tunables/dovecot>
profile dovecot-pop3 /usr/lib/dovecot/pop3 {
profile dovecot-pop3 /usr/lib*/dovecot/pop3 {
include <abstractions/base>
include <abstractions/nameservice>
include <abstractions/dovecot-common>
@@ -27,7 +27,7 @@ profile dovecot-pop3 /usr/lib/dovecot/pop3 {
@{HOME} r, # ???
@{PROC}/@{pid}/stat r,
/usr/lib/dovecot/pop3 mr,
/usr/lib*/dovecot/pop3 mr,
# Site-specific additions and overrides. See local/README for details.
include if exists <local/usr.lib.dovecot.pop3>

View File

@@ -14,7 +14,7 @@ abi <abi/3.0>,
include <tunables/global>
profile dovecot-pop3-login /usr/lib/dovecot/pop3-login {
profile dovecot-pop3-login /usr/lib*/dovecot/pop3-login {
include <abstractions/base>
include <abstractions/dovecot-common>
include <abstractions/openssl>
@@ -26,7 +26,7 @@ profile dovecot-pop3-login /usr/lib/dovecot/pop3-login {
network inet6 stream,
network unix stream,
/usr/lib/dovecot/pop3-login mr,
/usr/lib*/dovecot/pop3-login mr,
@{run}/dovecot/anvil rw,
@{run}/dovecot/login-master-notify* rw,
@{run}/dovecot/login/ r,

View File

@@ -15,7 +15,7 @@
include <tunables/dovecot>
include <tunables/global>
profile dovecot-replicator /usr/lib/dovecot/replicator {
profile dovecot-replicator /usr/lib*/dovecot/replicator {
include <abstractions/base>
include <abstractions/dovecot-common>
include <abstractions/nameservice>
@@ -25,7 +25,7 @@ profile dovecot-replicator /usr/lib/dovecot/replicator {
/etc/dovecot/conf.d/ r,
/etc/dovecot/conf.d/** r,
/etc/dovecot/dovecot.conf r,
/usr/lib/dovecot/replicator mr,
/usr/lib*/dovecot/replicator mr,
/usr/share/dovecot/** r,
/{,var/}run/dovecot/auth-master rw,
@{DOVECOT_MAILSTORE}/ rw,

View File

@@ -14,14 +14,14 @@ abi <abi/3.0>,
include <tunables/global>
profile dovecot-script-login /usr/lib/dovecot/script-login {
profile dovecot-script-login /usr/lib*/dovecot/script-login {
include <abstractions/base>
include <abstractions/dovecot-common>
include <abstractions/nameservice>
capability setuid,
/usr/lib/dovecot/script-login mrPx,
/usr/lib*/dovecot/script-login mrPx,
# NOTE: You'll need to allow execution of your actual login script.
# The recommended way is to add a rule for it in local/usr.lib.dovecot.script-login

View File

@@ -13,13 +13,13 @@ abi <abi/3.0>,
include <tunables/global>
profile dovecot-ssl-params /usr/lib/dovecot/ssl-params {
profile dovecot-ssl-params /usr/lib*/dovecot/ssl-params {
include <abstractions/base>
include <abstractions/dovecot-common>
@{run}/dovecot/ssl-params rw,
@{run}/dovecot/login/ssl-params rw,
/usr/lib/dovecot/ssl-params mr,
/usr/lib*/dovecot/ssl-params mr,
/var/lib/dovecot/ssl-parameters.dat rw,
/var/lib/dovecot/ssl-parameters.dat.tmp rwk,

View File

@@ -13,7 +13,7 @@ abi <abi/3.0>,
include <tunables/global>
profile dovecot-stats /usr/lib/dovecot/stats {
profile dovecot-stats /usr/lib*/dovecot/stats {
include <abstractions/base>
include <abstractions/dovecot-common>
@@ -24,7 +24,7 @@ profile dovecot-stats /usr/lib/dovecot/stats {
network inet stream,
network inet6 stream,
/usr/lib/dovecot/stats mr,
/usr/lib*/dovecot/stats mr,
# Site-specific additions and overrides. See local/README for details.
include if exists <local/usr.lib.dovecot.stats>

View File

@@ -33,10 +33,10 @@ profile dovecot /usr/{bin,sbin}/dovecot flags=(attach_disconnected) {
capability sys_chroot,
capability sys_resource,
signal send peer=/usr/lib/dovecot/*,
signal send peer=/usr/lib*/dovecot/*,
signal send peer=dovecot-*,
unix (receive, send) type=stream peer=(label=/usr/lib/dovecot/anvil),
unix (receive, send) type=stream peer=(label=/usr/lib*/dovecot/anvil),
unix (receive, send) type=stream peer=(label=dovecot-anvil),
/etc/dovecot/** r,
@@ -46,26 +46,26 @@ profile dovecot /usr/{bin,sbin}/dovecot flags=(attach_disconnected) {
@{PROC}/@{pid}/mounts r,
@{PROC}/sys/fs/suid_dumpable r,
/usr/bin/doveconf rix,
/usr/lib/dovecot/anvil mrPx,
/usr/lib/dovecot/auth mrPx,
/usr/lib/dovecot/config mrPx,
/usr/lib/dovecot/dict mrPx,
/usr/lib/dovecot/director mrPx,
/usr/lib/dovecot/doveadm-server mrPx,
/usr/lib/dovecot/dovecot-auth Pxmr,
/usr/lib/dovecot/imap Pxmr,
/usr/lib/dovecot/imap-login Pxmr,
/usr/lib/dovecot/lmtp mrPx,
/usr/lib/dovecot/log mrPx,
/usr/lib/dovecot/managesieve mrPx,
/usr/lib/dovecot/managesieve-login Pxmr,
/usr/lib/dovecot/pop3 mrPx,
/usr/lib/dovecot/pop3-login Pxmr,
/usr/lib/dovecot/replicator mrPx,
/usr/lib/dovecot/script-login Px,
/usr/lib/dovecot/ssl-build-param rix,
/usr/lib/dovecot/ssl-params mrPx,
/usr/lib/dovecot/stats Px,
/usr/lib*/dovecot/anvil mrPx,
/usr/lib*/dovecot/auth mrPx,
/usr/lib*/dovecot/config mrPx,
/usr/lib*/dovecot/dict mrPx,
/usr/lib*/dovecot/director mrPx,
/usr/lib*/dovecot/doveadm-server mrPx,
/usr/lib*/dovecot/dovecot-auth Pxmr,
/usr/lib*/dovecot/imap Pxmr,
/usr/lib*/dovecot/imap-login Pxmr,
/usr/lib*/dovecot/lmtp mrPx,
/usr/lib*/dovecot/log mrPx,
/usr/lib*/dovecot/managesieve mrPx,
/usr/lib*/dovecot/managesieve-login Pxmr,
/usr/lib*/dovecot/pop3 mrPx,
/usr/lib*/dovecot/pop3-login Pxmr,
/usr/lib*/dovecot/replicator mrPx,
/usr/lib*/dovecot/script-login Px,
/usr/lib*/dovecot/ssl-build-param rix,
/usr/lib*/dovecot/ssl-params mrPx,
/usr/lib*/dovecot/stats Px,
/usr/{bin,sbin}/dovecot mrix,
/usr/share/dovecot/dh.pem r,
/usr/share/dovecot/protocols.d/ r,

30
tests/regression/apparmor/capabilities.sh Normal file → Executable file
View File

@@ -49,14 +49,20 @@ CAPABILITIES="chown dac_override dac_read_search fowner fsetid kill \
sys_admin sys_boot sys_nice sys_resource sys_time \
sys_tty_config mknod lease audit_write audit_control"
# lockdown thwarts both ioperm and iopl
notlockeddown=TRUE
if [ -f /sys/kernel/security/lockdown ] && ! grep -q "\[none\]" /sys/kernel/security/lockdown; then
notlockeddown=FALSE
fi
# defines which test+capability pairs should succeed.
syscall_reboot_sys_boot=TRUE
syscall_sethostname_sys_admin=TRUE
syscall_setdomainname_sys_admin=TRUE
syscall_setpriority_sys_nice=TRUE
syscall_setscheduler_sys_nice=TRUE
syscall_ioperm_sys_rawio=TRUE
syscall_iopl_sys_rawio=TRUE
syscall_ioperm_sys_rawio=$notlockeddown
syscall_iopl_sys_rawio=$notlockeddown
syscall_chroot_sys_chroot=TRUE
syscall_mlockall_ipc_lock=TRUE
syscall_sysctl_sys_admin=TRUE
@@ -93,7 +99,13 @@ for TEST in ${TESTS} ; do
settest ${TEST}
# base case, unconfined
runchecktest "${TEST} -- unconfined" pass ${my_arg}
if [ "${TEST}" = "syscall_ioperm" -a "$notlockeddown" = "FALSE" ] ||
[ "${TEST}" = "syscall_iopl" -a "$notlockeddown" = "FALSE" ]; then
expected=fail
else
expected=pass
fi
runchecktest "${TEST} -- unconfined" ${expected} ${my_arg}
# no capabilities allowed
genprofile ${my_entries}
@@ -107,11 +119,13 @@ for TEST in ${TESTS} ; do
# all capabilities allowed
genprofile cap:ALL ${my_entries}
runchecktest "${TEST} -- all caps" pass ${my_arg}
runchecktest "${TEST} -- all caps" ${expected} ${my_arg}
# iterate through each of the capabilities
for cap in ${CAPABILITIES} ; do
if [ "X$(eval echo \${${TEST}_${cap}})" = "XTRUE" ] ; then
if [ ${expected} = "fail" ]; then
expected_result=fail
elif [ "X$(eval echo \${${TEST}_${cap}})" = "XTRUE" ] ; then
expected_result=pass
elif [ "${TEST}" = "syscall_ptrace" -a "$(kernel_features ptrace)" = "true" ]; then
expected_result=pass
@@ -136,10 +150,12 @@ for TEST in ${TESTS} ; do
# all capabilities allowed
genprofile hat:$bin/${TEST} addimage:${bin}/${TEST} cap:ALL ${my_entries}
runchecktest "${TEST} changehat -- all caps" pass $bin/${TEST} ${my_arg}
runchecktest "${TEST} changehat -- all caps" ${expected} $bin/${TEST} ${my_arg}
for cap in ${CAPABILITIES} ; do
if [ "X$(eval echo \${${TEST}_${cap}})" = "XTRUE" ] ; then
if [ ${expected} = "fail" ]; then
expected_result=fail
elif [ "X$(eval echo \${${TEST}_${cap}})" = "XTRUE" ] ; then
expected_result=pass
elif [ "${TEST}" = "syscall_ptrace" -a "$(kernel_features ptrace)" = "true" ]; then
expected_result=pass

View File

@@ -398,6 +398,16 @@ else
runchecktest "UMOUNT (confined cap umount:ALL)" pass umount ${loop_device} ${mount_point}
remove_mnt
# MR:https://gitlab.com/apparmor/apparmor/-/merge_requests/1054
# https://bugs.launchpad.net/apparmor/+bug/2023814
# https://bugzilla.opensuse.org/show_bug.cgi?id=1211989
# based on rules from profile in bug that triggered issue
genprofile cap:sys_admin "qual=deny:mount:/snap/bin/:-> /**" \
"mount:options=(rw,bind):-> ${mount_point}/"
runchecktest "MOUNT (confined cap bind mount with deny mount that doesn't overlap)" pass mount ${mount_point2} ${mount_point} -o bind
remove_mnt
test_options
fi

View File

@@ -150,13 +150,19 @@ i386 | i486 | i586 | i686 | x86 | x86_64)
# But don't run them on xen kernels
if [ ! -d /proc/xen ] ; then
# lockdown thwarts both ioperm and iopl
expected=pass
if [ -f /sys/kernel/security/lockdown ] && ! grep -q "\[none\]" /sys/kernel/security/lockdown; then
expected=fail
fi
##
## F. IOPERM
##
settest syscall_ioperm
# TEST F1
runchecktest "IOPERM (no confinement)" pass 0 0x3ff
runchecktest "IOPERM (no confinement)" $expected 0 0x3ff
# TEST F2. ioperm will fail
genprofile
@@ -169,7 +175,7 @@ runchecktest "IOPERM (confinement)" fail 0 0x3ff
settest syscall_iopl
# TEST G1
runchecktest "IOPL (no confinement)" pass 3
runchecktest "IOPL (no confinement)" $expected 3
# TEST G2. iopl will fail
genprofile

View File

@@ -14,8 +14,14 @@ pwd=`cd $pwd ; /bin/pwd`
bin=$pwd
# TODO:
# need to update so we can run the test for ech supported
# need to be able to modify the compile features to choose the
# kernel feature supported
# need to be able to query the parser if it supports the
# kernel feature
. $bin/prologue.inc
requires_kernel_features network
requires_any_of_kernel_features network network_v8
port=34567
ip="127.0.0.1"

View File

@@ -113,6 +113,15 @@ def read_proc_current(filename):
return attr
def escape_special_chars(data):
"""escape special characters in program names so that they can't mess up the terminal"""
data = repr(data)
if len(data) > 1 and data.startswith("'") and data.endswith("'"):
return data[1:-1]
else:
return data
pids = set()
if paranoid:
pids = get_all_pids()
@@ -124,6 +133,7 @@ else:
for pid in sorted(map(int, pids)):
try:
prog = os.readlink("/proc/%s/exe" % pid)
prog = escape_special_chars(prog)
except OSError:
continue
@@ -140,6 +150,7 @@ for pid in sorted(map(int, pids)):
pname = cmdline.split("\0")[0]
if '/' in pname and pname != prog:
pname = "(%s)" % pname
pname = escape_special_chars(pname)
else:
pname = ""
regex_interpreter = re.compile(r"^(/usr)?/bin/(python|perl|bash|dash|sh)$")
@@ -147,6 +158,7 @@ for pid in sorted(map(int, pids)):
if regex_interpreter.search(prog):
cmdline = re.sub(r"\x00", " ", cmdline)
cmdline = re.sub(r"\s+$", "", cmdline).strip()
cmdline = escape_special_chars(cmdline)
ui.UI_Info(_("%(pid)s %(program)s (%(commandline)s) not confined") % {'pid': pid, 'program': prog, 'commandline': cmdline})
else:
@@ -157,6 +169,7 @@ for pid in sorted(map(int, pids)):
if regex_interpreter.search(prog):
cmdline = re.sub(r"\0", " ", cmdline)
cmdline = re.sub(r"\s+$", "", cmdline).strip()
cmdline = escape_special_chars(cmdline)
ui.UI_Info(_("%(pid)s %(program)s (%(commandline)s) confined by '%(attribute)s'") % {'pid': pid, 'program': prog, 'commandline': cmdline, 'attribute': attr})
else:
if pname and pname[-1] == ')':

View File

@@ -812,22 +812,17 @@ def ask_exec(hashlog):
'''ask the user about exec events (requests to execute another program) and which exec mode to use'''
for aamode in hashlog:
for profile in hashlog[aamode]:
if '//' in hashlog[aamode][profile]['final_name'] and hashlog[aamode][profile]['exec'].keys():
# TODO: is this really needed? Or would removing Cx from the options be good enough?
aaui.UI_Important('WARNING: Ignoring exec event in %s, nested profiles are not supported yet.' % hashlog[aamode][profile]['final_name'])
continue
for full_profile in hashlog[aamode]:
profile, hat = split_name(full_profile) # XXX temporary solution to avoid breaking the existing code
hat = profile # XXX temporary solution to avoid breaking the existing code
for exec_target in hashlog[aamode][profile]['exec']:
for target_profile in hashlog[aamode][profile]['exec'][exec_target]:
for exec_target in hashlog[aamode][full_profile]['exec']:
for target_profile in hashlog[aamode][full_profile]['exec'][exec_target]:
to_name = ''
if os.path.isdir(exec_target):
raise AppArmorBug('exec permissions requested for directory %s. This should not happen - please open a bugreport!' % exec_target)
if not aa[profile][hat]:
if not aa[profile].get(hat):
continue # ignore log entries for non-existing profiles
exec_event = FileRule(exec_target, None, FileRule.ANY_EXEC, FileRule.ALL, owner=False, log_event=True)
@@ -848,7 +843,9 @@ def ask_exec(hashlog):
##options = 'i'
# Don't allow hats to cx?
options.replace('c', '')
if '//' in hashlog[aamode][full_profile]['final_name'] and hashlog[aamode][full_profile]['exec'].keys():
options = options.replace('c', '')
# Add deny to options
options += 'd'
# Define the default option
@@ -1661,6 +1658,9 @@ def collapse_log(hashlog, ignore_null_profiles=True):
ptrace = hashlog[aamode][full_profile]['ptrace']
for peer in ptrace.keys():
if '//null-' in peer:
continue # ignore null-* peers
for access in ptrace[peer].keys():
ptrace_event = PtraceRule(access, peer, log_event=True)
if not hat_exists or not is_known_rule(aa[profile][hat], 'ptrace', ptrace_event):
@@ -1668,6 +1668,9 @@ def collapse_log(hashlog, ignore_null_profiles=True):
sig = hashlog[aamode][full_profile]['signal']
for peer in sig.keys():
if '//null-' in peer:
continue # ignore null-* peers
for access in sig[peer].keys():
for signal in sig[peer][access].keys():
signal_event = SignalRule(access, signal, peer, log_event=True)

View File

@@ -34,8 +34,8 @@ class ProfileList:
def __init__(self):
self.profile_names = {} # profile name -> filename
self.attachments = {} # attachment -> filename
self.attachments_AARE = {} # AARE(attachment) -> filename
self.attachments = {} # attachment -> {'f': filename, 'p': profile}
self.attachments_AARE = {} # attachment -> AARE(attachment)
self.files = {} # filename -> content - see init_file()
def __repr__(self):
@@ -72,7 +72,7 @@ class ProfileList:
self.profile_names[profile_name] = filename
if attachment:
self.attachments[attachment] = filename
self.attachments[attachment] = {'f': filename, 'p': profile_name or attachment} # if a profile doesn't have a name, the attachment is stored as profile name
self.attachments_AARE[attachment] = AARE(attachment, True)
self.init_file(filename)
@@ -164,18 +164,28 @@ class ProfileList:
def filename_from_attachment(self, attachment):
''' Return profile filename for the given attachment/executable path, or None '''
return self.thing_from_attachment(attachment, 'f')
def profile_from_attachment(self, attachment):
"""Return profile filename for the given attachment/executable path, or None"""
return self.thing_from_attachment(attachment, 'p')
def thing_from_attachment(self, attachment, thing):
"""Return thing for the given attachment/executable path, or None.
thing can be 'f' for filename or 'p' for profile name"""
if not attachment.startswith( ('/', '@', '{') ):
raise AppArmorBug('Called filename_from_attachment with non-path attachment: %s' % attachment)
# plain path
if self.attachments.get(attachment):
return self.attachments[attachment]
return self.attachments[attachment][thing]
# try AARE matches to cover profile names with alternations and wildcards
for path in self.attachments.keys():
if self.attachments_AARE[path].match(attachment):
return self.attachments[path] # XXX this returns the first match, not necessarily the best one
return self.attachments[path][thing] # XXX this returns the first match, not necessarily the best one
return None # nothing found

View File

@@ -61,15 +61,27 @@ class aa_tools:
profile = fq_path
else:
program = fq_path
profile = apparmor.get_profile_filename_from_attachment(fq_path, True)
if self.name == 'cleanprof':
profile = apparmor.active_profiles.profile_from_attachment(fq_path)
else:
profile = apparmor.get_profile_filename_from_attachment(fq_path, True)
else:
which = apparmor.which(p)
if which is not None:
if self.name == 'cleanprof' and p in apparmor.aa:
program = p # not really correct, but works
profile = p
elif which is not None:
program = apparmor.get_full_path(which)
profile = apparmor.get_profile_filename_from_attachment(program, True)
if self.name == 'cleanprof':
profile = program
else:
profile = apparmor.get_profile_filename_from_attachment(program, True)
elif os.path.exists(os.path.join(apparmor.profile_dir, p)):
program = None
profile = apparmor.get_full_path(os.path.join(apparmor.profile_dir, p)).strip()
if self.name == 'cleanprof':
profile = p
else:
profile = apparmor.get_full_path(os.path.join(apparmor.profile_dir, p)).strip()
else:
if '/' not in p:
aaui.UI_Info(_("Can't find %(program)s in the system path list. If the name of the application\nis correct, please run 'which %(program)s' as a user with correct PATH\nenvironment set up in order to find the fully-qualified path and\nuse the full path as parameter.") % { 'program': p })
@@ -87,15 +99,15 @@ class aa_tools:
if program is None:
program = profile
if not program or not(os.path.exists(program) or apparmor.profile_exists(program)):
if not program or not(os.path.exists(program) or profile in apparmor.aa):
if program and not program.startswith('/'):
program = aaui.UI_GetString(_('The given program cannot be found, please try with the fully qualified path name of the program: '), '')
else:
aaui.UI_Info(_("%s does not exist, please double-check the path.") % program)
sys.exit(1)
if program and apparmor.profile_exists(program):
self.clean_profile(program)
if program and profile in apparmor.aa:
self.clean_profile(program, profile)
else:
if '/' not in program:
@@ -193,14 +205,14 @@ class aa_tools:
if self.aa_mountpoint:
apparmor.reload(program)
def clean_profile(self, program):
filename = apparmor.get_profile_filename_from_attachment(program, True)
def clean_profile(self, program, profile):
filename = apparmor.get_profile_filename_from_profile_name(profile)
import apparmor.cleanprofile as cleanprofile
prof = cleanprofile.Prof(filename)
cleanprof = cleanprofile.CleanProf(True, prof, prof)
deleted = cleanprof.remove_duplicate_rules(program)
deleted = cleanprof.remove_duplicate_rules(profile)
aaui.UI_Info(_("\nDeleted %s rules.") % deleted)
apparmor.changed[program] = True
apparmor.changed[profile] = True
if filename:
if not self.silent:
@@ -216,14 +228,14 @@ class aa_tools:
while ans != 'CMD_SAVE_CHANGES':
ans, arg = q.promptUser()
if ans == 'CMD_SAVE_CHANGES':
apparmor.write_profile_ui_feedback(program, True)
apparmor.write_profile_ui_feedback(profile)
self.reload_profile(filename)
elif ans == 'CMD_VIEW_CHANGES':
#oldprofile = apparmor.serialize_profile(apparmor.original_aa[program], program, {})
newprofile = apparmor.serialize_profile(apparmor.aa[program], program, {'is_attachment': True})
#oldprofile = apparmor.serialize_profile(apparmor.original_aa[profile], program, {})
newprofile = apparmor.serialize_profile(apparmor.aa[profile], profile, {}) # {'is_attachment': True})
aaui.UI_Changes(filename, newprofile, comments=True)
else:
apparmor.write_profile_ui_feedback(program, True)
apparmor.write_profile_ui_feedback(profile, True)
self.reload_profile(filename)
else:
raise apparmor.AppArmorException(_('The profile for %s does not exists. Nothing to clean.') % program)

View File

@@ -111,6 +111,14 @@ exception_not_raised = [
'mount/bad_opt_29.sd',
'mount/bad_opt_30.sd',
'mount/bad_opt_31.sd',
'mount/bad_opt_32.sd',
'mount/bad_opt_35.sd',
'mount/bad_opt_36.sd',
'mount/bad_opt_37.sd',
'mount/bad_opt_38.sd',
'mount/bad_opt_39.sd',
'mount/bad_opt_40.sd',
'mount/bad_opt_41.sd',
'profile/flags/flags_bad10.sd',
'profile/flags/flags_bad11.sd',
'profile/flags/flags_bad12.sd',

View File

@@ -35,14 +35,14 @@ class TestAdd_profile(AATest):
def testAdd_profile_1(self):
self.pl.add_profile('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo')
self.assertEqual(self.pl.profile_names, {'foo': '/etc/apparmor.d/bin.foo'})
self.assertEqual(self.pl.attachments, {'/bin/foo': '/etc/apparmor.d/bin.foo'})
self.assertEqual(self.pl.attachments, {'/bin/foo': {'f': '/etc/apparmor.d/bin.foo', 'p': 'foo'}})
self.assertEqual(self.pl.profiles_in_file('/etc/apparmor.d/bin.foo'), ['foo'])
self.assertEqual('%s' % self.pl, '\n<ProfileList>\n/etc/apparmor.d/bin.foo\n</ProfileList>\n')
def testAdd_profile_2(self):
self.pl.add_profile('/etc/apparmor.d/bin.foo', None, '/bin/foo')
self.assertEqual(self.pl.profile_names, {})
self.assertEqual(self.pl.attachments, {'/bin/foo': '/etc/apparmor.d/bin.foo'})
self.assertEqual(self.pl.attachments, {'/bin/foo': {'f': '/etc/apparmor.d/bin.foo', 'p': '/bin/foo'}})
self.assertEqual(self.pl.profiles_in_file('/etc/apparmor.d/bin.foo'), ['/bin/foo'])
self.assertEqual('%s' % self.pl, '\n<ProfileList>\n/etc/apparmor.d/bin.foo\n</ProfileList>\n')
@@ -124,7 +124,11 @@ class TestFilename_from_attachment(AATest):
self.pl.add_profile('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo')
self.pl.add_profile('/etc/apparmor.d/bin.baz', 'baz', '/bin/ba*')
self.pl.add_profile('/etc/apparmor.d/bin.foobar', 'foobar', '/bin/foo{bar,baz}')
self.pl.add_profile('/etc/apparmor.d/usr.bin.wine', '/usr{,{/lib,/lib32,/lib64}/wine}/bin/wine{,-preloader,server}{,-staging-*,-vanilla-*}', '/usr{,{/lib,/lib32,/lib64}/wine}/bin/wine{,-preloader,server}{,-staging-*,-vanilla-*}')
self.pl.add_profile('/etc/apparmor.d/bin.asdf', None, '/bin/asdf')
self.pl.add_profile(
'/etc/apparmor.d/usr.bin.wine',
'wine',
'/usr{,{/lib,/lib32,/lib64}/wine}/bin/wine{,-preloader,server}{,-staging-*,-vanilla-*}')
def _run_test(self, params, expected):
self.assertEqual(self.pl.filename_from_attachment(params), expected)
@@ -133,6 +137,27 @@ class TestFilename_from_attachment(AATest):
with self.assertRaises(AppArmorBug):
self.pl.filename_from_attachment('foo')
class TestProfile_from_attachment(TestFilename_from_attachment):
# uses AASetup from TestFilename_from_attachment
tests = (
('/bin/foo', 'foo'),
('/bin/baz', 'baz'),
('/bin/foobar', 'foobar'),
('/bin/asdf', '/bin/asdf'),
('@{foo}', None), # XXX variables not supported yet (and @{foo} isn't defined in this test)
('/bin/404', None),
('/usr{,{/lib,/lib32,/lib64}/wine}/bin/wine{,-preloader,server}{,-staging-*,-vanilla-*}', 'wine'), # XXX should this really match, or should attachment matching only use AARE?
('/usr/lib/wine/bin/wine-preloader-staging-foo', 'wine'), # AARE match
)
def _run_test(self, params, expected):
self.assertEqual(self.pl.profile_from_attachment(params), expected)
def test_non_path_attachment(self):
with self.assertRaises(AppArmorBug):
self.pl.profile_from_attachment('foo')
class TestAdd_inc_ie(AATest):
def AASetup(self):
self.pl = ProfileList()