From e979fe05b06f525e5a65c767b4eabe5600147355 Mon Sep 17 00:00:00 2001 From: Alexandre Pujol Date: Sat, 23 Mar 2024 17:42:53 +0000 Subject: [PATCH] doc: add directives documentation. --- docs/development/dbus.md | 114 +++++++++++++++++++++---- docs/development/directives.md | 152 +++++++++++++++++++++++++++++++++ mkdocs.yml | 3 + 3 files changed, 252 insertions(+), 17 deletions(-) create mode 100644 docs/development/directives.md diff --git a/docs/development/dbus.md b/docs/development/dbus.md index 145fea53..8a533ae1 100644 --- a/docs/development/dbus.md +++ b/docs/development/dbus.md @@ -18,38 +18,118 @@ For more access, simply use the [`dbus: talk`](#dbus-directive) directive. ## Dbus Directive -We use a special directive to generate (when running `make`) more advanced dbus access. +We use a special [directive](directives.md) to generate more advanced dbus access. The directive format is on purpose very similar to apparmor dbus rule. -**Directive format** -``` -#aa:dbus: ( own | talk ) bus=( system | session ) name=AARE [label=AARE] [interface=AARE] [path=AARE] +**Format** + +```sh +#aa:dbus bus= name= [label=AARE] [interface=AARE] [path=AARE] ``` -The directive format is on purpose very similar to apparmor dbus rules. However, there are some restrictions: +**``** -- `bus` and `name` are mandatory and will break the build if ignored. -- For the *talk* sub directive, profile name under a `label` is also mandatory -- `interface` can optionally be given when it is different to the dbus path. -- `path` can optionally be given when it is different to the dbus name. -- It is still a comment: the rule must not end with a comma, multiline directive is not supported. +: Access type. Can be `own` or `talk`: -**Example:** + - `own` means the profile own this dbus interface. It is allowed to send and receive from anyone on this interface. + - `talk` means the profile can talk on a given interface to the profile owning it (that must be given under the `label` option). + +**``** + +: Dbus bus, can be `system`, `session` or `accessibility`. + +**``** + +: Dbus interface name. + +**`[label=AARE]`** + +: Name of the profile + +**`[interface=AARE]`** + +: Can optionally be given when it is different to the dbus path. + +**`[path=AARE]`** + +: Can optionally be given when it is different to the dbus name. + + +Note: ``, `` and `` are mandatory and will break the build if ignored. + + +**Example** Allow owning a dbus interface: !!! note "" - [apparmor.d/groups/network/NetworkManager](https://github.com/roddhjav/apparmor.d/blob/a3b15973640042af7da0ed540db690c711fbf6ec/apparmor.d/groups/network/NetworkManager#L46) - ``` aa linenums="46" - #aa:dbus: own bus=system name=org.freedesktop.NetworkManager + [apparmor.d/groups/network/NetworkManager](https://github.com/roddhjav/apparmor.d/blob/f81ceb91855f194dc53c10c17cbe1d7b50434a1e/apparmor.d/groups/network/NetworkManager#L45) + ``` sh linenums="45" + #aa:dbus own bus=system name=org.freedesktop.NetworkManager ``` Allow talking to a dbus interface on a given profile !!! note "" - [apparmor.d/groups/gnome/gdm](https://github.com/roddhjav/apparmor.d/blob/a3b15973640042af7da0ed540db690c711fbf6ec/apparmor.d/groups/gnome/gdm#L32) - ``` aa linenums="32" - #aa:dbus: talk bus=system name=org.freedesktop.login1 label=systemd-logind + [apparmor.d/groups/gnome/gdm](https://github.com/roddhjav/apparmor.d/blob/f81ceb91855f194dc53c10c17cbe1d7b50434a1e/apparmor.d/groups/gnome/gdm#L44) + ``` sh linenums="34" + #aa:dbus talk bus=system name=org.freedesktop.login1 label=systemd-logind ``` +**Generate** + +`#aa:dbus own bus=system name=org.freedesktop.NetworkManager` + +: + ```sh + dbus bind bus=system name=org.freedesktop.NetworkManager{,.*}, + dbus receive bus=system path=/org/freedesktop/NetworkManager{,/**} + interface=org.freedesktop.NetworkManager{,.*} + peer=(name=":1.@{int}"), + dbus receive bus=system path=/org/freedesktop/NetworkManager{,/**} + interface=org.freedesktop.DBus.Properties + peer=(name=":1.@{int}"), + dbus receive bus=system path=/org/freedesktop/NetworkManager{,/**} + interface=org.freedesktop.DBus.ObjectManager + peer=(name=":1.@{int}"), + dbus send bus=system path=/org/freedesktop/NetworkManager{,/**} + interface=org.freedesktop.NetworkManager{,.*} + peer=(name="{:1.@{int},org.freedesktop.DBus}"), + dbus send bus=system path=/org/freedesktop/NetworkManager{,/**} + interface=org.freedesktop.DBus.Properties + peer=(name="{:1.@{int},org.freedesktop.DBus}"), + dbus send bus=system path=/org/freedesktop/NetworkManager{,/**} + interface=org.freedesktop.DBus.ObjectManager + peer=(name="{:1.@{int},org.freedesktop.DBus}"), + dbus receive bus=system path=/org/freedesktop/NetworkManager{,/**} + interface=org.freedesktop.DBus.Introspectable + member=Introspect + peer=(name=":1.@{int}"), + ``` + +`#aa:dbus talk bus=system name=org.freedesktop.login1 label=systemd-logind` + +: + ```sh + dbus send bus=system path=/org/freedesktop/login1{,/**} + interface=org.freedesktop.login1{,.*} + peer=(name="{:1.@{int},org.freedesktop.login1{,.*}}", label=systemd-logind), + dbus send bus=system path=/org/freedesktop/login1{,/**} + interface=org.freedesktop.DBus.Properties + peer=(name="{:1.@{int},org.freedesktop.login1{,.*}}", label=systemd-logind), + dbus send bus=system path=/org/freedesktop/login1{,/**} + interface=org.freedesktop.DBus.ObjectManager + peer=(name="{:1.@{int},org.freedesktop.login1{,.*}}", label=systemd-logind), + dbus receive bus=system path=/org/freedesktop/login1{,/**} + interface=org.freedesktop.login1{,.*} + peer=(name="{:1.@{int},org.freedesktop.login1{,.*}}", label=systemd-logind), + dbus receive bus=system path=/org/freedesktop/login1{,/**} + interface=org.freedesktop.DBus.Properties + peer=(name="{:1.@{int},org.freedesktop.login1{,.*}}", label=systemd-logind), + dbus receive bus=system path=/org/freedesktop/login1{,/**} + interface=org.freedesktop.DBus.ObjectManager + peer=(name="{:1.@{int},org.freedesktop.login1{,.*}}", label=systemd-logind), + dbus send bus=system path=/org/freedesktop/Accounts{,/**} + interface=org.freedesktop.Accounts{,.*} + ``` \ No newline at end of file diff --git a/docs/development/directives.md b/docs/development/directives.md new file mode 100644 index 00000000..12befdb7 --- /dev/null +++ b/docs/development/directives.md @@ -0,0 +1,152 @@ +--- +title: Directives +--- + +`apparmor.d` supports build directives, they are processed at build time of the project, when running `make`. They are valid apparmor comment, `apparmor_parser` can be used on a profile even if the directives have not been processed. They should not end with a comma. Multiline directive is not supported. + +The directives follow the format: +```sh +#aa: [options] +``` + +**``** + +: The name of the directive to apply + + +**`[options]`** + +: A (possibly empty) list or map of arguments. Exact format depend on the directive. + +## Dbus + +See the [dbus page](dbus.md#dbus-directive). + + +## Only, Exclude + +The `only` and `exclude` directive can be used to filter individual rule or rule paragraph depending on the target distribution of distribution family. + +**Format** + +```sh +#aa:only +#aa:exclude +``` + +**``** + +: The filter to apply. Can be: + + - A supported target distribution: `arch`, `debian`, `ubuntu`, `opensuse`, `whonix`. + - A supported distribution family: `apt`, `pacman`, `zypper`. + +**Example** + +!!! note "" + + [apparmor.d/profiles-m-r/packagekitd](https://github.com/roddhjav/apparmor.d/blob/f81ceb91855f194dc53c10c17cbe1d7b50434a1e/apparmor.d/profiles-m-r/packagekitd#L99) + ``` sh linenums="99" + #aa:only opensuse + @{run}/zypp.pid rwk, + owner @{run}/zypp-rpm.pid rwk, + owner @{run}/zypp/packages/ r, + ``` + +**Generate** + +`#aa:only pacman` + +: + Remove the line/paragraph when the project is not compiled on the Archlinux family. + + +## Exec + +The `exec` directive is useful to allow executing transition to a profile without having to manage the possible long list of profile attachment (that varies depending on the distribution). The directive parse and resolve the attachment variable (`@{exec_path}`) of the target profile and include it in the current profile. + +**Format** + +```sh +#aa:exec [transition] profiles... +``` + +**`profiles...`** + +: List of profile **file** that can be executed from the current profile. + +**`[transition]`** + +: Optional transition mode (default: `P`). Can be any of: `P`, `U`, `p`, `u`, `PU`, `pu`. + + +**Example** + +!!! note "" + + [apparmor.d/groups/kde/ksmserver](https://github.com/roddhjav/apparmor.d/blob/f81ceb91855f194dc53c10c17cbe1d7b50434a1e/apparmor.d/groups/kde/ksmserver#L29) + ``` sh linenums="29" + #aa:exec kscreenlocker_greet + ``` + +**Generate** + +`#aa:exec baloo` + +: + ```sh + @{bin}/baloo_file Px, + @{lib}/@{multiarch}/{,libexec/}baloo_file Px, + @{lib}/{,kf6/}baloo_file Px, + ``` + + +## Stack + +[Stacked](https://gitlab.com/apparmor/apparmor/-/wikis/AppArmorStacking) profiles can be hard to maintain. The *parents* profile need to manage its own rules as well as always include stacked profile rules. This directive automatically include the stacked profile rules into the parent profile. + +**Format** + +```sh +#aa:stack profiles... +``` + +**`profiles...`** + +: List a profile **file** to stack at the end of the current profile. + + +**Example** + +!!! note "" + + [apparmor.d/_full/systemd](https://github.com/roddhjav/apparmor.d/blob/f81ceb91855f194dc53c10c17cbe1d7b50434a1e/apparmor.d/groups/_full/systemd#L150) + ``` sh linenums="150" + #aa:stack systemd-networkd systemd-oomd systemd-resolved systemd-timesyncd + ``` + +**Generate** + +`#aa:stack systemd-oomd` + +: + ```sh + # Stacked profile: systemd-oomd + include + include + capability dac_override, + capability kill, + unix (bind) type=stream addr=@@{hex}/bus/systemd-oomd/bus-api-oom, + #aa:dbus own bus=system name=org.freedesktop.oom1 + /etc/systemd/oomd.conf r, + /etc/systemd/oomd.conf.d/{,**} r, + @{run}/systemd/io.system.ManagedOOM rw, + @{run}/systemd/io.systemd.ManagedOOM rw, + @{run}/systemd/notify rw, + owner @{run}/systemd/journal/socket w, + @{sys}/fs/cgroup/cgroup.controllers r, + @{sys}/fs/cgroup/memory.pressure r, + @{sys}/fs/cgroup/user.slice/user-@{uid}.slice/user@@{uid}.service/memory.* r, + @{PROC}/pressure/{cpu,io,memory} r, + include if exists + ``` diff --git a/mkdocs.yml b/mkdocs.yml index 0a4274ec..c620dc0b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -91,6 +91,7 @@ markdown_extensions: - md_in_html - toc: permalink: true + toc_depth: 3 - pymdownx.betterem: smart_enable: all - pymdownx.caret @@ -143,6 +144,8 @@ nav: - development/install.md - development/guidelines.md - development/structure.md + - Profiles: + - development/directives.md - development/dbus.md - Tests: - development/tests.md