Merge branch 'roddhjav:main' into fix-slurp

This commit is contained in:
Stoppedpuma 2025-09-08 14:12:08 +00:00 committed by GitHub
commit f9b27e49eb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
72 changed files with 890 additions and 252 deletions

View file

@ -49,44 +49,44 @@ c := "--connect=qemu:///system"
# VM prefix # VM prefix
prefix := "aa-" prefix := "aa-"
[doc('Show this help message')] # Show this help message
help: help:
@just --list --unsorted @just --list --unsorted
@printf "\n%s\n" "See https://apparmor.pujol.io/development/ for more information." @printf "\n%s\n" "See https://apparmor.pujol.io/development/ for more information."
# Build the go programs
[group('build')] [group('build')]
[doc('Build the go programs')]
build: build:
@go build -o {{build}}/ ./cmd/aa-log @go build -o {{build}}/ ./cmd/aa-log
@go build -o {{build}}/ ./cmd/prebuild @go build -o {{build}}/ ./cmd/prebuild
# Prebuild the profiles in enforced mode
[group('build')] [group('build')]
[doc('Prebuild the profiles in enforced mode')]
enforce: build enforce: build
@./{{build}}/prebuild --buildir {{build}} @./{{build}}/prebuild --buildir {{build}}
# Prebuild the profiles in complain mode
[group('build')] [group('build')]
[doc('Prebuild the profiles in complain mode')]
complain: build complain: build
./{{build}}/prebuild --buildir {{build}} --complain ./{{build}}/prebuild --buildir {{build}} --complain
# Prebuild the profiles in FSP mode
[group('build')] [group('build')]
[doc('Prebuild the profiles in FSP mode')]
fsp: build fsp: build
@./{{build}}/prebuild --buildir {{build}} --full @./{{build}}/prebuild --buildir {{build}} --full
# Prebuild the profiles in FSP mode (complain)
[group('build')] [group('build')]
[doc('Prebuild the profiles in FSP mode (complain)')]
fsp-complain: build fsp-complain: build
@./{{build}}/prebuild --buildir {{build}} --complain --full @./{{build}}/prebuild --buildir {{build}} --complain --full
# Prebuild the profiles in FSP mode (debug)
[group('build')] [group('build')]
[doc('Prebuild the profiles in FSP mode (debug)')]
fsp-debug: build fsp-debug: build
@./{{build}}/prebuild --buildir {{build}} --complain --full --debug @./{{build}}/prebuild --buildir {{build}} --complain --full --debug
# Install prebuild profiles
[group('install')] [group('install')]
[doc('Install prebuild profiles')]
install: install:
#!/usr/bin/env bash #!/usr/bin/env bash
set -eu -o pipefail set -eu -o pipefail
@ -113,8 +113,8 @@ install:
install -Dm0644 "$file" "{{destdir}}/usr/lib/systemd/user/$service.d/apparmor.conf" install -Dm0644 "$file" "{{destdir}}/usr/lib/systemd/user/$service.d/apparmor.conf"
done done
# Locally install prebuild profiles
[group('install')] [group('install')]
[doc('Locally install prebuild profiles')]
local +names: local +names:
#!/usr/bin/env bash #!/usr/bin/env bash
set -eu -o pipefail set -eu -o pipefail
@ -135,39 +135,39 @@ local +names:
done; done;
systemctl restart apparmor || sudo journalctl -xeu apparmor.service systemctl restart apparmor || sudo journalctl -xeu apparmor.service
# Prebuild, install, and load a dev profile
[group('install')] [group('install')]
[doc('Prebuild, install, and load a dev profile')]
dev name: dev name:
go run ./cmd/prebuild --complain --file `find apparmor.d -iname {{name}}` go run ./cmd/prebuild --complain --file `find apparmor.d -iname {{name}}`
sudo install -Dm644 {{build}}/apparmor.d/{{name}} /etc/apparmor.d/{{name}} sudo install -Dm644 {{build}}/apparmor.d/{{name}} /etc/apparmor.d/{{name}}
sudo systemctl restart apparmor || sudo journalctl -xeu apparmor.service sudo systemctl restart apparmor || sudo journalctl -xeu apparmor.service
# Build & install apparmor.d on Arch based systems
[group('packages')] [group('packages')]
[doc('Build & install apparmor.d on Arch based systems')]
pkg: pkg:
@makepkg --syncdeps --install --cleanbuild --force --noconfirm @makepkg --syncdeps --install --cleanbuild --force --noconfirm
# Build & install apparmor.d on Debian based systems
[group('packages')] [group('packages')]
[doc('Build & install apparmor.d on Debian based systems')]
dpkg: dpkg:
@bash dists/build.sh dpkg @bash dists/build.sh dpkg
@sudo dpkg -i {{pkgdest}}/{{pkgname}}_*.deb @sudo dpkg -i {{pkgdest}}/{{pkgname}}_*.deb
# Build & install apparmor.d on OpenSUSE based systems
[group('packages')] [group('packages')]
[doc('Build & install apparmor.d on OpenSUSE based systems')]
rpm: rpm:
@bash dists/build.sh rpm @bash dists/build.sh rpm
@sudo rpm -ivh --force {{pkgdest}}/{{pkgname}}-*.rpm @sudo rpm -ivh --force {{pkgdest}}/{{pkgname}}-*.rpm
# Run the unit tests
[group('tests')] [group('tests')]
[doc('Run the unit tests')]
tests: tests:
@go test ./cmd/... -v -cover -coverprofile=coverage.out @go test ./cmd/... -v -cover -coverprofile=coverage.out
@go test ./pkg/... -v -cover -coverprofile=coverage.out @go test ./pkg/... -v -cover -coverprofile=coverage.out
@go tool cover -func=coverage.out @go tool cover -func=coverage.out
# Run the linters
[group('linter')] [group('linter')]
[doc('Run the linters')]
lint: lint:
golangci-lint run golangci-lint run
packer fmt tests/packer/ packer fmt tests/packer/
@ -177,34 +177,34 @@ lint:
tests/packer/init.sh tests/packer/src/aa-update tests/packer/clean.sh \ tests/packer/init.sh tests/packer/src/aa-update tests/packer/clean.sh \
debian/{{pkgname}}.postinst debian/{{pkgname}}.postrm debian/{{pkgname}}.postinst debian/{{pkgname}}.postrm
# Run style checks on the profiles
[group('linter')] [group('linter')]
[doc('Run style checks on the profiles')]
check: check:
@bash tests/check.sh @bash tests/check.sh
# Generate the man pages
[group('docs')] [group('docs')]
[doc('Generate the man pages')]
man: man:
@pandoc -t man -s -o share/man/man8/aa-log.8 share/man/man8/aa-log.md @pandoc -t man -s -o share/man/man8/aa-log.8 share/man/man8/aa-log.md
# Build the documentation
[group('docs')] [group('docs')]
[doc('Build the documentation')]
docs: docs:
@ENABLED_GIT_REVISION_DATE=false MKDOCS_OFFLINE=true mkdocs build --strict @ENABLED_GIT_REVISION_DATE=false MKDOCS_OFFLINE=true mkdocs build --strict
# Serve the documentation
[group('docs')] [group('docs')]
[doc('Serve the documentation')]
serve: serve:
@ENABLED_GIT_REVISION_DATE=false MKDOCS_OFFLINE=false mkdocs serve @ENABLED_GIT_REVISION_DATE=false MKDOCS_OFFLINE=false mkdocs serve
[doc('Remove all build artifacts')] # Remove all build artifacts
clean: clean:
@rm -rf \ @rm -rf \
debian/.debhelper debian/debhelper* debian/*.debhelper debian/{{pkgname}} \ debian/.debhelper debian/debhelper* debian/*.debhelper debian/{{pkgname}} \
{{pkgdest}}/{{pkgname}}* {{build}} coverage.out {{pkgdest}}/{{pkgname}}* {{build}} coverage.out
# Build the package in a clean OCI container
[group('packages')] [group('packages')]
[doc('Build the package in a clean OCI container')]
package dist: package dist:
#!/usr/bin/env bash #!/usr/bin/env bash
set -eu -o pipefail set -eu -o pipefail
@ -219,8 +219,8 @@ package dist:
fi fi
bash dists/docker.sh $dist $version bash dists/docker.sh $dist $version
# Build the VM image
[group('vm')] [group('vm')]
[doc('Build the VM image')]
img dist flavor: (package dist) img dist flavor: (package dist)
@mkdir -p {{base_dir}} @mkdir -p {{base_dir}}
packer build -force \ packer build -force \
@ -237,8 +237,8 @@ img dist flavor: (package dist)
-var output_dir={{output_dir}} \ -var output_dir={{output_dir}} \
tests/packer/ tests/packer/
# Create the machine
[group('vm')] [group('vm')]
[doc('Create the machine')]
create dist flavor: create dist flavor:
@cp -f {{base_dir}}/{{prefix}}{{dist}}-{{flavor}}.qcow2 {{vm}}/{{prefix}}{{dist}}-{{flavor}}.qcow2 @cp -f {{base_dir}}/{{prefix}}{{dist}}-{{flavor}}.qcow2 {{vm}}/{{prefix}}{{dist}}-{{flavor}}.qcow2
@virt-install {{c}} \ @virt-install {{c}} \
@ -257,53 +257,53 @@ create dist flavor:
--sound model=ich9 \ --sound model=ich9 \
--noautoconsole --noautoconsole
# Start a machine
[group('vm')] [group('vm')]
[doc('Start a machine')]
up dist flavor: up dist flavor:
@virsh {{c}} start {{prefix}}{{dist}}-{{flavor}} @virsh {{c}} start {{prefix}}{{dist}}-{{flavor}}
# Stops the machine
[group('vm')] [group('vm')]
[doc('Stops the machine')]
halt dist flavor: halt dist flavor:
@virsh {{c}} shutdown {{prefix}}{{dist}}-{{flavor}} @virsh {{c}} shutdown {{prefix}}{{dist}}-{{flavor}}
# Reboot the machine
[group('vm')] [group('vm')]
[doc('Reboot the machine')]
reboot dist flavor: reboot dist flavor:
@virsh {{c}} reboot {{prefix}}{{dist}}-{{flavor}} @virsh {{c}} reboot {{prefix}}{{dist}}-{{flavor}}
# Destroy the machine
[group('vm')] [group('vm')]
[doc('Destroy the machine')]
destroy dist flavor: destroy dist flavor:
@virsh {{c}} destroy {{prefix}}{{dist}}-{{flavor}} || true @virsh {{c}} destroy {{prefix}}{{dist}}-{{flavor}} || true
@virsh {{c}} undefine {{prefix}}{{dist}}-{{flavor}} --nvram @virsh {{c}} undefine {{prefix}}{{dist}}-{{flavor}} --nvram
@rm -fv {{vm}}/{{prefix}}{{dist}}-{{flavor}}.qcow2 @rm -fv {{vm}}/{{prefix}}{{dist}}-{{flavor}}.qcow2
# Connect to the machine
[group('vm')] [group('vm')]
[doc('Connect to the machine')]
ssh dist flavor: ssh dist flavor:
@ssh {{sshopt}} {{username}}@`just _get_ip {{dist}} {{flavor}}` @ssh {{sshopt}} {{username}}@`just _get_ip {{dist}} {{flavor}}`
# Mount the shared directory on the machine
[group('vm')] [group('vm')]
[doc('Mount the shared directory on the machine')]
mount dist flavor: mount dist flavor:
@ssh {{sshopt}} {{username}}@`just _get_ip {{dist}} {{flavor}}` \ @ssh {{sshopt}} {{username}}@`just _get_ip {{dist}} {{flavor}}` \
sh -c 'mount | grep 0a31bc478ef8e2461a4b1cc10a24cc4 || sudo mount 0a31bc478ef8e2461a4b1cc10a24cc4' sh -c 'mount | grep 0a31bc478ef8e2461a4b1cc10a24cc4 || sudo mount 0a31bc478ef8e2461a4b1cc10a24cc4'
# Unmout the shared directory on the machine
[group('vm')] [group('vm')]
[doc('Unmout the shared directory on the machine')]
umount dist flavor: umount dist flavor:
@ssh {{sshopt}} {{username}}@`just _get_ip {{dist}} {{flavor}}` \ @ssh {{sshopt}} {{username}}@`just _get_ip {{dist}} {{flavor}}` \
sh -c 'true; sudo umount /home/{{username}}/Projects/apparmor.d || true' sh -c 'true; sudo umount /home/{{username}}/Projects/apparmor.d || true'
# List the machines
[group('vm')] [group('vm')]
[doc('List the machines')]
list: list:
@printf "{{BOLD}} %-4s %-22s %s{{NORMAL}}\n" "Id" "Distribution-Flavor" "State" @printf "{{BOLD}} %-4s %-22s %s{{NORMAL}}\n" "Id" "Distribution-Flavor" "State"
@virsh {{c}} list --all | grep {{prefix}} | sed 's/{{prefix}}//g' @virsh {{c}} list --all | grep {{prefix}} | sed 's/{{prefix}}//g'
# List the VM images
[group('vm')] [group('vm')]
[doc('List the VM images')]
images: images:
#!/usr/bin/env bash #!/usr/bin/env bash
set -eu -o pipefail set -eu -o pipefail
@ -320,8 +320,8 @@ images:
} }
' '
# List the VM images that can be created
[group('vm')] [group('vm')]
[doc('List the VM images that can be created')]
available: available:
#!/usr/bin/env bash #!/usr/bin/env bash
set -eu -o pipefail set -eu -o pipefail
@ -337,36 +337,36 @@ available:
} }
' '
# Install dependencies for the integration tests
[group('tests')] [group('tests')]
[doc('Install dependencies for the integration tests')]
init: init:
@bash tests/requirements.sh @bash tests/requirements.sh
# Run the integration tests
[group('tests')] [group('tests')]
[doc('Run the integration tests')]
integration name="": integration name="":
bats --recursive --timing --print-output-on-failure tests/integration/{{name}} bats --recursive --timing --print-output-on-failure tests/integration/{{name}}
# Install dependencies for the integration tests (machine)
[group('tests')] [group('tests')]
[doc('Install dependencies for the integration tests (machine)')]
tests-init dist flavor: tests-init dist flavor:
@ssh {{sshopt}} {{username}}@`just _get_ip {{dist}} {{flavor}}` \ @ssh {{sshopt}} {{username}}@`just _get_ip {{dist}} {{flavor}}` \
just --justfile /home/{{username}}/Projects/apparmor.d/Justfile init just --justfile /home/{{username}}/Projects/apparmor.d/Justfile init
# Synchronize the integration tests (machine)
[group('tests')] [group('tests')]
[doc('Synchronize the integration tests (machine)')]
tests-sync dist flavor: tests-sync dist flavor:
@ssh {{sshopt}} {{username}}@`just _get_ip {{dist}} {{flavor}}` \ @ssh {{sshopt}} {{username}}@`just _get_ip {{dist}} {{flavor}}` \
rsync -a --delete /home/{{username}}/Projects/apparmor.d/tests/ /home/{{username}}/Projects/tests/ rsync -a --delete /home/{{username}}/Projects/apparmor.d/tests/ /home/{{username}}/Projects/tests/
# Re-synchronize the integration tests (machine)
[group('tests')] [group('tests')]
[doc('Re-synchronize the integration tests (machine)')]
tests-resync dist flavor: (mount dist flavor) \ tests-resync dist flavor: (mount dist flavor) \
(tests-sync dist flavor) \ (tests-sync dist flavor) \
(umount dist flavor) (umount dist flavor)
# Run the integration tests (machine)
[group('tests')] [group('tests')]
[doc('Run the integration tests (machine)')]
tests-run dist flavor name="": (tests-resync dist flavor) tests-run dist flavor name="": (tests-resync dist flavor)
ssh {{sshopt}} {{username}}@`just _get_ip {{dist}} {{flavor}}` \ ssh {{sshopt}} {{username}}@`just _get_ip {{dist}} {{flavor}}` \
bats --recursive --pretty --timing --print-output-on-failure \ bats --recursive --pretty --timing --print-output-on-failure \

111
PKGBUILD
View file

@ -3,8 +3,15 @@
# Warning: for development only, use https://aur.archlinux.org/packages/apparmor.d-git for production use. # Warning: for development only, use https://aur.archlinux.org/packages/apparmor.d-git for production use.
pkgname=apparmor.d pkgbase=apparmor.d
pkgver=0.001 pkgname=(
apparmor.d
# apparmor.d.enforced
# apparmor.d.fsp apparmor.d.fsp.enforced
# apparmor.d.server apparmor.d.server.enforced
# apparmor.d.server.fsp apparmor.d.server.fsp.enforced
)
pkgver=0.0001
pkgrel=1 pkgrel=1
pkgdesc="Full set of apparmor profiles" pkgdesc="Full set of apparmor profiles"
arch=('x86_64' 'armv6h' 'armv7h' 'aarch64') arch=('x86_64' 'armv6h' 'armv7h' 'aarch64')
@ -12,10 +19,9 @@ url="https://github.com/roddhjav/apparmor.d"
license=('GPL-2.0-only') license=('GPL-2.0-only')
depends=('apparmor>=4.1.0' 'apparmor<5.0.0') depends=('apparmor>=4.1.0' 'apparmor<5.0.0')
makedepends=('go' 'git' 'rsync' 'just') makedepends=('go' 'git' 'rsync' 'just')
conflicts=("$pkgname-git")
pkgver() { pkgver() {
cd "$srcdir/$pkgname" cd "$srcdir/$pkgbase"
echo "0.$(git rev-list --count HEAD)" echo "0.$(git rev-list --count HEAD)"
} }
@ -24,17 +30,104 @@ prepare() {
} }
build() { build() {
cd "$srcdir/$pkgname" cd "$srcdir/$pkgbase"
export CGO_CPPFLAGS="${CPPFLAGS}" export CGO_CPPFLAGS="${CPPFLAGS}"
export CGO_CFLAGS="${CFLAGS}" export CGO_CFLAGS="${CFLAGS}"
export CGO_CXXFLAGS="${CXXFLAGS}" export CGO_CXXFLAGS="${CXXFLAGS}"
export CGO_LDFLAGS="${LDFLAGS}" export CGO_LDFLAGS="${LDFLAGS}"
export GOPATH="${srcdir}"
export GOFLAGS="-buildmode=pie -trimpath -ldflags=-linkmode=external -mod=readonly -modcacherw" export GOFLAGS="-buildmode=pie -trimpath -ldflags=-linkmode=external -mod=readonly -modcacherw"
export DISTRIBUTION=arch export DISTRIBUTION=arch
just complain local -A modes=(
# Mapping of modes to just build target.
[default]=complain
# [enforced]=enforce
# [fsp]=fsp-complain
# [fsp.enforced]=fsp
# [server]=server-complain
# [server.enforced]=server
# [server.fsp]=server-fsp-complain
# [server.fsp.enforced]=server-fsp
)
for mode in "${!modes[@]}"; do
just build=".build/$mode" "${modes[$mode]}"
done
} }
package() { _conflicts() {
cd "$srcdir/$pkgname" local mode="$1"
just destdir="$pkgdir" install local pattern=".$mode"
if [[ "$mode" == "default" ]]; then
pattern=""
else
echo "$pkgbase"
fi
for pkg in "${pkgname[@]}"; do
if [[ "$pkg" == "${pkgbase}${pattern}" ]]; then
continue
fi
echo "$pkg"
done
}
_install() {
local mode="${1:?}"
cd "$srcdir/$pkgbase"
just build=".build/$mode" destdir="$pkgdir" install
}
package_apparmor.d() {
mode=default
pkgdesc="$pkgdesc (complain mode)"
mapfile -t conflicts < <(_conflicts $mode)
_install $mode
}
package_apparmor.d.enforced() {
mode=enforced
pkgdesc="$pkgdesc (enforced mode)"
mapfile -t conflicts < <(_conflicts $mode)
_install $mode
}
package_apparmor.d.fsp() {
mode="fsp"
pkgdesc="$pkgdesc (FSP mode)"
mapfile -t conflicts < <(_conflicts $mode)
_install $mode
}
package_apparmor.d.fsp.enforced() {
mode="fsp.enforced"
pkgdesc="$pkgdesc (FSP enforced mode)"
mapfile -t conflicts < <(_conflicts $mode)
_install $mode
}
package_apparmor.d.server() {
mode="server"
pkgdesc="$pkgdesc (server complain mode)"
mapfile -t conflicts < <(_conflicts $mode)
_install $mode
}
package_apparmor.d.server.enforced() {
mode="server.enforced"
pkgdesc="$pkgdesc (server enforced mode)"
mapfile -t conflicts < <(_conflicts $mode)
_install $mode
}
package_apparmor.d.server.fsp() {
mode="server.fsp"
pkgdesc="$pkgdesc (server FSP complain mode)"
mapfile -t conflicts < <(_conflicts $mode)
_install $mode
}
package_apparmor.d.server.fsp.enforced() {
mode="server.fsp.enforced"
pkgdesc="$pkgdesc (server FSP enforced mode)"
mapfile -t conflicts < <(_conflicts $mode)
_install $mode
} }

View file

@ -30,6 +30,7 @@
include <abstractions/bus/org.gnome.Mutter.IdleMonitor> include <abstractions/bus/org.gnome.Mutter.IdleMonitor>
include <abstractions/bus/org.gnome.SessionManager> include <abstractions/bus/org.gnome.SessionManager>
include <abstractions/bus/org.kde.kwalletd> include <abstractions/bus/org.kde.kwalletd>
include <abstractions/camera>
include <abstractions/common/chromium> include <abstractions/common/chromium>
include <abstractions/dconf-write> include <abstractions/dconf-write>
include <abstractions/desktop> include <abstractions/desktop>
@ -44,7 +45,6 @@
include <abstractions/uim> include <abstractions/uim>
include <abstractions/user-download-strict> include <abstractions/user-download-strict>
include <abstractions/user-read-strict> include <abstractions/user-read-strict>
include <abstractions/video>
network inet dgram, network inet dgram,
network inet6 dgram, network inet6 dgram,

View file

@ -0,0 +1,35 @@
# apparmor.d - Full set of apparmor profiles
# Copyright (C) 2025 Alexandre Pujol <alexandre@pujol.io>
# SPDX-License-Identifier: GPL-2.0-only
# Allows access to all cameras
abi <abi/4.0>,
# Allow detection of cameras. Leaks plugged in USB device info
@{sys}/bus/usb/devices/ r,
@{sys}/devices/@{pci}/usb@{int}/**/busnum r,
@{sys}/devices/@{pci}/usb@{int}/**/devnum r,
@{sys}/devices/@{pci}/usb@{int}/**/idProduct r,
@{sys}/devices/@{pci}/usb@{int}/**/idVendor r,
@{sys}/devices/@{pci}/usb@{int}/**/interface r,
@{sys}/devices/@{pci}/usb@{int}/**/modalias r,
@{sys}/devices/@{pci}/usb@{int}/**/speed r,
@{sys}/class/video4linux/ r,
@{sys}/devices/**/video4linux/** r,
@{sys}/devices/**/video4linux/video@{int}/ r,
@{sys}/devices/**/video4linux/video@{int}/uevent r,
@{run}/udev/data/+usb:* r, # Identifies all USB devices
@{run}/udev/data/c81:@{int} r, # For video4linux
# VideoCore cameras (shared device with VideoCore/EGL)
/dev/vchiq rw,
# Access to video /dev devices
/dev/video@{int} rw,
include if exists <abstractions/camera.d>
# vim:syntax=apparmor

View file

@ -16,6 +16,7 @@
include <abstractions/bus-session> include <abstractions/bus-session>
include <abstractions/bus-system> include <abstractions/bus-system>
include <abstractions/bus/org.a11y> include <abstractions/bus/org.a11y>
include <abstractions/camera>
include <abstractions/consoles> include <abstractions/consoles>
include <abstractions/cups-client> include <abstractions/cups-client>
include <abstractions/desktop> include <abstractions/desktop>
@ -30,7 +31,6 @@
include <abstractions/path> include <abstractions/path>
include <abstractions/sqlite> include <abstractions/sqlite>
include <abstractions/ssl_certs> include <abstractions/ssl_certs>
include <abstractions/video>
dbus bus=accessibility, dbus bus=accessibility,
dbus bus=session, dbus bus=session,

View file

@ -46,7 +46,7 @@
owner @{user_config_dirs}/kdeglobals r, owner @{user_config_dirs}/kdeglobals r,
owner @{user_config_dirs}/kwinrc r, owner @{user_config_dirs}/kwinrc r,
owner @{user_config_dirs}/session/ rw, owner @{user_config_dirs}/session/ rw,
owner @{user_config_dirs}/session/*_@{hex}_@{int}_@{int} rwlk, owner @{user_config_dirs}/session/*_* rwlk,
owner @{user_config_dirs}/session/#@{int} rw, owner @{user_config_dirs}/session/#@{int} rw,
owner @{user_config_dirs}/trashrc r, owner @{user_config_dirs}/trashrc r,

View file

@ -0,0 +1,20 @@
# apparmor.d - Full set of apparmor profiles
# Copyright (C) 2021 Canonical Ltd
# Copyright (C) 2025 Alexandre Pujol <alexandre@pujol.io>
# SPDX-License-Identifier: GPL-2.0-only
# Allows access to media controller such as microphones, and video capture hardware.
# See: https://www.kernel.org/doc/Documentation/userspace-api/media/mediactl/media-controller-intro.rst
abi <abi/4.0>,
# Control of media devices
/dev/media@{int} rwk,
# Access to V4L subnodes configuration
# See https://www.kernel.org/doc/html/v4.12/media/uapi/v4l/dev-subdev.html
/dev/v4l-subdev@{int} rw,
include if exists <abstractions/media-control.d>
# vim:syntax=apparmor

View file

@ -0,0 +1,16 @@
# apparmor.d - Full set of apparmor profiles
# Copyright (C) 2016-2017 Canonical Ltd
# Copyright (C) 2021-2025 Alexandre Pujol <alexandre@pujol.io>
# SPDX-License-Identifier: GPL-2.0-only
# Communication to the system TPM chip over /dev/tpm@{int} and kernel TPM
# resource manager /dev/tpmrm@{int}
abi <abi/4.0>,
/dev/tpm@{int} rw,
/dev/tpmrm@{int} rw,
include if exists <abstractions/tpm.d>
# vim:syntax=apparmor

View file

@ -9,9 +9,9 @@
owner @{user_share_dirs}/applications/wine/ rw, owner @{user_share_dirs}/applications/wine/ rw,
owner @{user_share_dirs}/applications/wine/**/ rw, owner @{user_share_dirs}/applications/wine/**/ rw,
owner @{tmp}/.wine-@{uid}/ rw, owner @{att}/@{tmp}/.wine-@{uid}/ rw,
owner @{tmp}/.wine-@{uid}/** rwk, owner @{att}/@{tmp}/.wine-@{uid}/** rwk,
owner @{tmp}/.wine-@{uid}/server-fd@{int2}-@{hex}/tmpmap-@{hex8} m, owner @{att}/@{tmp}/.wine-@{uid}/server-fd@{int2}-@{hex}/tmpmap-@{hex8} m,
owner /dev/shm/wine-@{hex6}-fsync rw, owner /dev/shm/wine-@{hex6}-fsync rw,
owner /dev/shm/wine-@{hex6}@{h}-fsync rw, owner /dev/shm/wine-@{hex6}@{h}-fsync rw,

View file

@ -12,6 +12,7 @@ profile epiphany @{exec_path} flags=(attach_disconnected) {
include <abstractions/audio-server> include <abstractions/audio-server>
include <abstractions/bus-system> include <abstractions/bus-system>
include <abstractions/bus/org.freedesktop.GeoClue2> include <abstractions/bus/org.freedesktop.GeoClue2>
include <abstractions/camera>
include <abstractions/common/bwrap> include <abstractions/common/bwrap>
include <abstractions/common/gnome> include <abstractions/common/gnome>
include <abstractions/gstreamer> include <abstractions/gstreamer>
@ -61,8 +62,6 @@ profile epiphany @{exec_path} flags=(attach_disconnected) {
deny @{user_share_dirs}/gvfs-metadata/* r, deny @{user_share_dirs}/gvfs-metadata/* r,
/dev/video@{int} rw,
include if exists <local/epiphany> include if exists <local/epiphany>
} }

View file

@ -25,7 +25,7 @@ profile cups-backend-pdf @{exec_path} {
@{sh_path} rix, @{sh_path} rix,
@{bin}/cp rix, @{bin}/cp rix,
@{bin}/gs rix, @{bin}/gs{,.bin} rix,
@{bin}/gsc rix, @{bin}/gsc rix,
@{lib}/ghostscript/** mr, @{lib}/ghostscript/** mr,

View file

@ -62,7 +62,7 @@ profile cupsd @{exec_path} flags=(attach_disconnected) {
@{bin}/chmod rix, @{bin}/chmod rix,
@{bin}/cp rix, @{bin}/cp rix,
@{bin}/{,e}grep rix, @{bin}/{,e}grep rix,
@{bin}/gs rix, @{bin}/gs{,.bin} rix,
@{bin}/gsc rix, @{bin}/gsc rix,
@{bin}/hostname rix, @{bin}/hostname rix,
@{bin}/ippfind rix, @{bin}/ippfind rix,

View file

@ -11,8 +11,10 @@ profile ufw-init @{exec_path} {
include <abstractions/base> include <abstractions/base>
include <abstractions/nameservice-strict> include <abstractions/nameservice-strict>
capability dac_override,
capability dac_read_search, capability dac_read_search,
capability net_admin, capability net_admin,
capability net_raw,
network inet dgram, network inet dgram,
network inet raw, network inet raw,
@ -27,12 +29,29 @@ profile ufw-init @{exec_path} {
@{sbin}/sysctl rCx -> sysctl, @{sbin}/sysctl rCx -> sysctl,
@{sbin}/xtables-legacy-multi rix, @{sbin}/xtables-legacy-multi rix,
@{sbin}/xtables-nft-multi rix, @{sbin}/xtables-nft-multi rix,
@{bin}/kmod rCx -> kmod,
/etc/default/ufw r, /etc/default/ufw r,
/etc/ufw/* r, /etc/ufw/* r,
@{run}/xtables.lock rwk,
@{PROC}/@{pid}/net/ip_tables_names r, @{PROC}/@{pid}/net/ip_tables_names r,
# @{PROC}/sys/net/ipv{4,6}/** rw, @{PROC}/sys/kernel/modprobe r,
profile kmod {
include <abstractions/base>
include <abstractions/app/kmod>
capability sys_module,
@{run}/xtables.lock r,
@{sys}/module/compression r,
@{sys}/module/x_tables/initstate r,
include if exists <local/ufw-init_kmod>
}
profile sysctl { profile sysctl {
include <abstractions/base> include <abstractions/base>

View file

@ -14,8 +14,9 @@ profile pipewire @{exec_path} flags=(attach_disconnected) {
include <abstractions/bus-session> include <abstractions/bus-session>
include <abstractions/bus-system> include <abstractions/bus-system>
include <abstractions/bus/org.freedesktop.RealtimeKit1> include <abstractions/bus/org.freedesktop.RealtimeKit1>
include <abstractions/camera>
include <abstractions/media-control>
include <abstractions/nameservice-strict> include <abstractions/nameservice-strict>
include <abstractions/video>
capability sys_ptrace, capability sys_ptrace,
@ -66,8 +67,6 @@ profile pipewire @{exec_path} flags=(attach_disconnected) {
owner @{PROC}/@{pid}/attr/apparmor/current r, owner @{PROC}/@{pid}/attr/apparmor/current r,
owner @{PROC}/@{pid}/task/@{tid}/comm rw, owner @{PROC}/@{pid}/task/@{tid}/comm rw,
/dev/media@{int} rw,
include if exists <local/pipewire> include if exists <local/pipewire>
} }

View file

@ -14,9 +14,9 @@ profile pipewire-media-session @{exec_path} {
include <abstractions/bus-session> include <abstractions/bus-session>
include <abstractions/bus-system> include <abstractions/bus-system>
include <abstractions/bus/org.freedesktop.RealtimeKit1> include <abstractions/bus/org.freedesktop.RealtimeKit1>
include <abstractions/camera>
include <abstractions/devices-usb> include <abstractions/devices-usb>
include <abstractions/nameservice-strict> include <abstractions/nameservice-strict>
include <abstractions/video>
network bluetooth raw, network bluetooth raw,
network bluetooth seqpacket, network bluetooth seqpacket,

View file

@ -18,6 +18,7 @@ profile pulseaudio @{exec_path} {
include <abstractions/bus/org.freedesktop.Avahi> include <abstractions/bus/org.freedesktop.Avahi>
include <abstractions/bus/org.freedesktop.hostname1> include <abstractions/bus/org.freedesktop.hostname1>
include <abstractions/bus/org.freedesktop.RealtimeKit1> include <abstractions/bus/org.freedesktop.RealtimeKit1>
include <abstractions/camera>
include <abstractions/consoles> include <abstractions/consoles>
include <abstractions/dconf-write> include <abstractions/dconf-write>
include <abstractions/dri> include <abstractions/dri>
@ -25,6 +26,7 @@ profile pulseaudio @{exec_path} {
include <abstractions/desktop> include <abstractions/desktop>
include <abstractions/gstreamer> include <abstractions/gstreamer>
include <abstractions/hosts_access> include <abstractions/hosts_access>
include <abstractions/media-control>
include <abstractions/nameservice-strict> include <abstractions/nameservice-strict>
ptrace (trace) peer=@{profile_name}, ptrace (trace) peer=@{profile_name},
@ -105,7 +107,6 @@ profile pulseaudio @{exec_path} {
@{sys}/devices/**/sound/**/{uevent,pcm_class} r, @{sys}/devices/**/sound/**/{uevent,pcm_class} r,
@{sys}/devices/virtual/dmi/id/{bios_vendor,board_vendor,sys_vendor} r, @{sys}/devices/virtual/dmi/id/{bios_vendor,board_vendor,sys_vendor} r,
@{sys}/devices/virtual/video4linux/video@{int}/uevent r,
deny @{sys}/module/apparmor/parameters/enabled r, deny @{sys}/module/apparmor/parameters/enabled r,
@ -113,9 +114,6 @@ profile pulseaudio @{exec_path} {
owner @{PROC}/@{pids}/stat r, owner @{PROC}/@{pids}/stat r,
owner @{PROC}/@{pids}/cmdline r, owner @{PROC}/@{pids}/cmdline r,
/dev/media@{int} r,
/dev/video@{int} rw,
# file_inherit # file_inherit
owner /dev/tty@{int} rw, owner /dev/tty@{int} rw,

View file

@ -16,9 +16,10 @@ profile wireplumber @{exec_path} {
include <abstractions/bus/org.freedesktop.impl.portal.PermissionStore> include <abstractions/bus/org.freedesktop.impl.portal.PermissionStore>
include <abstractions/bus/org.freedesktop.RealtimeKit1> include <abstractions/bus/org.freedesktop.RealtimeKit1>
include <abstractions/bus/org.freedesktop.UPower> include <abstractions/bus/org.freedesktop.UPower>
include <abstractions/camera>
include <abstractions/devices-usb> include <abstractions/devices-usb>
include <abstractions/media-control>
include <abstractions/nameservice-strict> include <abstractions/nameservice-strict>
include <abstractions/video>
network bluetooth raw, network bluetooth raw,
network bluetooth seqpacket, network bluetooth seqpacket,
@ -65,13 +66,11 @@ profile wireplumber @{exec_path} {
@{run}/systemd/users/@{uid} r, @{run}/systemd/users/@{uid} r,
@{run}/udev/data/c14:@{int} r, # Open Sound System (OSS) @{run}/udev/data/c14:@{int} r, # Open Sound System (OSS)
@{run}/udev/data/c81:@{int} r, # For video4linux
@{run}/udev/data/c116:@{int} r, # For ALSA @{run}/udev/data/c116:@{int} r, # For ALSA
@{run}/udev/data/c@{dynamic}:@{int} r, # For dynamic assignment range 234 to 254, 384 to 511 @{run}/udev/data/c@{dynamic}:@{int} r, # For dynamic assignment range 234 to 254, 384 to 511
@{sys}/bus/ r, @{sys}/bus/ r,
@{sys}/bus/media/devices/ r, @{sys}/bus/media/devices/ r,
@{sys}/devices/@{pci}/video4linux/video@{int}/uevent r,
@{sys}/devices/**/device:*/{,**/}path r, @{sys}/devices/**/device:*/{,**/}path r,
@{sys}/devices/**/sound/**/pcm_class r, @{sys}/devices/**/sound/**/pcm_class r,
@{sys}/devices/**/sound/**/uevent r, @{sys}/devices/**/sound/**/uevent r,
@ -87,7 +86,6 @@ profile wireplumber @{exec_path} {
owner @{PROC}/@{pid}/cgroup r, owner @{PROC}/@{pid}/cgroup r,
owner @{PROC}/@{pid}/task/@{tid}/comm rw, owner @{PROC}/@{pid}/task/@{tid}/comm rw,
/dev/media@{int} rw,
/dev/udmabuf rw, /dev/udmabuf rw,
include if exists <local/wireplumber> include if exists <local/wireplumber>

View file

@ -8,7 +8,7 @@ abi <abi/4.0>,
include <tunables/global> include <tunables/global>
@{exec_path} = @{bin}/xdg-settings @{exec_path} = @{bin}/xdg-settings
profile xdg-settings @{exec_path} { profile xdg-settings @{exec_path} flags=(attach_disconnected) {
include <abstractions/base> include <abstractions/base>
include <abstractions/consoles> include <abstractions/consoles>
include <abstractions/freedesktop.org> include <abstractions/freedesktop.org>

View file

@ -13,10 +13,12 @@ profile gnome-boxes @{exec_path} {
include <abstractions/bus-session> include <abstractions/bus-session>
include <abstractions/bus-system> include <abstractions/bus-system>
include <abstractions/bus/org.freedesktop.timedate1> include <abstractions/bus/org.freedesktop.timedate1>
include <abstractions/camera>
include <abstractions/dconf-write> include <abstractions/dconf-write>
include <abstractions/gnome-strict> include <abstractions/gnome-strict>
include <abstractions/graphics> include <abstractions/graphics>
include <abstractions/gstreamer> include <abstractions/gstreamer>
include <abstractions/media-control>
include <abstractions/nameservice-strict> include <abstractions/nameservice-strict>
include <abstractions/p11-kit> include <abstractions/p11-kit>
include <abstractions/ssl_certs> include <abstractions/ssl_certs>
@ -80,9 +82,6 @@ profile gnome-boxes @{exec_path} {
owner @{PROC}/@{pid}/mountinfo r, owner @{PROC}/@{pid}/mountinfo r,
owner @{PROC}/@{pid}/stat r, owner @{PROC}/@{pid}/stat r,
/dev/media@{int} rw,
/dev/video@{int} rw,
deny owner @{user_share_dirs}/gvfs-metadata/{,*} r, deny owner @{user_share_dirs}/gvfs-metadata/{,*} r,
profile virsh { profile virsh {

View file

@ -7,7 +7,7 @@ abi <abi/4.0>,
include <tunables/global> include <tunables/global>
@{exec_path} = @{bin}/gnome-calculator @{exec_path} = @{bin}/gnome-calculator
profile gnome-calculator @{exec_path} { profile gnome-calculator @{exec_path} flags=(attach_disconnected) {
include <abstractions/base> include <abstractions/base>
include <abstractions/common/gnome> include <abstractions/common/gnome>
include <abstractions/nameservice-strict> include <abstractions/nameservice-strict>

View file

@ -17,11 +17,13 @@ profile gnome-control-center @{exec_path} flags=(attach_disconnected) {
include <abstractions/bus/org.freedesktop.Avahi> include <abstractions/bus/org.freedesktop.Avahi>
include <abstractions/bus/org.freedesktop.portal.Desktop> include <abstractions/bus/org.freedesktop.portal.Desktop>
include <abstractions/bus/org.gtk.vfs.MountTracker> include <abstractions/bus/org.gtk.vfs.MountTracker>
include <abstractions/camera>
include <abstractions/cups-client> include <abstractions/cups-client>
include <abstractions/dconf-write> include <abstractions/dconf-write>
include <abstractions/gnome-strict> include <abstractions/gnome-strict>
include <abstractions/graphics> include <abstractions/graphics>
include <abstractions/gstreamer> include <abstractions/gstreamer>
include <abstractions/media-control>
include <abstractions/nameservice-strict> include <abstractions/nameservice-strict>
include <abstractions/p11-kit> include <abstractions/p11-kit>
include <abstractions/ssl_certs> include <abstractions/ssl_certs>
@ -191,8 +193,6 @@ profile gnome-control-center @{exec_path} flags=(attach_disconnected) {
owner @{PROC}/@{pid}/task/*/comm rw, owner @{PROC}/@{pid}/task/*/comm rw,
/dev/ r, /dev/ r,
/dev/media@{int} r,
/dev/video@{int} rw,
deny owner @{user_share_dirs}/gvfs-metadata/{,*} r, deny owner @{user_share_dirs}/gvfs-metadata/{,*} r,

View file

@ -32,18 +32,19 @@ profile gnome-shell @{exec_path} flags=(attach_disconnected,mediate_deleted) {
include <abstractions/bus/org.freedesktop.systemd1> include <abstractions/bus/org.freedesktop.systemd1>
include <abstractions/bus/org.freedesktop.UPower> include <abstractions/bus/org.freedesktop.UPower>
include <abstractions/bus/org.gtk.Private.RemoteVolumeMonitor> include <abstractions/bus/org.gtk.Private.RemoteVolumeMonitor>
include <abstractions/camera>
include <abstractions/dconf-write> include <abstractions/dconf-write>
include <abstractions/fontconfig-cache-write> include <abstractions/fontconfig-cache-write>
include <abstractions/gnome-strict> include <abstractions/gnome-strict>
include <abstractions/graphics> include <abstractions/graphics>
include <abstractions/gstreamer> include <abstractions/gstreamer>
include <abstractions/ibus> include <abstractions/ibus>
include <abstractions/media-control>
include <abstractions/nameservice-strict> include <abstractions/nameservice-strict>
include <abstractions/notifications> include <abstractions/notifications>
include <abstractions/p11-kit> include <abstractions/p11-kit>
include <abstractions/ssl_certs> include <abstractions/ssl_certs>
include <abstractions/thumbnails-cache-read> include <abstractions/thumbnails-cache-read>
include <abstractions/video>
capability sys_nice, capability sys_nice,
capability sys_ptrace, capability sys_ptrace,
@ -321,7 +322,6 @@ profile gnome-shell @{exec_path} flags=(attach_disconnected,mediate_deleted) {
@{run}/udev/data/+acpi:* r, # Exposes ACPI objects (power buttons, batteries, thermal) @{run}/udev/data/+acpi:* r, # Exposes ACPI objects (power buttons, batteries, thermal)
@{run}/udev/data/+pci:* r, # Identifies all PCI devices (CPU, GPU, Network, Disks, USB, etc.) @{run}/udev/data/+pci:* r, # Identifies all PCI devices (CPU, GPU, Network, Disks, USB, etc.)
@{run}/udev/data/+sound:card@{int} r, # for sound card @{run}/udev/data/+sound:card@{int} r, # for sound card
@{run}/udev/data/+usb:* r, # Identifies all USB devices
@{run}/udev/data/+i2c:* r, # For Inter-Integrated Circuit, low-speed peripherals (sensors, EEPROMs, etc.) @{run}/udev/data/+i2c:* r, # For Inter-Integrated Circuit, low-speed peripherals (sensors, EEPROMs, etc.)
@{run}/udev/data/+hid:* r, # For Human Interface Device (mice, controllers, drawing tablets, scanners) @{run}/udev/data/+hid:* r, # For Human Interface Device (mice, controllers, drawing tablets, scanners)
@{run}/udev/data/c10:@{int} r, # for non-serial mice, misc features @{run}/udev/data/c10:@{int} r, # for non-serial mice, misc features
@ -379,7 +379,6 @@ profile gnome-shell @{exec_path} flags=(attach_disconnected,mediate_deleted) {
owner @{PROC}/@{pid}/task/@{tid}/comm rw, owner @{PROC}/@{pid}/task/@{tid}/comm rw,
owner @{PROC}/@{pid}/task/@{tid}/stat r, owner @{PROC}/@{pid}/task/@{tid}/stat r,
/dev/media@{int} rw,
/dev/tty@{int} rw, /dev/tty@{int} rw,
@{att}/dev/dri/card@{int} rw, @{att}/dev/dri/card@{int} rw,
@{att}/dev/input/event@{int} rw, @{att}/dev/input/event@{int} rw,

View file

@ -68,9 +68,6 @@ profile localsearch @{exec_path} flags=(attach_disconnected) {
owner @{PROC}/@{pid}/mounts r, owner @{PROC}/@{pid}/mounts r,
owner @{PROC}/@{pid}/task/@{tid}/comm rw, owner @{PROC}/@{pid}/task/@{tid}/comm rw,
/dev/media@{int} rw,
/dev/video@{int} rw,
include if exists <local/localsearch> include if exists <local/localsearch>
} }

View file

@ -10,14 +10,15 @@ include <tunables/global>
profile org.gnome.NautilusPreviewer @{exec_path} flags=(attach_disconnected) { profile org.gnome.NautilusPreviewer @{exec_path} flags=(attach_disconnected) {
include <abstractions/base> include <abstractions/base>
include <abstractions/audio-client> include <abstractions/audio-client>
include <abstractions/camera>
include <abstractions/dconf-write> include <abstractions/dconf-write>
include <abstractions/deny-sensitive-home> include <abstractions/deny-sensitive-home>
include <abstractions/gnome-strict> include <abstractions/gnome-strict>
include <abstractions/graphics> include <abstractions/graphics>
include <abstractions/gstreamer> include <abstractions/gstreamer>
include <abstractions/media-control>
include <abstractions/nameservice-strict> include <abstractions/nameservice-strict>
include <abstractions/private-files-strict> include <abstractions/private-files-strict>
include <abstractions/video>
network netlink raw, network netlink raw,
@ -52,8 +53,6 @@ profile org.gnome.NautilusPreviewer @{exec_path} flags=(attach_disconnected) {
owner @{PROC}/@{pid}/task/@{tid}/comm w, owner @{PROC}/@{pid}/task/@{tid}/comm w,
owner @{PROC}/@{pid}/task/@{tid}/stat r, owner @{PROC}/@{pid}/task/@{tid}/stat r,
/dev/media@{int} r,
include if exists <local/org.gnome.NautilusPreviewer> include if exists <local/org.gnome.NautilusPreviewer>
} }

View file

@ -25,7 +25,11 @@ profile dolphin @{exec_path} {
network netlink raw, network netlink raw,
signal (send) set=(term) peer=kioworker, signal send set=hup peer=@{p_systemd},
signal send set=term peer=kioworker,
ptrace read peer=@{p_systemd},
ptrace read peer=okular,
@{exec_path} mr, @{exec_path} mr,
@ -109,10 +113,11 @@ profile dolphin @{exec_path} {
owner @{PROC}/@{pid}/cmdline r, owner @{PROC}/@{pid}/cmdline r,
owner @{PROC}/@{pid}/mountinfo r, owner @{PROC}/@{pid}/mountinfo r,
owner @{PROC}/@{pid}/mounts r, owner @{PROC}/@{pid}/mounts r,
owner @{PROC}/@{pid}/stat r,
@{sys}/devices/virtual/block/dm-@{int}/uevent r, @{sys}/devices/virtual/block/dm-@{int}/uevent r,
/dev/tty r, /dev/tty rw,
include if exists <local/dolphin> include if exists <local/dolphin>
} }

View file

@ -41,7 +41,7 @@ profile kioworker @{exec_path} {
@{lib}/libheif/*.so* rm, @{lib}/libheif/*.so* rm,
@{bin}/wrestool rPUx, @{bin}/wrestool rPUx,
@{bin}/gs rix, @{bin}/gs{,.bin} rix,
#aa:exec kio_http_cache_cleaner #aa:exec kio_http_cache_cleaner

View file

@ -41,6 +41,7 @@ profile kwin_x11 @{exec_path} {
/usr/share/kwin-x11/{,**} r, /usr/share/kwin-x11/{,**} r,
/usr/share/kwin/{,**} r, /usr/share/kwin/{,**} r,
/usr/share/plasma/desktoptheme/{,**} r, /usr/share/plasma/desktoptheme/{,**} r,
/usr/share/sounds/*/stereo/*.oga r,
/etc/machine-id r, /etc/machine-id r,
/etc/xdg/plasmarc r, /etc/xdg/plasmarc r,

View file

@ -23,6 +23,8 @@ profile okular @{exec_path} {
network netlink raw, network netlink raw,
ptrace read peer=@{p_systemd},
signal send set=term peer=kioworker, signal send set=term peer=kioworker,
@{exec_path} mr, @{exec_path} mr,
@ -69,7 +71,7 @@ profile okular @{exec_path} {
owner @{user_state_dirs}/#@{int} rw, owner @{user_state_dirs}/#@{int} rw,
owner @{user_state_dirs}/okularstaterc rw, owner @{user_state_dirs}/okularstaterc rw,
owner @{user_state_dirs}/okularstaterc.@{rand6} rwl -> @{user_state_dirs}/#@{int}, owner @{user_state_dirs}/okularstaterc.@{rand6} rwlk -> @{user_state_dirs}/#@{int},
owner @{user_state_dirs}/okularstaterc.lock rwk, owner @{user_state_dirs}/okularstaterc.lock rwk,
owner @{tmp}/#@{int} rw, owner @{tmp}/#@{int} rw,
@ -82,6 +84,7 @@ profile okular @{exec_path} {
owner @{PROC}/@{pid}/mountinfo r, owner @{PROC}/@{pid}/mountinfo r,
owner @{PROC}/@{pid}/mounts r, owner @{PROC}/@{pid}/mounts r,
owner @{PROC}/@{pid}/stat r,
profile gpg { profile gpg {
include <abstractions/base> include <abstractions/base>

View file

@ -7,7 +7,7 @@ abi <abi/4.0>,
include <tunables/global> include <tunables/global>
@{exec_path} = @{bin}/pgrep @{exec_path} = @{bin}/pgrep
profile pgrep @{exec_path} { profile pgrep @{exec_path} flags=(attach_disconnected) {
include <abstractions/base> include <abstractions/base>
include <abstractions/app/pgrep> include <abstractions/app/pgrep>
include <abstractions/nameservice-strict> include <abstractions/nameservice-strict>

View file

@ -136,7 +136,7 @@ profile systemd-logind @{exec_path} flags=(attach_disconnected) {
@{PROC}/sysvipc/{shm,sem,msg} r, @{PROC}/sysvipc/{shm,sem,msg} r,
owner @{PROC}/@{pid}/fdinfo/@{int} r, owner @{PROC}/@{pid}/fdinfo/@{int} r,
/dev/dri/card@{int} rw, @{att}/dev/dri/card@{int} rw,
/dev/input/event@{int} rw, # Input devices (keyboard, mouse, etc) /dev/input/event@{int} rw, # Input devices (keyboard, mouse, etc)
/dev/mqueue/ r, /dev/mqueue/ r,
/dev/tty@{int} rw, /dev/tty@{int} rw,

View file

@ -8,7 +8,7 @@ abi <abi/4.0>,
include <tunables/global> include <tunables/global>
@{exec_path} = @{bin}/su @{exec_path} = @{bin}/su
profile su @{exec_path} { profile su @{exec_path} flags=(attach_disconnected) {
include <abstractions/base> include <abstractions/base>
include <abstractions/app-launcher-root> include <abstractions/app-launcher-root>
include <abstractions/app/sudo> include <abstractions/app/sudo>

View file

@ -0,0 +1,31 @@
# apparmor.d - Full set of apparmor profiles
# Copyright (C) 2024 Alexandre Pujol <alexandre@pujol.io>
# Copyright (C) 2025 Sighy Brantler <sighy.brantler@mailfence.com>
# SPDX-License-Identifier: GPL-2.0-only
abi <abi/4.0>,
include <tunables/global>
@{exec_path} = @{bin}/xfce4-clipman
profile xfce-clipman @{exec_path} {
include <abstractions/base>
include <abstractions/dconf>
include <abstractions/nameservice-strict>
include <abstractions/xfce>
@{exec_path} mr,
/etc/xdg/xfce4/panel/xfce4-clipman-actions.xml r,
owner @{user_cache_dirs}/xfce4/clipman/ r,
owner @{user_cache_dirs}/xfce4/clipman/* rw,
owner @{user_config_dirs}/autostart/ r,
owner @{user_config_dirs}/autostart/xfce4-clipman-plugin-autostart.desktop rw,
owner @{user_config_dirs}/autostart/xfce4-clipman-plugin-autostart.desktop.@{rand6} rw,
include if exists <local/xfce-clipman>
}
# vim:syntax=apparmor

View file

@ -11,10 +11,12 @@ include <tunables/global>
profile cheese @{exec_path} { profile cheese @{exec_path} {
include <abstractions/base> include <abstractions/base>
include <abstractions/audio-client> include <abstractions/audio-client>
include <abstractions/camera>
include <abstractions/dconf-write> include <abstractions/dconf-write>
include <abstractions/desktop> include <abstractions/desktop>
include <abstractions/graphics> include <abstractions/graphics>
include <abstractions/gstreamer> include <abstractions/gstreamer>
include <abstractions/media-control>
include <abstractions/nameservice-strict> include <abstractions/nameservice-strict>
include <abstractions/thumbnails-cache-write> include <abstractions/thumbnails-cache-write>
@ -49,9 +51,6 @@ profile cheese @{exec_path} {
owner @{PROC}/@{pid}/task/@{tid}/comm rw, owner @{PROC}/@{pid}/task/@{tid}/comm rw,
/dev/media@{int} rw,
/dev/video@{int} rw,
include if exists <local/cheese> include if exists <local/cheese>
} }

View file

@ -20,6 +20,7 @@ profile fwupd @{exec_path} flags=(attach_disconnected,complain) {
include <abstractions/mime> include <abstractions/mime>
include <abstractions/nameservice-strict> include <abstractions/nameservice-strict>
include <abstractions/sqlite> include <abstractions/sqlite>
include <abstractions/tpm>
capability dac_override, capability dac_override,
capability dac_read_search, capability dac_read_search,
@ -133,8 +134,6 @@ profile fwupd @{exec_path} flags=(attach_disconnected,complain) {
/dev/mei@{int} rw, /dev/mei@{int} rw,
/dev/mem r, /dev/mem r,
/dev/mtd@{int} rw, /dev/mtd@{int} rw,
/dev/tpm@{int} rw,
/dev/tpmrm@{int} rw,
/dev/wmi/* r, /dev/wmi/* r,
profile gpg flags=(attach_disconnected,complain) { profile gpg flags=(attach_disconnected,complain) {

View file

@ -65,6 +65,7 @@ profile git @{exec_path} flags=(attach_disconnected) {
@{pager_path} rPx -> child-pager, @{pager_path} rPx -> child-pager,
@{bin}/gh rPUx,
@{bin}/man rPx, @{bin}/man rPx,
@{bin}/meld rPUx, @{bin}/meld rPUx,
@{lib}/code/extensions/git/dist/askpass.sh rPx, @{lib}/code/extensions/git/dist/askpass.sh rPx,

View file

@ -0,0 +1,26 @@
# apparmor.d - Full set of apparmor profiles
# Copyright (C) 2025 Zane Zakraisek <zakraise@eng.utah.edu>
# SPDX-License-Identifier: GPL-2.0-only
abi <abi/4.0>,
include <tunables/global>
@{exec_path} = @{bin}/kdestroy
profile kdestroy @{exec_path} {
include <abstractions/base>
include <abstractions/kerberosclient>
#Allow root to destroy other users' creds cache
capability dac_override,
@{exec_path} mr,
#Credentials cache
/tmp/krb5cc_* rwk,
/tmp/tkt* rwk,
include if exists <local/kdestroy>
}
# vim:syntax=apparmor

View file

@ -0,0 +1,33 @@
# apparmor.d - Full set of apparmor profiles
# Copyright (C) 2025 Zane Zakraisek <zakraise@eng.utah.edu>
# SPDX-License-Identifier: GPL-2.0-only
abi <abi/4.0>,
include <tunables/global>
@{exec_path} = @{bin}/kinit
profile kinit @{exec_path} {
include <abstractions/base>
include <abstractions/nameservice-strict>
include <abstractions/kerberosclient>
network inet dgram,
network inet6 dgram,
network inet stream,
network inet6 stream,
network netlink raw,
@{exec_path} mr,
#User keytab file
/var/lib/krb5/user/@{uid}/client.keytab r,
#Credentials cache
/tmp/krb5cc_* rwk,
/tmp/tkt* rwk,
include if exists <local/kinit>
}
# vim:syntax=apparmor

View file

@ -0,0 +1,30 @@
# apparmor.d - Full set of apparmor profiles
# Copyright (C) 2025 Zane Zakraisek <zakraise@eng.utah.edu>
# SPDX-License-Identifier: GPL-2.0-only
abi <abi/4.0>,
include <tunables/global>
@{exec_path} = @{bin}/klist
profile klist @{exec_path} {
include <abstractions/base>
include <abstractions/kerberosclient>
#Allow root to list other users' creds cache
capability dac_override,
capability dac_read_search,
@{exec_path} mr,
#User keytab file
/var/lib/krb5/user/@{uid}/client.keytab rk,
#Credentials cache
/tmp/krb5cc_* rk,
/tmp/tkt* rk,
include if exists <local/klist>
}
# vim:syntax=apparmor

View file

@ -78,21 +78,24 @@ profile libreoffice @{exec_path} {
/usr/share/mythes/{,**} r, /usr/share/mythes/{,**} r,
/usr/share/thumbnailers/{,**} r, /usr/share/thumbnailers/{,**} r,
/etc/cups/ppd/*.ppd r,
/etc/java{,-}{,@{version}}-openjdk/{,**} r, /etc/java{,-}{,@{version}}-openjdk/{,**} r,
/etc/libreoffice/{,**} r, /etc/libreoffice/{,**} r,
/etc/paperspecs r,
/etc/papersize r, /etc/papersize r,
/etc/paperspecs r,
/etc/xdg/* r, /etc/xdg/* r,
/var/tmp/ r, /var/tmp/ r,
owner /var/spool/libreoffice/uno_packages/cache/stamp.sys w, owner /var/spool/libreoffice/uno_packages/cache/stamp.sys w,
owner @{user_cache_dirs}/libreoffice/{,**} rw, owner @{user_cache_dirs}/libreoffice/{,**} rw,
owner @{user_config_dirs}/kservicemenurc r,
owner @{user_config_dirs}/libreoffice/ rw, owner @{user_config_dirs}/libreoffice/ rw,
owner @{user_config_dirs}/libreoffice/** rwk, owner @{user_config_dirs}/libreoffice/** rwk,
owner @{user_config_dirs}/soffice.*.lock rwk,
owner @{user_config_dirs}/plasma_workspace.notifyrc r, owner @{user_config_dirs}/plasma_workspace.notifyrc r,
owner @{user_config_dirs}/kservicemenurc r, owner @{user_config_dirs}/soffice.*.lock rwk,
owner @{user_config_dirs}/soffice.binrc r,
owner @{user_share_dirs}/#@{int} rw, owner @{user_share_dirs}/#@{int} rw,
owner @{user_share_dirs}/user-places.xbel r, owner @{user_share_dirs}/user-places.xbel r,

View file

@ -9,6 +9,7 @@ include <tunables/global>
@{exec_path} = @{bin}/sbctl @{exec_path} = @{bin}/sbctl
profile sbctl @{exec_path} { profile sbctl @{exec_path} {
include <abstractions/base> include <abstractions/base>
include <abstractions/tpm>
capability dac_read_search, capability dac_read_search,
capability linux_immutable, capability linux_immutable,
@ -34,9 +35,6 @@ profile sbctl @{exec_path} {
@{sys}/firmware/efi/efivars/SecureBoot-@{uuid} r, @{sys}/firmware/efi/efivars/SecureBoot-@{uuid} r,
@{sys}/firmware/efi/efivars/SetupMode-@{uuid} r, @{sys}/firmware/efi/efivars/SetupMode-@{uuid} r,
/dev/pts/@{int} rw,
/dev/tpmrm@{int} rw,
# File Inherit # File Inherit
deny network inet stream, deny network inet stream,
deny network inet6 stream, deny network inet6 stream,

View file

@ -19,6 +19,7 @@ profile signal-desktop @{exec_path} flags=(attach_disconnected) {
include <abstractions/audio-client> include <abstractions/audio-client>
include <abstractions/bus-session> include <abstractions/bus-session>
include <abstractions/bus/org.kde.StatusNotifierWatcher> include <abstractions/bus/org.kde.StatusNotifierWatcher>
include <abstractions/camera>
include <abstractions/common/electron> include <abstractions/common/electron>
include <abstractions/devices-usb-read> include <abstractions/devices-usb-read>
include <abstractions/notifications> include <abstractions/notifications>

View file

@ -9,14 +9,12 @@ include <tunables/global>
@{exec_path} = @{bin}/v4l2-ctl @{exec_path} = @{bin}/v4l2-ctl
profile v4l2-ctl @{exec_path} { profile v4l2-ctl @{exec_path} {
include <abstractions/base> include <abstractions/base>
include <abstractions/camera>
include <abstractions/consoles> include <abstractions/consoles>
include <abstractions/devices-usb> include <abstractions/media-control>
@{exec_path} mr, @{exec_path} mr,
/dev/media@{int} rw,
/dev/video@{int} rw,
include if exists <local/v4l2-ctl> include if exists <local/v4l2-ctl>
} }

View file

@ -16,12 +16,14 @@ profile virt-manager @{exec_path} flags=(attach_disconnected) {
include <abstractions/bus-session> include <abstractions/bus-session>
include <abstractions/bus-system> include <abstractions/bus-system>
include <abstractions/bus/org.a11y> include <abstractions/bus/org.a11y>
include <abstractions/camera>
include <abstractions/dconf-write> include <abstractions/dconf-write>
include <abstractions/desktop> include <abstractions/desktop>
include <abstractions/devices-usb> include <abstractions/devices-usb>
include <abstractions/fontconfig-cache-read> include <abstractions/fontconfig-cache-read>
include <abstractions/graphics> include <abstractions/graphics>
include <abstractions/gstreamer> include <abstractions/gstreamer>
include <abstractions/media-control>
include <abstractions/nameservice-strict> include <abstractions/nameservice-strict>
include <abstractions/python> include <abstractions/python>
include <abstractions/ssl_certs> include <abstractions/ssl_certs>
@ -101,9 +103,6 @@ profile virt-manager @{exec_path} flags=(attach_disconnected) {
owner @{PROC}/@{pid}/mounts r, owner @{PROC}/@{pid}/mounts r,
owner @{PROC}/@{pid}/stat r, owner @{PROC}/@{pid}/stat r,
/dev/media@{int} r,
/dev/video@{int} rw,
# Silence the noise # Silence the noise
deny /usr/share/virt-manager/{,**} w, deny /usr/share/virt-manager/{,**} w,
deny owner @{user_share_dirs}/gvfs-metadata/{,*} r, deny owner @{user_share_dirs}/gvfs-metadata/{,*} r,

View file

@ -17,6 +17,7 @@ profile vlc @{exec_path} {
include <abstractions/bus/org.freedesktop.secrets> include <abstractions/bus/org.freedesktop.secrets>
include <abstractions/bus/org.kde.kwalletd> include <abstractions/bus/org.kde.kwalletd>
include <abstractions/bus/org.kde.StatusNotifierWatcher> include <abstractions/bus/org.kde.StatusNotifierWatcher>
include <abstractions/camera>
include <abstractions/dconf-write> include <abstractions/dconf-write>
include <abstractions/desktop> include <abstractions/desktop>
include <abstractions/devices-usb> include <abstractions/devices-usb>
@ -85,7 +86,6 @@ profile vlc @{exec_path} {
/dev/shm/#@{int} rw, /dev/shm/#@{int} rw,
/dev/snd/ r, /dev/snd/ r,
/dev/tty r, /dev/tty r,
/dev/video@{int} rw,
owner /dev/tty@{int} rw, owner /dev/tty@{int} rw,
# Silencer # Silencer

View file

@ -49,6 +49,9 @@ func init() {
case "noble": case "noble":
prebuild.ABI = 4 prebuild.ABI = 4
prebuild.Version = 4.0 prebuild.Version = 4.0
case "questing":
prebuild.ABI = 4
prebuild.Version = 5.0
} }
case "debian": case "debian":

View file

@ -1,56 +0,0 @@
// apparmor.d - Full set of apparmor profiles
// Copyright (C) 2023-2024 Alexandre Pujol <alexandre@pujol.io>
// SPDX-License-Identifier: GPL-2.0-only
package main
import (
"os"
"os/exec"
"testing"
"github.com/roddhjav/apparmor.d/pkg/prebuild"
)
func chdirGitRoot() {
cmd := exec.Command("git", "rev-parse", "--show-toplevel")
out, err := cmd.Output()
if err != nil {
panic(err)
}
root := string(out[0 : len(out)-1])
if err := os.Chdir(root); err != nil {
panic(err)
}
}
func Test_main(t *testing.T) {
tests := []struct {
name string
dist string
}{
{
name: "Build for Archlinux",
dist: "arch",
},
{
name: "Build for Ubuntu",
dist: "ubuntu",
},
{
name: "Build for Debian",
dist: "debian",
},
{
name: "Build for OpenSUSE Tumbleweed",
dist: "opensuse",
},
}
chdirGitRoot()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
prebuild.Distribution = tt.dist
main()
})
}
}

View file

@ -8,6 +8,6 @@ set -e
#DEBHELPER# #DEBHELPER#
apparmor_parser --purge-cache || true apparmor_parser --purge-cache || true
deb-systemd-invoke reload apparmor.service deb-systemd-invoke reload apparmor.service || true
exit 0 exit 0

View file

@ -8,6 +8,6 @@ set -e
#DEBHELPER# #DEBHELPER#
apparmor_parser --purge-cache || true apparmor_parser --purge-cache || true
deb-systemd-invoke reload apparmor.service deb-systemd-invoke reload apparmor.service || true
exit 0 exit 0

View file

@ -16,7 +16,7 @@ readonly VERSION
main() { main() {
case "$COMMAND" in case "$COMMAND" in
pkg) pkg)
PKGDEST="$OUTPUT" makepkg --syncdeps --force --cleanbuild --noconfirm --noprogressbar PKGDEST="$OUTPUT" BUILDDIR=/tmp/makepkg makepkg --syncdeps --force --cleanbuild --noconfirm --noprogressbar
;; ;;
dpkg) dpkg)

View file

@ -25,7 +25,7 @@ readonly VERSION PACKAGER
_start() { _start() {
local img="$1" local img="$1"
docker start "$img" docker start "$img" || return 1
} }
_is_running() { _is_running() {
@ -65,7 +65,7 @@ build_in_docker_makepkg() {
--env PKGDEST="$BUILDIR" --env PACKAGER="$PACKAGER" \ --env PKGDEST="$BUILDIR" --env PACKAGER="$PACKAGER" \
--env BUILDDIR=/tmp/build \ --env BUILDDIR=/tmp/build \
"$BASEIMAGE/$dist" "$BASEIMAGE/$dist"
docker exec "$img" sudo pacman -Syu --noconfirm --noprogressbar docker exec "$img" sudo pacman -Sy --noconfirm --noprogressbar
fi fi
docker exec --workdir="$BUILDIR/$PKGNAME" "$img" bash dists/build.sh pkg docker exec --workdir="$BUILDIR/$PKGNAME" "$img" bash dists/build.sh pkg

View file

@ -185,6 +185,7 @@ kconf_update complain
kde-powerdevil attach_disconnected,mediate_deleted,complain kde-powerdevil attach_disconnected,mediate_deleted,complain
kde-systemd-start-condition complain kde-systemd-start-condition complain
kded complain kded complain
kdestroy complain
kdump_mem_estimator complain kdump_mem_estimator complain
kdump-config attach_disconnected,complain kdump-config attach_disconnected,complain
kdump-tools-init complain,attach_disconnected kdump-tools-init complain,attach_disconnected
@ -193,9 +194,11 @@ kernel-install complain
kernel-postinst-kdump complain kernel-postinst-kdump complain
keyboxd complain keyboxd complain
kglobalacceld complain kglobalacceld complain
kinit complain
kio_http_cache_cleaner complain kio_http_cache_cleaner complain
kiod complain kiod complain
kioworker complain kioworker complain
klist complain
konsole attach_disconnected,mediate_deleted,complain konsole attach_disconnected,mediate_deleted,complain
kscreen_backend_launcher complain kscreen_backend_launcher complain
kscreen_osd_service complain kscreen_osd_service complain
@ -230,7 +233,7 @@ lvmdump complain
lvmpolld complain lvmpolld complain
man complain man complain
mate-notification-daemon complain mate-notification-daemon complain
mdadm complain mdadm attach_disconnected,complain
mdadm-mkconf complain mdadm-mkconf complain
ModemManager attach_disconnected,complain ModemManager attach_disconnected,complain
mount attach_disconnected,complain mount attach_disconnected,complain
@ -327,7 +330,7 @@ systemd-generator-ds-identify attach_disconnected,complain
systemd-generator-environment-arch complain systemd-generator-environment-arch complain
systemd-generator-environment-flatpak complain systemd-generator-environment-flatpak complain
systemd-generator-environment-snapd attach_disconnected,complain systemd-generator-environment-snapd attach_disconnected,complain
systemd-generator-friendly-recover attach_disconnected,complain systemd-generator-friendly-recovery attach_disconnected,complain
systemd-generator-fstab attach_disconnected,complain systemd-generator-fstab attach_disconnected,complain
systemd-generator-getty attach_disconnected,complain systemd-generator-getty attach_disconnected,complain
systemd-generator-gpt-auto attach_disconnected,complain systemd-generator-gpt-auto attach_disconnected,complain

View file

@ -8,6 +8,7 @@ apt-helper complain
check-new-release-gtk complain check-new-release-gtk complain
do-release-upgrade complain do-release-upgrade complain
dpkg-genbuildinfo complain dpkg-genbuildinfo complain
esm_cache complain
fanctl attach_disconnected,complain fanctl attach_disconnected,complain
hwe-support-status complain hwe-support-status complain
list-oem-metapackages complain list-oem-metapackages complain

View file

@ -217,6 +217,14 @@ Minimal set of rules for sandboxed programs using `bwrap`. A profile using this
A minimal set of rules for chromium based application. Handle access for internal sandbox. A minimal set of rules for chromium based application. Handle access for internal sandbox.
It works as a *function* and requires some variables to be provided as *arguments* and set in the header of the calling profile:
!!! note ""
[apparmor.d/profile-s-z/spotify](https://github.com/roddhjav/apparmor.d/blob/main/apparmor.d/groups/steam/steam#L24-L25)
``` sh linenums="24"
@{domain} = org.chromium.Chromium
```
### **`common/electron`** ### **`common/electron`**
@ -227,6 +235,7 @@ A minimal set of rules for all electron based UI applications. It works as a *fu
[apparmor.d/profile-s-z/spotify](https://github.com/roddhjav/apparmor.d/blob/7d1380530aa56f31589ccc6a360a8144f3601731/apparmor.d/profiles-s-z/spotify#L10-L13) [apparmor.d/profile-s-z/spotify](https://github.com/roddhjav/apparmor.d/blob/7d1380530aa56f31589ccc6a360a8144f3601731/apparmor.d/profiles-s-z/spotify#L10-L13)
``` sh linenums="10" ``` sh linenums="10"
@{name} = spotify @{name} = spotify
@{domain} = org.chromium.Chromium
@{lib_dirs} = /opt/@{name} @{lib_dirs} = /opt/@{name}
@{config_dirs} = @{user_config_dirs}/@{name} @{config_dirs} = @{user_config_dirs}/@{name}
@{cache_dirs} = @{user_cache_dirs}/@{name} @{cache_dirs} = @{user_cache_dirs}/@{name}

View file

@ -10,18 +10,22 @@ go run ./cmd/prebuild -h
``` ```
``` ```
aa-prebuild [-h] [--complain | --enforce] [--full] [--abi 3|4] aa-prebuild [-h] [--complain | --enforce] [--full] [--server] [--abi 3|4] [--version V] [--file FILE]
Prebuild apparmor.d profiles for a given distribution and apply Prebuild apparmor.d profiles for a given distribution and apply
internal built-in directives. internal built-in directives.
Options: Options:
-h, --help Show this help message and exit. -h, --help Show this help message and exit.
-c, --complain Set complain flag on all profiles. -c, --complain Set complain flag on all profiles.
-e, --enforce Set enforce flag on all profiles. -e, --enforce Set enforce flag on all profiles.
-a, --abi ABI Target apparmor ABI. -a, --abi ABI Target apparmor ABI.
-f, --full Set AppArmor for full system policy. -v, --version V Target apparmor version.
-F, --file Only prebuild a given file. -f, --full Set AppArmor for full system policy.
-s, --server Set AppArmor for server.
-b, --buildir DIR Root build directory.
-F, --file Only prebuild a given file.
--debug Enable debug mode.
Prepare tasks: Prepare tasks:
configure - Set distribution specificities configure - Set distribution specificities
@ -31,21 +35,27 @@ Prepare tasks:
overwrite - Overwrite dummy upstream profiles overwrite - Overwrite dummy upstream profiles
synchronise - Initialize a new clean apparmor.d build directory synchronise - Initialize a new clean apparmor.d build directory
ignore - Ignore profiles and files from: ignore - Ignore profiles and files from:
server - Configure AppArmor for server
systemd-default - Configure systemd unit drop in files to a profile for some units systemd-default - Configure systemd unit drop in files to a profile for some units
systemd-early - Configure systemd unit drop in files to ensure some service start after apparmor systemd-early - Configure systemd unit drop in files to ensure some service start after apparmor
attach - Configure tunable for re-attached path
Build tasks: Build tasks:
abi3 - Convert all profiles from abi 4.0 to abi 3.0 userspace - Fix: resolve variable in profile attachments
attach - Re-attach disconnected path abi3 - Build: convert all profiles from abi 4.0 to abi 3.0
complain - Set complain flag on all profiles attach - Feat: re-attach disconnected path
enforce - All profiles have been enforced base-strict - Feat: use 'base-strict' as base abstraction
fsp - Prevent unconfined transitions in profile rules complain - Build: set complain flag on all profiles
hotfix - Temporary fix for #74, #80 & #235 debug - Build: debug mode enabled
userspace - Resolve variable in profile attachments enforce - Build: all profiles have been enforced
fsp - Feat: prevent unconfined transitions in profile rules
hotfix - Fix: temporary solution for #74, #80 & #235
stacked-dbus - Fix: resolve peer label variable in dbus rules
Directive: Directive:
#aa:dbus own bus=<bus> name=<name> [interface=AARE] [path=AARE] #aa:dbus own bus=<bus> name=<name> [interface=AARE] [path=AARE]
#aa:dbus talk bus=<bus> name=<name> label=<profile> [interface=AARE] [path=AARE] #aa:dbus talk bus=<bus> name=<name> label=<profile> [interface=AARE] [path=AARE]
#aa:dbus common bus=<bus> name=<name> label=<profile>
#aa:exec [P|U|p|u|PU|pu|] profiles... #aa:exec [P|U|p|u|PU|pu|] profiles...
#aa:only filters... #aa:only filters...
#aa:exclude filters... #aa:exclude filters...
@ -66,6 +76,12 @@ Ignore profiles and files as defined in the `dist/ignore` directory. See [workfl
*Enabled by default. Can be disabled in `cmd/prebuild/main.go`* *Enabled by default. Can be disabled in `cmd/prebuild/main.go`*
### **`server`**
Configure AppArmor for server. Desktop related groups and profiles that use desktop abstraction are not included. [hotfix](#hotfix) is also disabled, as it is only needed on desktop system. It is mostly intended to be used on server with FSP enabled. E.g: [the play machine](https://github.com/roddhjav/play).
*Enable with the `--server` option in the prebuild command.*
### **`merge`** ### **`merge`**
Merge profiles from `apparmor.d/group/`, `apparmor.d/profiles-*-*/` to a unified directory in `.build/apparmor.d` that AppArmor can parse. Merge profiles from `apparmor.d/group/`, `apparmor.d/profiles-*-*/` to a unified directory in `.build/apparmor.d` that AppArmor can parse.

View file

@ -6,11 +6,18 @@ title: Roadmap
This is the current list of features that must be implemented to get to a stable release This is the current list of features that must be implemented to get to a stable release
- [x] **Play machine** - [x] **[Play machine](https://github.com/roddhjav/play)**
- [ ] **[Sub packages](https://github.com/roddhjav/apparmor.d/issues/464)** - [ ] **[Sub packages](https://github.com/roddhjav/apparmor.d/issues/464)**
- [x] Move most profiles into groups such that - [x] Move most profiles into groups
- [ ] New simplified build system to generate the packages with profile dependencies check - [ ] Provide complain/enforced packages version
- [ ] normal/FSP/server packages variants
- [ ] **Build system**
- [ ] Continuous release on the main branch, ~2 releases per week
- [ ] Provide packages repo for ubuntu/debian
- [x] Add a `just` target to install the profiles in the right place
- [x] Fully drop the Makefile in favor of `just`
- [ ] **Tests** - [ ] **Tests**
- [x] Tests VM for all supported targets (see [tests/vm](vm.md)) - [x] Tests VM for all supported targets (see [tests/vm](vm.md))
@ -22,14 +29,26 @@ This is the current list of features that must be implemented to get to a stable
- [ ] **General improvements** - [ ] **General improvements**
- [ ] Provide a proper fix for [#74](https://github.com/roddhjav/apparmor.d/issues/74), [#80](https://github.com/roddhjav/apparmor.d/issues/80) & [#235](https://github.com/roddhjav/apparmor.d/issues/235) - [ ] Provide a proper fix for [#74](https://github.com/roddhjav/apparmor.d/issues/74), [#80](https://github.com/roddhjav/apparmor.d/issues/80) & [#235](https://github.com/roddhjav/apparmor.d/issues/235)
- [x] The apt/dpkg profiles needs to be reworked
- [ ] Build system - [ ] **Abstractions**
- [ ] Continuous release on the main branch, ~2 releases per week - [ ] Document all abstractions
- [ ] Provide packages repo for ubuntu/debian - [ ] Split and reorganize some big abs into set of smaller abstractions.
- [ ] Provide complain/enforced packages version Strictly follow the new abstractions guidelines (layer 0, layer 1, etc.)
- [x] Add a `just` target to install the profiles in the right place - [ ] Abstraction based profiles:
- [x] Fully drop the Makefile in favor of `just` Most of the accesses needed by GUI based application are commons. As such 80-90% of the profile content should be handled by abstractions (internally they will have conditions).
- [ ] Test new interface like abstractions
- notifications
- audio-bluetooth
- secrets-service
- media-keys
- ...
- [ ] Rewrite the desktop abstraction to only contains other abs. No direct rules in it.
- [ ] Rewrite the DE specific abstraction to be a layer 1 abs
- [ ] **Security improvements**
- [ ] Limit the use of `abstractions/common/systemd`
- [ ] Ensure systemctl restart/stop/reload is always confined and filtered by unit (dbus only)
- [ ] Revisit the usae of `systemd-tty-ask-password-agent`
## Next features ## Next features
@ -45,8 +64,16 @@ This is the current list of features that must be implemented to get to a stable
- [ ] Debug tool to show the profiles transition tree, and ensure no profile is missing - [ ] Debug tool to show the profiles transition tree, and ensure no profile is missing
- [x] Remove the `default` profile - [x] Remove the `default` profile
- [ ] **Define roles**
- [ ] Unrestricted shell role without FSP enabled
- [ ] Define the roles when FSP is enabled
## Done ## Done
**General improvements**
- [x] The apt/dpkg profiles has been rewritten
**Abstractions** **Abstractions**
- [x] New `audio-client` and `audio-server` abstractions - [x] New `audio-client` and `audio-server` abstractions

View file

@ -6,6 +6,19 @@ title: Known issues
Known bugs are tracked on the meta issue **[#75](https://github.com/roddhjav/apparmor.d/issues/74)**. Known bugs are tracked on the meta issue **[#75](https://github.com/roddhjav/apparmor.d/issues/74)**.
## Ubuntu
### Dbus
Ubuntu fully supports dbus mediation with apparmor. If it is a value added by Ubuntu from other distributions, it can also lead to some breakage if you enforce some profiles. *Do not enforce the rules on Ubuntu Desktop.*
Note: Ubuntu server has been more tested and will work without issues with enforced rules.
### Snap
Apparmor.d needs to be fully integrated with snap, otherwise your snap applications may not work properly. As of today, it is a work in progress.
## Complain mode ## Complain mode
A profile in *complain* mode cannot break the program it confines. However, there are some **major exceptions**: A profile in *complain* mode cannot break the program it confines. However, there are some **major exceptions**:
@ -14,20 +27,3 @@ A profile in *complain* mode cannot break the program it confines. However, ther
2. `attach_disconnected` (and `mediate_deleted`) will break the program if they are required and missing in the profile, 2. `attach_disconnected` (and `mediate_deleted`) will break the program if they are required and missing in the profile,
3. If AppArmor does not find the profile to transition `rPx`. 3. If AppArmor does not find the profile to transition `rPx`.
## Pacman "could not get current working directory"
```sh
$ sudo pacman -Syu
...
error: could not get current working directory
:: Processing package changes...
...
```
This is **a feature, not a bug!** It can safely be ignored. Pacman tries to get your current directory. You will only get this error when you run pacman in your home directory.
According to the Arch Linux guideline, on Arch Linux, packages cannot install files under `/home/`. Therefore, the [`pacman`][pacman] profile purposely does not allow access of your home directory.
This provides a basic protection against some packages (on the AUR) that may have rogue install script.
[pacman]: https://github.com/roddhjav/apparmor.d/blob/main/apparmor.d/groups/pacman/pacman

View file

@ -31,6 +31,9 @@ func init() {
func (b ReAttach) Apply(opt *Option, profile string) (string, error) { func (b ReAttach) Apply(opt *Option, profile string) (string, error) {
var insert string var insert string
var origin = "profile " + opt.Name var origin = "profile " + opt.Name
if opt.File.HasSuffix("attached/base") {
return profile, nil // Do not re-attach twice
}
if strings.Contains(profile, "attach_disconnected") { if strings.Contains(profile, "attach_disconnected") {
insert = "@{att} = /att/" + opt.Name + "/\n" insert = "@{att} = /att/" + opt.Name + "/\n"
@ -42,13 +45,17 @@ func (b ReAttach) Apply(opt *Option, profile string) (string, error) {
"include <abstractions/base>", "include <abstractions/base>",
"include <abstractions/attached/base>", "include <abstractions/attached/base>",
) )
profile = strings.ReplaceAll(profile,
"include <abstractions/base-strict>",
"include <abstractions/attached/base>",
)
profile = strings.ReplaceAll(profile, profile = strings.ReplaceAll(profile,
"include <abstractions/consoles>", "include <abstractions/consoles>",
"include <abstractions/attached/consoles>", "include <abstractions/attached/consoles>",
) )
} else { } else {
insert = "@{att} = /\n" insert = "@{att} = \"\"\n"
} }

View file

@ -231,10 +231,80 @@ func TestBuilder_Apply(t *testing.T) {
want: "", want: "",
wantErr: true, wantErr: true,
}, },
{
name: "stacked-dbus-1",
b: Builders["stacked-dbus"],
profile: `
profile foo {
dbus send bus=session path=/org/freedesktop/DBus
interface=org.freedesktop.DBus
member={Hello,AddMatch,RemoveMatch,GetNameOwner,NameHasOwner,StartServiceByName}
peer=(name=org.freedesktop.DBus, label="@{p_dbus_session}"),
}`,
want: `
profile foo {
dbus send bus=session path=/org/freedesktop/DBus
interface=org.freedesktop.DBus
member={Hello,AddMatch,RemoveMatch,GetNameOwner,NameHasOwner,StartServiceByName}
peer=(name=org.freedesktop.DBus, label=dbus-session),
dbus send bus=session path=/org/freedesktop/DBus
interface=org.freedesktop.DBus
member={Hello,AddMatch,RemoveMatch,GetNameOwner,NameHasOwner,StartServiceByName}
peer=(name=org.freedesktop.DBus, label=dbus-session//&unconfined),
}`,
},
{
name: "base-strict-1",
b: Builders["base-strict"],
profile: `
profile foo {
include <abstractions/base>
}`,
want: `
profile foo {
include <abstractions/base-strict>
}`,
},
{
name: "attach-1",
b: Builders["attach"],
profile: `
profile attach-1 flags=(attach_disconnected) {
include <abstractions/base>
include <abstractions/base-strict>
include <abstractions/consoles>
}`,
want: `
@{att} = /att/attach-1/
profile attach-1 flags=(attach_disconnected,attach_disconnected.path=@{att}) {
include <abstractions/attached/base>
include <abstractions/attached/base>
include <abstractions/attached/consoles>
}`,
},
{
name: "attach-2",
b: Builders["attach"],
profile: `
profile attach-2 flags=(complain) {
include <abstractions/base>
include <abstractions/base-strict>
include <abstractions/consoles>
}`,
want: `
@{att} = ""
profile attach-2 flags=(complain) {
include <abstractions/base>
include <abstractions/base-strict>
include <abstractions/consoles>
}`,
},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
opt := &Option{File: prebuild.RootApparmord.Join(tt.name)} opt := &Option{File: prebuild.RootApparmord.Join(tt.name), Name: tt.name}
got, err := tt.b.Apply(opt, tt.profile) got, err := tt.b.Apply(opt, tt.profile)
if (err != nil) != tt.wantErr { if (err != nil) != tt.wantErr {
t.Errorf("Builder.Apply() error = %v, wantErr %v", err, tt.wantErr) t.Errorf("Builder.Apply() error = %v, wantErr %v", err, tt.wantErr)

View file

@ -72,7 +72,7 @@ func (b StackedDbus) Apply(opt *Option, profile string) (string, error) {
toResolve = append(toResolve, k) toResolve = append(toResolve, k)
} }
rulesByParagraph, paragraphs, err := parse(kind, profile) // rulesByParagraph, paragraphs, err := parse(kind, profile)
if err != nil { if err != nil {
return "", err return "", err
} }

View file

@ -7,6 +7,8 @@ package cli
import ( import (
"flag" "flag"
"fmt" "fmt"
"os"
"slices"
"strings" "strings"
"github.com/roddhjav/apparmor.d/pkg/logging" "github.com/roddhjav/apparmor.d/pkg/logging"
@ -20,7 +22,7 @@ import (
const ( const (
nilABI = 0 nilABI = 0
nilVer = 0.0 nilVer = 0.0
usage = `aa-prebuild [-h] [--complain | --enforce] [--full] [--abi 3|4] [--version V] [--file FILE] usage = `aa-prebuild [-h] [--complain | --enforce] [--full] [--server] [--abi 3|4] [--version V] [--file FILE]
Prebuild apparmor.d profiles for a given distribution and apply Prebuild apparmor.d profiles for a given distribution and apply
internal built-in directives. internal built-in directives.
@ -32,7 +34,8 @@ Options:
-a, --abi ABI Target apparmor ABI. -a, --abi ABI Target apparmor ABI.
-v, --version V Target apparmor version. -v, --version V Target apparmor version.
-f, --full Set AppArmor for full system policy. -f, --full Set AppArmor for full system policy.
-b, --buildir DIR Root build directory. -s, --server Set AppArmor for server.
-b, --buildir DIR Root build directory.
-F, --file Only prebuild a given file. -F, --file Only prebuild a given file.
--debug Enable debug mode. --debug Enable debug mode.
` `
@ -43,6 +46,7 @@ var (
complain bool complain bool
enforce bool enforce bool
full bool full bool
server bool
debug bool debug bool
abi int abi int
version float64 version float64
@ -55,6 +59,8 @@ func init() {
flag.BoolVar(&help, "help", false, "Show this help message and exit.") flag.BoolVar(&help, "help", false, "Show this help message and exit.")
flag.BoolVar(&full, "f", false, "Set AppArmor for full system policy.") flag.BoolVar(&full, "f", false, "Set AppArmor for full system policy.")
flag.BoolVar(&full, "full", false, "Set AppArmor for full system policy.") flag.BoolVar(&full, "full", false, "Set AppArmor for full system policy.")
flag.BoolVar(&server, "s", false, "Set AppArmor for server.")
flag.BoolVar(&server, "server", false, "Set AppArmor for server.")
flag.BoolVar(&complain, "c", false, "Set complain flag on all profiles.") flag.BoolVar(&complain, "c", false, "Set complain flag on all profiles.")
flag.BoolVar(&complain, "complain", false, "Set complain flag on all profiles.") flag.BoolVar(&complain, "complain", false, "Set complain flag on all profiles.")
flag.BoolVar(&enforce, "e", false, "Set enforce flag on all profiles.") flag.BoolVar(&enforce, "e", false, "Set enforce flag on all profiles.")
@ -81,7 +87,22 @@ func Configure() {
flag.Parse() flag.Parse()
if help { if help {
flag.Usage() flag.Usage()
return os.Exit(0)
}
if server {
idx := slices.Index(prepare.Prepares, prepare.Tasks["merge"])
if idx == -1 {
prepare.Register("server")
} else {
prepare.Prepares = slices.Insert(prepare.Prepares, idx, prepare.Tasks["server"])
}
// Remove hotfix task as it is not needed on server
idx = slices.Index(prepare.Prepares, prepare.Tasks["hotfix"])
if idx != -1 {
prepare.Prepares = slices.Delete(prepare.Prepares, idx, idx+1)
}
} }
if full && paths.New("apparmor.d/groups/_full").Exist() { if full && paths.New("apparmor.d/groups/_full").Exist() {
@ -118,8 +139,11 @@ func Configure() {
builder.Register("stacked-dbus") builder.Register("stacked-dbus")
} else { } else {
if !prebuild.DownStream {
prepare.Register("attach")
}
builder.Register("attach") builder.Register("attach")
prepare.Register("attach")
} }
default: default:

View file

@ -135,7 +135,7 @@ func (d Dbus) own(rules map[string]string) aa.Rules {
} }
res = append(res, res = append(res,
// DBus.Properties // DBus.Properties: reply to properties request from anyone
&aa.Dbus{ &aa.Dbus{
Access: []string{"send", "receive"}, Bus: rules["bus"], Path: rules["path"], Access: []string{"send", "receive"}, Bus: rules["bus"], Path: rules["path"],
Interface: "org.freedesktop.DBus.Properties", Interface: "org.freedesktop.DBus.Properties",
@ -143,7 +143,7 @@ func (d Dbus) own(rules map[string]string) aa.Rules {
PeerName: `"{@{busname},org.freedesktop.DBus}"`, PeerName: `"{@{busname},org.freedesktop.DBus}"`,
}, },
// DBus.Introspectable // DBus.Introspectable: allow clients to introspect the service
&aa.Dbus{ &aa.Dbus{
Access: []string{"receive"}, Bus: rules["bus"], Path: rules["path"], Access: []string{"receive"}, Bus: rules["bus"], Path: rules["path"],
Interface: "org.freedesktop.DBus.Introspectable", Interface: "org.freedesktop.DBus.Introspectable",
@ -151,7 +151,7 @@ func (d Dbus) own(rules map[string]string) aa.Rules {
PeerName: `"@{busname}"`, PeerName: `"@{busname}"`,
}, },
// DBus.ObjectManager // DBus.ObjectManager: allow clients to enumerate sources
&aa.Dbus{ &aa.Dbus{
Access: []string{"receive"}, Bus: rules["bus"], Path: rules["path"], Access: []string{"receive"}, Bus: rules["bus"], Path: rules["path"],
Interface: "org.freedesktop.DBus.ObjectManager", Interface: "org.freedesktop.DBus.ObjectManager",
@ -170,7 +170,14 @@ func (d Dbus) own(rules map[string]string) aa.Rules {
func (d Dbus) talk(rules map[string]string) aa.Rules { func (d Dbus) talk(rules map[string]string) aa.Rules {
interfaces := getInterfaces(rules) interfaces := getInterfaces(rules)
res := aa.Rules{} res := aa.Rules{
&aa.Unix{
Type: "stream",
Address: "none",
PeerLabel: rules["label"],
PeerAddr: "none",
},
}
// Interfaces // Interfaces
for _, iface := range interfaces { for _, iface := range interfaces {
@ -198,7 +205,7 @@ func (d Dbus) talk(rules map[string]string) aa.Rules {
PeerName: `"{@{busname},` + rules["name"] + `}"`, PeerLabel: rules["label"], PeerName: `"{@{busname},` + rules["name"] + `}"`, PeerLabel: rules["label"],
}, },
// DBus.ObjectManager // DBus.ObjectManager: allow clients to enumerate sources
&aa.Dbus{ &aa.Dbus{
Access: []string{"send"}, Bus: rules["bus"], Path: rules["path"], Access: []string{"send"}, Bus: rules["bus"], Path: rules["path"],
Interface: "org.freedesktop.DBus.ObjectManager", Interface: "org.freedesktop.DBus.ObjectManager",

View file

@ -8,7 +8,7 @@ import (
"testing" "testing"
) )
const dbusOwnSystemd1 = ` include <abstractions/bus/own-system> const dbusOwnSystemd1 = ` include <abstractions/bus/system/own>
dbus bind bus=system name=org.freedesktop.systemd1{,.*}, dbus bind bus=system name=org.freedesktop.systemd1{,.*},
dbus receive bus=system path=/org/freedesktop/systemd1{,/**} dbus receive bus=system path=/org/freedesktop/systemd1{,/**}
@ -73,7 +73,7 @@ func TestDbus_Apply(t *testing.T) {
Raw: " #aa:dbus own bus=session name=com.rastersoft.ding interface+=org.gtk.Actions", Raw: " #aa:dbus own bus=session name=com.rastersoft.ding interface+=org.gtk.Actions",
}, },
profile: " #aa:dbus own bus=session name=com.rastersoft.ding interface+=org.gtk.Actions", profile: " #aa:dbus own bus=session name=com.rastersoft.ding interface+=org.gtk.Actions",
want: ` include <abstractions/bus/own-session> want: ` include <abstractions/bus/session/own>
dbus bind bus=session name=com.rastersoft.ding{,.*}, dbus bind bus=session name=com.rastersoft.ding{,.*},
dbus receive bus=session path=/com/rastersoft/ding{,/**} dbus receive bus=session path=/com/rastersoft/ding{,/**}
@ -120,7 +120,9 @@ func TestDbus_Apply(t *testing.T) {
Raw: " #aa:dbus talk bus=system name=org.freedesktop.Accounts label=accounts-daemon", Raw: " #aa:dbus talk bus=system name=org.freedesktop.Accounts label=accounts-daemon",
}, },
profile: " #aa:dbus talk bus=system name=org.freedesktop.Accounts label=accounts-daemon", profile: " #aa:dbus talk bus=system name=org.freedesktop.Accounts label=accounts-daemon",
want: ` dbus (send receive) bus=system path=/org/freedesktop/Accounts{,/**} want: ` unix type=stream addr=none peer=(label=accounts-daemon, addr=none),
dbus (send receive) bus=system path=/org/freedesktop/Accounts{,/**}
interface=org.freedesktop.Accounts{,.*} interface=org.freedesktop.Accounts{,.*}
peer=(name="{@{busname},org.freedesktop.Accounts{,.*}}", label=accounts-daemon), peer=(name="{@{busname},org.freedesktop.Accounts{,.*}}", label=accounts-daemon),
dbus (send receive) bus=system path=/org/freedesktop/Accounts{,/**} dbus (send receive) bus=system path=/org/freedesktop/Accounts{,/**}

View file

@ -13,6 +13,9 @@ var (
// AppArmor version // AppArmor version
Version = 4.0 Version = 4.0
// Tells the build we are a downstream project using apparmor.d as dependency
DownStream = false
// Either or not RBAC is enabled // Either or not RBAC is enabled
RBAC = false RBAC = false

View file

@ -11,9 +11,12 @@ import (
) )
// Hide is the default content of debian/apparmor.d.hide. Whonix has special addition. // Hide is the default content of debian/apparmor.d.hide. Whonix has special addition.
var Hide = `# This file is generated by "make", all edit will be lost. var Hide = `# This file is generated by "just", all edit will be lost.
/etc/apparmor.d/usr.bin.firefox /etc/apparmor.d/usr.bin.firefox
/etc/apparmor.d/usr.bin.swtpm
/etc/apparmor.d/usr.bin.wsdd
/etc/apparmor.d/usr.libexec.geoclue
/etc/apparmor.d/usr.sbin.cups-browsed /etc/apparmor.d/usr.sbin.cups-browsed
/etc/apparmor.d/usr.sbin.cupsd /etc/apparmor.d/usr.sbin.cupsd
/etc/apparmor.d/usr.sbin.rsyslogd /etc/apparmor.d/usr.sbin.rsyslogd

View file

@ -0,0 +1,108 @@
// apparmor.d - Full set of apparmor profiles
// Copyright (C) 2021-2024 Alexandre Pujol <alexandre@pujol.io>
// SPDX-License-Identifier: GPL-2.0-only
package prepare
import (
"fmt"
"strings"
"github.com/roddhjav/apparmor.d/pkg/paths"
"github.com/roddhjav/apparmor.d/pkg/prebuild"
)
var (
serverIgnorePatterns = []string{
"include <abstractions/app/chromium>",
"include <abstractions/app/firefox>",
"include <abstractions/app/open>",
"include <abstractions/common/desktop>",
"include <abstractions/common/electron>",
"include <abstractions/common/gnome>",
"include <abstractions/cosmic>",
"include <abstractions/desktop>",
"include <abstractions/desktop>",
"include <abstractions/freedesktop.org>",
"include <abstractions/gnome-strict>",
"include <abstractions/kde-strict>",
"include <abstractions/lxqt>",
"include <abstractions/xfce>",
}
serverIgnoreGroups = []string{
"akonadi",
"avahi",
"bluetooth",
"browsers",
"cosmic",
"cups",
"display-manager",
"flatpak",
"freedesktop",
"gnome",
"gvfs",
"hyprland",
"kde",
"lxqt",
"steam",
"xfce",
"zed",
}
)
type Server struct {
prebuild.Base
}
func init() {
RegisterTask(&Server{
Base: prebuild.Base{
Keyword: "server",
Msg: "Configure AppArmor for server",
},
})
}
func (p Server) Apply() ([]string, error) {
res := []string{}
// Ignore desktop related groups
groupNb := 0
for _, group := range serverIgnoreGroups {
path := prebuild.RootApparmord.Join("groups", group)
if path.IsDir() {
if err := path.RemoveAll(); err != nil {
return res, err
}
groupNb++
} else {
res = append(res, fmt.Sprintf("Group %s not found, ignoring", path))
}
}
// Ignore profiles using a desktop related abstraction
fileNb := 0
files, _ := prebuild.RootApparmord.ReadDirRecursiveFiltered(nil, paths.FilterOutDirectories())
for _, file := range files {
if !file.Exist() {
continue
}
profile, err := file.ReadFileAsString()
if err != nil {
return res, err
}
for _, pattern := range serverIgnorePatterns {
if strings.Contains(profile, pattern) {
if err := file.RemoveAll(); err != nil {
return res, err
}
fileNb++
break
}
}
}
res = append(res, fmt.Sprintf("%d groups ignored", groupNb))
res = append(res, fmt.Sprintf("%d profiles ignored", fileNb))
return res, nil
}

View file

@ -11,9 +11,13 @@ set -eu -o pipefail
RES=$(mktemp) RES=$(mktemp)
echo "false" >"$RES" echo "false" >"$RES"
MAX_JOBS=$(nproc) MAX_JOBS=$(nproc)
APPARMORD=${CHECK_APPARMORD:-apparmor.d}
SBIN_LIST=${CHECK_SBIN_LIST:-tests/sbin.list}
declare WITH_CHECK declare WITH_CHECK
declare _check_is_disabled declare _check_is_disabled
readonly RES MAX_JOBS APPARMORD="apparmor.d" declare _check_is_disabled_global
_FILE_IGNORE_ALL=false
readonly APPARMORD SBIN_LIST RES MAX_JOBS
readonly reset="\033[0m" fgRed="\033[0;31m" fgYellow="\033[0;33m" fgWhite="\033[0;37m" BgWhite="\033[1;37m" readonly reset="\033[0m" fgRed="\033[0;31m" fgYellow="\033[0;33m" fgWhite="\033[0;37m" BgWhite="\033[1;37m"
_msg() { printf '%b%s%b\n' "$BgWhite" "$*" "$reset"; } _msg() { printf '%b%s%b\n' "$BgWhite" "$*" "$reset"; }
_warn() { _warn() {
@ -42,6 +46,11 @@ _in_array() {
_is_enabled() { _is_enabled() {
local check="$1" local check="$1"
if _in_array "$check" "${WITH_CHECK[@]}"; then if _in_array "$check" "${WITH_CHECK[@]}"; then
if [[ -n "${_check_is_disabled_global+x}" && ${#_check_is_disabled_global[@]} -gt 0 ]]; then
if _in_array "$check" "${_check_is_disabled_global[@]}"; then
return 1
fi
fi
if [[ -z "${_check_is_disabled+x}" || ${#_check_is_disabled[@]} -eq 0 ]]; then if [[ -z "${_check_is_disabled+x}" || ${#_check_is_disabled[@]} -eq 0 ]]; then
return 0 return 0
fi fi
@ -68,10 +77,18 @@ _ignore_lint() {
local checks line="$1" local checks line="$1"
if [[ "$line" =~ ^[[:space:]]*$_IGNORE_LINT=.*$ ]]; then if [[ "$line" =~ ^[[:space:]]*$_IGNORE_LINT=.*$ ]]; then
# Start of an ignore block # Start of an ignore block (or file-wide if in header)
_IGNORE_LINT_BLOCK=true
checks="${line#*"$_IGNORE_LINT="}" checks="${line#*"$_IGNORE_LINT="}"
read -ra _check_is_disabled <<<"${checks//,/ }" read -ra _parsed <<<"${checks//,/ }"
if (( line_number <= 10 )); then
# Treat as file-wide ignore
_check_is_disabled_global=("${_parsed[@]}")
_FILE_IGNORE_ALL=true
_IGNORE_LINT_BLOCK=false
return 0
fi
_IGNORE_LINT_BLOCK=true
_check_is_disabled=("${_parsed[@]}")
elif [[ $_IGNORE_LINT_BLOCK == true && "$line" =~ ^[[:space:]]*$ ]]; then elif [[ $_IGNORE_LINT_BLOCK == true && "$line" =~ ^[[:space:]]*$ ]]; then
# New paragraph, end of block # New paragraph, end of block
@ -79,22 +96,33 @@ _ignore_lint() {
_check_is_disabled=() _check_is_disabled=()
elif [[ $_IGNORE_LINT_BLOCK == true ]]; then elif [[ $_IGNORE_LINT_BLOCK == true ]]; then
# Nothing to do, we are in a block # Nothing to do, we are in a block/paragraph
return 0 return 0
elif [[ "$line" == *"$_IGNORE_LINT="* ]]; then elif [[ "$line" == *"$_IGNORE_LINT="* ]]; then
# Inline ignore # Inline ignore (or file-wide if in header)
checks="${line#*"$_IGNORE_LINT="}" checks="${line#*"$_IGNORE_LINT="}"
read -ra _check_is_disabled <<<"${checks//,/ }" read -ra _parsed <<<"${checks//,/ }"
if (( line_number <= 10 )); then
_check_is_disabled_global=("${_parsed[@]}")
_FILE_IGNORE_ALL=true
return 0
fi
_check_is_disabled=("${_parsed[@]}")
else else
_check_is_disabled=() # Do not clear if file-wide ignore is set
if ! $_FILE_IGNORE_ALL; then
_check_is_disabled=()
fi
fi fi
} }
_check() { _check() {
local file="$1" local file="$1"
local line_number=0 line_number=0
_FILE_IGNORE_ALL=false
_check_is_disabled_global=()
while IFS= read -r line; do while IFS= read -r line; do
line_number=$((line_number + 1)) line_number=$((line_number + 1))
@ -193,6 +221,7 @@ declare -A EQUIVALENTS=(
["awk"]="{m,g,}awk" ["awk"]="{m,g,}awk"
["gawk"]="{m,g,}awk" ["gawk"]="{m,g,}awk"
["grep"]="{,e}grep" ["grep"]="{,e}grep"
["gs"]="gs{,.bin}"
["which"]="which{,.debianutils}" ["which"]="which{,.debianutils}"
) )
_check_equivalent() { _check_equivalent() {
@ -500,14 +529,14 @@ _check_udev() {
check_sbin() { check_sbin() {
local file name jobs local file name jobs
mapfile -t sbin <tests/sbin.list mapfile -t sbin <"$SBIN_LIST"
_msg "Ensuring '@{bin} and '@{sbin}' are correctly used in profiles" _msg "Ensuring '@{bin} and '@{sbin}' are correctly used in profiles"
jobs=0 jobs=0
for name in "${sbin[@]}"; do for name in "${sbin[@]}"; do
( (
mapfile -t files < <( mapfile -t files < <(
grep --line-number --recursive -P "(^|[[:space:]])@{bin}/$name([[:space:]]|$)(?!.*$_IGNORE_LINT=sbin)" apparmor.d | grep --line-number --recursive -P "(^|[[:space:]])@{bin}/$name([[:space:]]|$)(?!.*$_IGNORE_LINT=sbin)" "$APPARMORD" |
cut -d: -f1,2 cut -d: -f1,2
) )
for file in "${files[@]}"; do for file in "${files[@]}"; do
@ -520,7 +549,7 @@ check_sbin() {
local pattern='[[:alnum:]_.-]+' # Pattern for valid file names local pattern='[[:alnum:]_.-]+' # Pattern for valid file names
jobs=0 jobs=0
mapfile -t files < <(grep --line-number --recursive -E "(^|[[:space:]])@{sbin}/$pattern([[:space:]]|$)" apparmor.d | cut -d: -f1,2) mapfile -t files < <(grep --line-number --recursive -E "(^|[[:space:]])@{sbin}/$pattern([[:space:]]|$)" "$APPARMORD" | cut -d: -f1,2)
for file in "${files[@]}"; do for file in "${files[@]}"; do
( (
while read -r match; do while read -r match; do

View file

@ -1,6 +1,22 @@
#cloud-config #cloud-config
packages: *core-packages packages: *gnome-packages
runcmd:
# Replace SELinux by AppArmor in kernel parameters
- sed -i 's/security=selinux selinux=1/apparmor=1 apparmor.debug=1/g' /etc/default/grub
# Regenerate grub.cfg
- grub2-mkconfig -o /boot/grub2/grub.cfg
# Ensure auditd is enabled
- systemctl enable systemd-journald-audit.socket
write_files: write_files:
- *shared-directory # Setup shared directory - *shared-directory # Setup shared directory
- path: /etc/sysconfig/displaymanager
append: true
content: |
DISPLAYMANAGER="gdm"

View file

@ -1,6 +1,18 @@
#cloud-config #cloud-config
packages: *core-packages packages: *kde-packages
# apparmor.debug=1
runcmd:
# Replace SELinux by AppArmor in kernel parameters
- sed -i 's/security=selinux selinux=1/apparmor=1/g' /etc/default/grub
# Regenerate grub.cfg
- grub2-mkconfig -o /boot/grub2/grub.cfg
write_files: write_files:
- *shared-directory # Setup shared directory - *shared-directory # Setup shared directory
- path: /etc/sysconfig/displaymanager
append: true
content: |
DISPLAYMANAGER="sddm"

View file

@ -2,6 +2,13 @@
packages: *core-packages packages: *core-packages
runcmd:
# Replace SELinux by AppArmor in kernel parameters
- sed -i 's/security=selinux selinux=1/apparmor=1 apparmor.debug=1/g' /etc/default/grub
# Regenerate grub.cfg
- grub2-mkconfig -o /boot/grub2/grub.cfg
write_files: write_files:
- *shared-directory # Setup shared directory - *shared-directory # Setup shared directory
- *systemd-netword # Network configuration for server - *systemd-netword # Network configuration for server

View file

@ -2,9 +2,11 @@
# Core packages for OpenSUSE # Core packages for OpenSUSE
core-packages: &core-packages core-packages: &core-packages
- pattern:apparmor
- apparmor-profiles - apparmor-profiles
- bash-completion - bash-completion
- distribution-release - distribution-release
- docker
- git - git
- go - go
- golang-packaging - golang-packaging
@ -12,5 +14,57 @@ core-packages: &core-packages
- just - just
- rpmbuild - rpmbuild
- rsync - rsync
- systemd-container
- systemd-homed
- vim - vim
gnome-packages: &gnome-packages
# Core packages for OpenSUSE
- pattern:apparmor
- apparmor-profiles
- bash-completion
- distribution-release
- docker
- git
- go
- golang-packaging
- htop
- just
- rpmbuild
- rsync
- systemd-container
- systemd-homed
- vim
# Gnome packages for OpenSUSE
- pattern:gnome
- gdm
- spice-vdagent
- terminator
- loupe
- ptyxis
kde-packages: &kde-packages
# Core packages for OpenSUSE
- pattern:apparmor
- apparmor-profiles
- bash-completion
- distribution-release
- docker
- git
- go
- golang-packaging
- htop
- just
- rpmbuild
- rsync
- systemd-container
- systemd-homed
- vim
# KDE packages for OpenSUSE
- pattern:kde_plasma
- pattern:kde
- sddm
- spice-vdagent
- terminator

View file

@ -71,10 +71,10 @@ build {
"while [ ! -f /var/lib/cloud/instance/boot-finished ]; do echo 'Waiting for Cloud-Init...'; sleep 20; done", "while [ ! -f /var/lib/cloud/instance/boot-finished ]; do echo 'Waiting for Cloud-Init...'; sleep 20; done",
# Ensure cloud-init is successful # Ensure cloud-init is successful
# "cloud-init status", "cloud-init status || cloud-init collect-logs --tarfile /root/cloud-init.tar.gz",
# Remove logs and artifacts so cloud-init can re-run # Remove logs and artifacts so cloud-init can re-run
# "cloud-init clean", "cloud-init clean || true",
# Install local files and config # Install local files and config
"bash /tmp/init.sh", "bash /tmp/init.sh",

View file

@ -60,8 +60,7 @@ clean_pacman() {
clean_zypper() { clean_zypper() {
_msg "Cleaning zypper cache" _msg "Cleaning zypper cache"
zypper update -y zypper clean --all
zypper clean -y
} }
# Make the image as impersonal as possible. # Make the image as impersonal as possible.