[neon/backports-noble/apparmor-noble/Neon/unstable] debian: try a later beta which has been built for noble in the apparmor-dev backports ppa
Carlos De Maine
null at kde.org
Wed Apr 9 08:39:30 BST 2025
Git commit f91f966d4d07c1a075fbeaa12ccbfeb389bd4b7a by Carlos De Maine.
Committed on 09/04/2025 at 07:39.
Pushed by carlosdem into branch 'Neon/unstable'.
try a later beta which has been built for noble in the apparmor-dev backports ppa
M +2 -2 debian/apparmor-notify.install
M +5 -2 debian/apparmor-profiles.install
M +0 -1 debian/apparmor.dirs
M +52 -6 debian/apparmor.install
M +2 -0 debian/apparmor.maintscript
M +1 -0 debian/apparmor.manpages
M +185 -0 debian/changelog
M +5 -1 debian/control
M +1 -1 debian/libpam-apparmor.install
M +30 -7 debian/patches/series
A +196 -0 debian/patches/ubuntu/Move-the-bwrap-userns-restrict-profile-out-of-extras.patch
A +176 -0 debian/patches/ubuntu/Move-the-unshare-userns-restrict-profile-out-of-extras.patch
A +67 -0 debian/patches/ubuntu/alsamixer_mr_1517.patch
A +57 -0 debian/patches/ubuntu/delete-the-busybox-and-nautilus-profiles.patch
A +42 -0 debian/patches/ubuntu/dnstracer_mr_1366.patch
D +0 -33 debian/patches/ubuntu/fix-abi-break-record-for-aa-log-record.patch
A +681 -0 debian/patches/ubuntu/frr_mr_1380.patch
A +44 -0 debian/patches/ubuntu/fusermount3_mr_1514.patch
A +40 -0 debian/patches/ubuntu/fusermount3_profile_fixup.patch
A +32 -0 debian/patches/ubuntu/iotop_c_mr_1520.patch
A +65 -0 debian/patches/ubuntu/irssi_mr_1332.patch
D +0 -60 debian/patches/ubuntu/libapparmor-make-af_protos.h-consistent-in-different.patch
A +57 -0 debian/patches/ubuntu/libapparmor-swig-perl-typemaps.patch
A +57 -0 debian/patches/ubuntu/lsblk_mr_1437.patch
A +60 -0 debian/patches/ubuntu/lsusb_mr_1433.patch
A +63 -0 debian/patches/ubuntu/mbsync_mr_1372.patch
A +74 -0 debian/patches/ubuntu/mosquitto_mr_1506.patch
A +66 -0 debian/patches/ubuntu/netcat-openbsd_mr_1327.patch
A +133 -0 debian/patches/ubuntu/openvpn_mr_1263.patch
D +0 -3259 debian/patches/ubuntu/parser-add-support-for-prompting.patch
D +0 -129 debian/patches/ubuntu/parser-fix-integer-overflow-bug-in-rule-priority-com.patch
M +18 -21 debian/patches/ubuntu/parser-fix-pam_apparmor-regression-test-failures.patch
D +0 -141 debian/patches/ubuntu/parser-fix-rule-priority-destroying-rule-permissions.patch
D +0 -74 debian/patches/ubuntu/parser-revert-removal-of-second-minimization-pass.patch
D +0 -72 debian/patches/ubuntu/parser-update-tsts-for-explicit-deny-and-filtering-c.patch
M +5 -3 debian/patches/ubuntu/profiles-grant-access-to-systemd-resolved.patch
A +97 -0 debian/patches/ubuntu/remmina_mr_1348.patch
A +184 -0 debian/patches/ubuntu/rygel_mr_1311.patch
M +6 -4 debian/patches/ubuntu/samba-systemd-interaction.patch
A +300 -0 debian/patches/ubuntu/sbuild_mr_1555.patch
A +75 -0 debian/patches/ubuntu/socat_mr_1319.patch
A +28 -0 debian/patches/ubuntu/tar_cap_fowner_fix_mr_1553.patch
A +77 -0 debian/patches/ubuntu/tar_mr_1453.patch
A +112 -0 debian/patches/ubuntu/tinyproxy_mr_1477.patch
A +107 -0 debian/patches/ubuntu/tnftp_mr_1363.patch
A +87 -0 debian/patches/ubuntu/tshark_mr_1384.patch
D +0 -27 debian/patches/ubuntu/utils-change-os.mkdir-to-self.mkpath-to-create-inter.patch
A +178 -0 debian/patches/ubuntu/wireguard_mr_1323.patch
A +75 -0 debian/patches/ubuntu/wpa_supplicant_mr_1385.patch
A +31 -0 debian/patches/ubuntu/wpa_supplicant_profile_fixup.patch
A +62 -0 debian/patches/ubuntu/znc_mr_1376.patch
M +17 -18 debian/rules
M +2 -0 debian/usr/lib/sysctl.d/10-apparmor.conf
https://invent.kde.org/neon/backports-noble/apparmor-noble/-/commit/f91f966d4d07c1a075fbeaa12ccbfeb389bd4b7a
diff --git a/debian/apparmor-notify.install b/debian/apparmor-notify.install
index e214e00..433a797 100644
--- a/debian/apparmor-notify.install
+++ b/debian/apparmor-notify.install
@@ -1,5 +1,5 @@
utils/aa-notify.desktop /etc/xdg/autostart
usr/sbin/aa-notify /usr/bin/
etc/apparmor/notify.conf /etc/apparmor/
-usr/share/polkit-1/actions/com.ubuntu.pkexec.aa-notify.policy
-etc/apparmor/default_unconfined.template
\ No newline at end of file
+usr/share/polkit-1/actions/net.apparmor.pkexec.aa-notify.policy
+etc/apparmor/default_unconfined.template
diff --git a/debian/apparmor-profiles.install b/debian/apparmor-profiles.install
index 5cecd9d..4034671 100644
--- a/debian/apparmor-profiles.install
+++ b/debian/apparmor-profiles.install
@@ -40,6 +40,8 @@ etc/apparmor.d/usr.sbin.nscd
etc/apparmor.d/usr.sbin.smbd
etc/apparmor.d/usr.sbin.smbldap-useradd
etc/apparmor.d/usr.sbin.traceroute
+etc/apparmor.d/tar /usr/share/apparmor/extra-profiles/
+etc/apparmor.d/wpa_supplicant /usr/share/apparmor/extra-profiles/
etc/apparmor.d/zgrep /usr/share/apparmor/extra-profiles/
usr/share/apparmor/extra-profiles/README
usr/share/apparmor/extra-profiles/bin.netstat
@@ -63,8 +65,6 @@ usr/share/apparmor/extra-profiles/usr.bin.evolution-2.10
usr/share/apparmor/extra-profiles/usr.bin.fam
# The clamav-freshclam package ships its own profile
#usr/share/apparmor/extra-profiles/usr.bin.freshclam
-usr/share/apparmor/extra-profiles/bwrap-userns-restrict
-usr/share/apparmor/extra-profiles/unshare-userns-restrict
usr/share/apparmor/extra-profiles/usr.bin.gaim
usr/share/apparmor/extra-profiles/usr.bin.man
usr/share/apparmor/extra-profiles/usr.bin.mlmmj-bounce
@@ -116,6 +116,7 @@ usr/share/apparmor/extra-profiles/postfix-smtp
usr/share/apparmor/extra-profiles/postfix-smtpd
usr/share/apparmor/extra-profiles/postfix-spawn
usr/share/apparmor/extra-profiles/postfix-tlsmgr
+usr/share/apparmor/extra-profiles/postfix-tlsproxy
usr/share/apparmor/extra-profiles/postfix-trivial-rewrite
usr/share/apparmor/extra-profiles/postfix-verify
usr/share/apparmor/extra-profiles/postfix-virtual
@@ -149,3 +150,5 @@ usr/share/apparmor/extra-profiles/usr.bin.pyzorsocket
usr/share/apparmor/extra-profiles/usr.bin.razorsocket
usr/share/apparmor/extra-profiles/usr.sbin.clamd
usr/share/apparmor/extra-profiles/usr.sbin.haproxy
+usr/share/apparmor/extra-profiles/socat
+
diff --git a/debian/apparmor.dirs b/debian/apparmor.dirs
index 086e9e6..717979a 100644
--- a/debian/apparmor.dirs
+++ b/debian/apparmor.dirs
@@ -4,5 +4,4 @@
/etc/apparmor.d/tunables/home.d
/etc/apparmor.d/tunables/multiarch.d
/etc/apparmor.d/tunables/xdg-user-dirs.d
-/lib/apparmor/
/var/cache/apparmor
diff --git a/debian/apparmor.install b/debian/apparmor.install
index 9a64f8c..e2ffdd7 100644
--- a/debian/apparmor.install
+++ b/debian/apparmor.install
@@ -22,6 +22,7 @@ etc/apparmor.d/tunables/run
etc/apparmor.d/tunables/securityfs
etc/apparmor.d/tunables/share
etc/apparmor.d/tunables/sys
+etc/apparmor.d/tunables/system
etc/apparmor.d/tunables/xdg-user-dirs
etc/apparmor.d/tunables/xdg-user-dirs.d
etc/apparmor.d/ch-checkns
@@ -29,7 +30,7 @@ etc/apparmor.d/ch-run
etc/apparmor.d/crun
etc/apparmor.d/flatpak
etc/apparmor.d/linux-sandbox
-etc/apparmor.d/busybox
+# etc/apparmor.d/busybox
etc/apparmor.d/buildah
etc/apparmor.d/cam
etc/apparmor.d/ipa_verify
@@ -100,7 +101,7 @@ etc/apparmor.d/devhelp
etc/apparmor.d/epiphany
etc/apparmor.d/evolution
etc/apparmor.d/opam
-etc/apparmor.d/nautilus
+# etc/apparmor.d/nautilus
etc/apparmor.d/element-desktop
etc/apparmor.d/geary
etc/apparmor.d/goldendict
@@ -121,12 +122,57 @@ etc/apparmor.d/balena-etcher
etc/apparmor.d/transmission
etc/apparmor.d/Xorg
etc/apparmor.d/chromium
+# New profiles added as part of the profile writing effort
+etc/apparmor.d/alsamixer
+etc/apparmor.d/iotop-c
+etc/apparmor.d/babeld
+etc/apparmor.d/bfdd
+etc/apparmor.d/bgpd
+etc/apparmor.d/dnstracer
+etc/apparmor.d/eigrpd
+etc/apparmor.d/fabricd
+etc/apparmor.d/fusermount3
+etc/apparmor.d/isisd
+etc/apparmor.d/ldpd
+etc/apparmor.d/mosquitto
+etc/apparmor.d/nhrpd
+etc/apparmor.d/ospf6d
+etc/apparmor.d/ospfd
+etc/apparmor.d/pathd
+etc/apparmor.d/pbrd
+etc/apparmor.d/pim6d
+etc/apparmor.d/pimd
+etc/apparmor.d/ripd
+etc/apparmor.d/ripngd
+etc/apparmor.d/staticd
+etc/apparmor.d/vrrpd
+etc/apparmor.d/abstractions/frr
+etc/apparmor.d/abstractions/frr-snmp
+etc/apparmor.d/irssi
+etc/apparmor.d/lsblk
+etc/apparmor.d/lsusb
+etc/apparmor.d/mbsync
+etc/apparmor.d/nc.openbsd
+etc/apparmor.d/openvpn
+etc/apparmor.d/remmina
+etc/apparmor.d/rygel
+etc/apparmor.d/tunables/rygel
+etc/apparmor.d/tinyproxy
+etc/apparmor.d/tnftp
+etc/apparmor.d/tshark
+etc/apparmor.d/wg
+etc/apparmor.d/wg-quick
+etc/apparmor.d/znc
+# The special *-userns-restrict profiles
+etc/apparmor.d/bwrap-userns-restrict
+etc/apparmor.d/unshare-userns-restrict
+
etc/apparmor/parser.conf
-lib/apparmor/profile-load
-sbin/apparmor_parser
+lib/apparmor/profile-load /usr/lib/apparmor
+sbin/apparmor_parser /usr/sbin
parser/aa-teardown /usr/sbin/
-parser/apparmor.systemd /lib/apparmor/
-lib/apparmor/rc.apparmor.functions
+parser/apparmor.systemd /usr/lib/apparmor/
+lib/apparmor/rc.apparmor.functions /usr/lib/apparmor
usr/bin/aa-enabled
usr/bin/aa-exec
usr/bin/aa-features-abi
diff --git a/debian/apparmor.maintscript b/debian/apparmor.maintscript
index 0862338..ed787fb 100644
--- a/debian/apparmor.maintscript
+++ b/debian/apparmor.maintscript
@@ -61,3 +61,5 @@ rm_conffile /etc/apparmor.d/opt.microsoft.msedge.msedge 4.0.0~alpha4-0ubuntu1~
rm_conffile /etc/apparmor.d/opt.brave.com.brave.brave 4.0.0~alpha4-0ubuntu1~
rm_conffile /etc/apparmor.d/opt.vivaldi.vivaldi-bin 4.0.0~alpha4-0ubuntu1~
rm_conffile /etc/apparmor.d/bwrap-userns-restrict 4.0.1-0ubuntu2~
+rm_conffile /etc/apparmor.d/tar 4.1.0~beta5-0ubuntu5~
+rm_conffile /etc/apparmor.d/wpa_supplicant 4.1.0~beta5-0ubuntu5~
diff --git a/debian/apparmor.manpages b/debian/apparmor.manpages
index 2f03f63..965d9ce 100644
--- a/debian/apparmor.manpages
+++ b/debian/apparmor.manpages
@@ -5,6 +5,7 @@ debian/tmp/usr/share/man/man5/apparmor.d.5
debian/tmp/usr/share/man/man5/apparmor.vim.5
debian/tmp/usr/share/man/man7/apparmor.7
debian/tmp/usr/share/man/man7/apparmor_xattrs.7
+debian/tmp/usr/share/man/man8/aa-load.8
debian/tmp/usr/share/man/man8/aa-remove-unknown.8
debian/tmp/usr/share/man/man8/aa-status.8
debian/tmp/usr/share/man/man8/aa-teardown.8
diff --git a/debian/changelog b/debian/changelog
index 54d69e3..7548248 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,188 @@
+apparmor (4.1.0~beta5-0ubuntu5) noble; urgency=medium
+
+ * Add patch to fix fusermount3 profile breaking AppImages (LP: #2098993)
+ - d/p/u/fusermount3_profile_fixup.patch
+ * debian/apparmor.maintscript: remove tar and wpa_supplicant profiles
+ if they were previously installed via an upgrade
+
+ -- Ryan Lee <ryan.lee at canonical.com> Thu, 20 Feb 2025 09:18:01 -0800
+
+apparmor (4.1.0~beta5-0ubuntu4) plucky; urgency=medium
+
+ * Add patch to fix sbuild unshare breakage caused by the new
+ unshare-userns-restrict profile (LP: #2098906)
+ - d/p/u/sbuild_mr_1555.patch
+
+ -- Ryan Lee <ryan.lee at canonical.com> Wed, 19 Feb 2025 16:24:56 -0800
+
+apparmor (4.1.0~beta5-0ubuntu3) plucky; urgency=medium
+
+ * Add patch to address AppArmor denial logs reported in LP: #2098838:
+ - d/p/u/wpa_supplicant_profile_fixup.patch
+ * debian/apparmor.install: remove wpa_supplicant profile from default
+ install
+ * debian/apparmor-profiles.install: place wpa_supplicant profile in
+ extra-profiles
+
+ -- Ryan Lee <ryan.lee at canonical.com> Wed, 19 Feb 2025 13:56:15 -0800
+
+apparmor (4.1.0~beta5-0ubuntu2) plucky; urgency=medium
+
+ * Add patch to add capability fowner permission to the tar profile to
+ fix tar and snapd autopkgtest failures
+ - d/p/u/tar_cap_fowner_fix_mr_1553.patch
+ * debian/apparmor.install: remove tar profile from default install
+ * debian/apparmor-profiles.install: place tar profile in extra-profiles
+
+ -- Alex Murray <alex.murray at canonical.com> Wed, 19 Feb 2025 12:08:03 +1030
+
+apparmor (4.1.0~beta5-0ubuntu1) plucky; urgency=medium
+
+ * New upstream release.
+ * Dropped patches that were applied upstream:
+ - d/p/u/profiles-fix-non-user-namespace-bypass-in-unshare.patch
+ - d/p/u/libapparmor-swig-various-fixes-for-32bit-and-older.patch
+ - d/p/u/aa-notify-ttkthemes-fallback-mr1324-partial.patch
+ - d/p/u/aa-notify-fix-packaging-polkit.patch
+ - d/p/u/utils-allow-install-locations-to-be-overridden-in-Make.patch
+ * Add patch to fix Perl SWIG typemaps to complement upstream SWIG updates:
+ - d/p/u/libapparmor-swig-perl-typemaps.patch
+ * debian/apparmor.install: add entry for new upstream tunables/system
+ tunable
+ * debian/apparmor-notify.install: update location of polkit policy
+ file to match the new upstream location
+
+ -- Ryan Lee <ryan.lee at canonical.com> Tue, 18 Feb 2025 09:17:44 -0800
+
+apparmor (4.1.0~beta4-0ubuntu3) plucky; urgency=medium
+
+ * Add patch to fix build path leaking into generated polkit file:
+ - d/p/u/aa-notify-fix-packaging-polkit.patch
+ * Add patch to enable environment variable overrides in utils Makefile:
+ - d/p/u/utils-allow-install-locations-to-be-overridden-in-Make.patch
+
+ -- Ryan Lee <ryan.lee at canonical.com> Thu, 13 Feb 2025 14:30:46 -0800
+
+apparmor (4.1.0~beta4-0ubuntu2) plucky; urgency=medium
+
+ * Add patch to fix libapparmor SWIG build on 32-bit systems:
+ - d/p/u/libapparmor-swig-various-fixes-for-32-bit-and-older.patch
+ * Add patch for aa-notify GUI fallback when python3-ttkthemes is
+ unavailable:
+ - d/p/u/aa-notify-ttkthemes-fallback-mr1324-partial.patch
+ * Add patch with another new AppArmor profile for testing:
+ - d/p/u/mosquitto_mr_1506.patch
+ * debian/apparmor.install: add entry for the mosquitto profile
+ * debian/control: remove python3-ttkthemes from Build-Depends to fix
+ i386 build now that fallback is available
+
+ -- Ryan Lee <ryan.lee at canonical.com> Wed, 12 Feb 2025 15:30:49 -0800
+
+apparmor (4.1.0~beta4-0ubuntu1) plucky; urgency=medium
+
+ * New upstream release.
+ * Auto-refreshed patches via quilt refresh:
+ - d/p/u/profiles-grant-access-to-systemd-resolved.patch
+ - d/p/u/samba-systemd-interaction.patch
+ - d/p/u/parser-fix-pam_apparmor-regression-test-failures.patch
+ * Drop patches that were applied upstream:
+ - d/p/u/utils-change-os.mkdir-to-self.mkpath-to-create-inter.patch
+ - d/p/u/parser-fix-rule-priority-destroying-rule-permissions.patch
+ - d/p/u/libapparmor-make-af_protos.h-consistent-in-different.patch
+ - d/p/u/fix-abi-break-record-for-aa-log-record.patch
+ - d/p/u/handle-missing-cgitb.patch
+ * Drop patches that were superseded upstream:
+ - d/p/u/parser-fix-integer-overflow-bug-in-rule-priority-com.patch
+ - d/p/u/parser-revert-removal-of-second-minimization-pass.patch
+ - d/p/u/parser-update-tsts-for-explicit-deny-and-filtering-c.patch
+ * Add patches containing new AppArmor profiles for more testing:
+ - d/p/u/znc_mr_1376.patch
+ - d/p/u/tfntp_mr_1363.patch
+ - d/p/u/socat_mr_1319.patch
+ - d/p/u/rygel_mr_1311.patch
+ - d/p/u/remmina_mr_1348.patch
+ - d/p/u/lsusb_mr_1433.patch
+ - d/p/u/lsblk_mr_1437.patch
+ - d/p/u/mbsync_mr_1372.patch
+ - d/p/u/openvpn_mr_1263.patch
+ - d/p/u/tshark_mr_1384.patch
+ - d/p/u/wireguard_mr_1323.patch
+ - d/p/u/irssi_mr_1332.patch
+ - d/p/u/netcat-openbsd_mr_1327.patch
+ - d/p/u/tar_mr_1453.patch
+ - d/p/u/alsamixer_mr_1517.patch
+ - d/p/u/tinyproxy_mr_1477.patch
+ - d/p/u/frr_mr_1380.patch
+ - d/p/u/iotop_c_mr_1520.patch
+ - d/p/u/wpa_supplicant_mr_1385.patch
+ - d/p/u/fusermount3_mr_1514.patch
+ - d/p/u/dnstracer_mr_1366.patch
+ * Add a patch to enable the *-userns-restrict profiles by default:
+ - d/p/u/Move-the-bwrap-userns-restrict-profile-out-of-extras.patch
+ - d/p/u/Move the unshare-userns-restrict-profile-out-of-extras.patch
+ * Add a patch that deletes the busybox and nautilus profiles:
+ - d/p/u/delete-the-busybox-and-nautilus-profiles.patch
+ * debian/apparmor.dirs: remove /lib/apparmor as it would already be
+ created by the file installation process
+ * debian/apparmor.install:
+ - Install some files into /usr directory instead of under root
+ directory (as per the /usr merge):
+ - lib/apparmor/profile-load
+ - sbin/apparmor_parser
+ - parser/apparmor.systemd
+ - lib/apparmor/rc.apparmor/functions
+ - Install newly added profiles from profile patches above, with
+ the exception of the socat profile (d/p/u/socat_mr_1319.patch)
+ - Add installation of the *-userns-restrict profiles to install
+ them to /etc/apparmor.d/
+ - Remove entries for the busybox and nautilus profiles
+ * debian/apparmor.manpages: add upstream aa-load.8 man page
+ * debian/apparmor-profiles.install:
+ - Add entry for new upstream postfix-tlsproxy profile
+ - Add entry for the socat profile (d/p/u/socat_mr_1319.patch)
+ - Remove entries for *-userns-restrict profiles (moved to debian/
+ apparmor.install)
+ * debian/control:
+ - Add utils Build-Depends under a !nocheck condition for tests:
+ - flake8
+ - python3-gi
+ - python3-notify2
+ - python3-psutil
+ - python3-tk
+ - python3-ttkthemes
+ * debian/rules:
+ - override_dh_auto_build
+ - No longer create libraries/libapparmor/testsuite/test_multi/
+ testcase_mqueue_0[1-8].err empty files, as the patch they were
+ supposed to accompany was applied upstream
+ - override_dh_auto_test
+ - Test libapparmor in override_dh-auto-test before the parser and
+ binutils
+ - Add step that runs tests for utils
+ - override_dh_install-arch
+ - Fixup chmod call for lib/apparmor/apparmor.systemd for /usr
+ install location
+ * debian/libpam-apparmor.install:
+ - Install lib/security/pam_apparmor.so into /usr directory (as per
+ the /usr merge)
+ * debian/usr/lib/sysctl.d/10-apparmor.conf: Set sysctl
+ kernel.apparmor_restrict_unprivileged_unconfined=1
+
+ -- Ryan Lee <ryan.lee at canonical.com> Tue, 11 Feb 2025 17:12:16 -0800
+
+apparmor (4.1.0~beta1-0ubuntu5) plucky; urgency=medium
+
+ * d/p/u/handle-missing-cgitb.patch: handle the missing cgitb module, no
+ longer shipped with python 3.13 (LP: #2095597)
+
+ -- Andreas Hasenack <andreas at canonical.com> Tue, 28 Jan 2025 14:21:29 -0300
+
+apparmor (4.1.0~beta1-0ubuntu4) plucky; urgency=medium
+
+ * SRU: #2083480: No-change rebuild to add support for Python 3.13.
+
+ -- Matthias Klose <doko at ubuntu.com> Wed, 13 Nov 2024 09:56:58 +0100
+
apparmor (4.1.0~beta1-0ubuntu3) oracular; urgency=medium
* Add patch from upstream to fix unintentional ABI break (LP :#2083435)
diff --git a/debian/control b/debian/control
index dd42c58..cba4086 100644
--- a/debian/control
+++ b/debian/control
@@ -16,8 +16,8 @@ Build-Depends: apache2-dev,
dh-apache2,
dh-python,
dh-sequence-python3,
+ flake8 <!nocheck>,
flex,
- g++,
liblocale-gettext-perl <!nocheck>,
libpython3-all-dev,
libpam-dev,
@@ -28,7 +28,11 @@ Build-Depends: apache2-dev,
python3:any,
python3-all:any,
python3-all-dev:any,
+ python3-gi <!nocheck>,
+ python3-notify2 <!nocheck>,
+ python3-psutil <!nocheck>,
python3-setuptools,
+ python3-tk <!nocheck>,
swig
Standards-Version: 4.6.1
Vcs-Browser: https://salsa.debian.org/apparmor-team/apparmor/tree/ubuntu/master
diff --git a/debian/libpam-apparmor.install b/debian/libpam-apparmor.install
index 6e3fbd5..6153765 100644
--- a/debian/libpam-apparmor.install
+++ b/debian/libpam-apparmor.install
@@ -1 +1 @@
-lib/security/pam_apparmor.so
+lib/security/pam_apparmor.so /usr/lib/security/
diff --git a/debian/patches/series b/debian/patches/series
index 536c615..b5b1cbb 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -10,11 +10,34 @@ ubuntu/mimeinfo-snap-support.patch
ubuntu/profiles-grant-access-to-systemd-resolved.patch
ubuntu/samba-systemd-interaction.patch
ubuntu/userns-runtime-disable.patch
-ubuntu/utils-change-os.mkdir-to-self.mkpath-to-create-inter.patch
-ubuntu/parser-fix-rule-priority-destroying-rule-permissions.patch
ubuntu/parser-fix-pam_apparmor-regression-test-failures.patch
-ubuntu/parser-fix-integer-overflow-bug-in-rule-priority-com.patch
-ubuntu/parser-revert-removal-of-second-minimization-pass.patch
-ubuntu/parser-update-tsts-for-explicit-deny-and-filtering-c.patch
-ubuntu/libapparmor-make-af_protos.h-consistent-in-different.patch
-ubuntu/fix-abi-break-record-for-aa-log-record.patch
+ubuntu/lsblk_mr_1437.patch
+ubuntu/lsusb_mr_1433.patch
+ubuntu/remmina_mr_1348.patch
+ubuntu/rygel_mr_1311.patch
+ubuntu/socat_mr_1319.patch
+ubuntu/tnftp_mr_1363.patch
+ubuntu/znc_mr_1376.patch
+ubuntu/tshark_mr_1384.patch
+ubuntu/wireguard_mr_1323.patch
+ubuntu/openvpn_mr_1263.patch
+ubuntu/mbsync_mr_1372.patch
+ubuntu/irssi_mr_1332.patch
+ubuntu/netcat-openbsd_mr_1327.patch
+ubuntu/tar_mr_1453.patch
+ubuntu/alsamixer_mr_1517.patch
+ubuntu/tinyproxy_mr_1477.patch
+ubuntu/frr_mr_1380.patch
+ubuntu/iotop_c_mr_1520.patch
+ubuntu/wpa_supplicant_mr_1385.patch
+ubuntu/fusermount3_mr_1514.patch
+ubuntu/Move-the-bwrap-userns-restrict-profile-out-of-extras.patch
+ubuntu/Move-the-unshare-userns-restrict-profile-out-of-extras.patch
+ubuntu/delete-the-busybox-and-nautilus-profiles.patch
+ubuntu/dnstracer_mr_1366.patch
+ubuntu/mosquitto_mr_1506.patch
+ubuntu/libapparmor-swig-perl-typemaps.patch
+ubuntu/tar_cap_fowner_fix_mr_1553.patch
+ubuntu/wpa_supplicant_profile_fixup.patch
+ubuntu/sbuild_mr_1555.patch
+ubuntu/fusermount3_profile_fixup.patch
diff --git a/debian/patches/ubuntu/Move-the-bwrap-userns-restrict-profile-out-of-extras.patch b/debian/patches/ubuntu/Move-the-bwrap-userns-restrict-profile-out-of-extras.patch
new file mode 100644
index 0000000..1de0926
--- /dev/null
+++ b/debian/patches/ubuntu/Move-the-bwrap-userns-restrict-profile-out-of-extras.patch
@@ -0,0 +1,196 @@
+From cd73a121865dec2bd8e5f43f314119024c1ef045 Mon Sep 17 00:00:00 2001
+From: Ryan Lee <ryan.lee at canonical.com>
+Date: Wed, 5 Feb 2025 16:19:31 -0800
+Subject: [PATCH] Move the bwrap-userns-restrict profile out of extras into
+ apparmor.d
+
+---
+ .../profiles/extras => apparmor.d}/bwrap-userns-restrict | 0
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+ rename profiles/{apparmor/profiles/extras => apparmor.d}/bwrap-userns-restrict (100%)
+
+diff --git a/profiles/apparmor/profiles/extras/bwrap-userns-restrict b/profiles/apparmor/profiles/extras/bwrap-userns-restrict
+deleted file mode 100644
+index 9de2afc63..000000000
+--- a/profiles/apparmor/profiles/extras/bwrap-userns-restrict
++++ /dev/null
+@@ -1,85 +0,0 @@
+-# This profile allows almost everything and only exists to allow bwrap
+-# to work on a system with user namespace restrictions being enforced.
+-# bwrap is allowed access to user namespaces and capabilities within
+-# the user namespace, but its children do not have capabilities,
+-# blocking bwrap from being able to be used to arbitrarily by-pass the
+-# user namespace restrictions.
+-
+-# Note: the bwrap child is stacked against the bwrap profile due to
+-# bwraps use of no-new-privs.
+-
+-abi <abi/4.0>,
+-
+-include <tunables/global>
+-
+-profile bwrap /usr/bin/bwrap flags=(attach_disconnected,mediate_deleted) {
+- allow capability,
+- # not allow all, to allow for pix stack on systems that don't support
+- # rule priority.
+- #
+- # sadly we have to allow 'm' every where to allow children to work under
+- # profile stacking atm.
+- allow file rwlkm /{**,},
+- allow network,
+- allow unix,
+- allow ptrace,
+- allow signal,
+- allow mqueue,
+- allow io_uring,
+- allow userns,
+- allow mount,
+- allow umount,
+- allow pivot_root,
+- allow dbus,
+-
+- # stacked like this due to no-new-privs restriction
+- # this will stack a target profile against bwrap and unpriv_bwrap
+- # Ideally
+- # - there would be a transition at userns creation first. This would allow
+- # for the bwrap profile to be tighter, and looser within the user
+- # ns. bwrap will still have to fairly loose until a transition at
+- # namespacing in general (not just user ns) is available.
+- # - there would be an independent second target as fallback
+- # This would allow for select target profiles to be used, and not
+- # necessarily stack the unpriv_bwrap in cases where this is desired
+- #
+- # the ix works here because stack will apply to ix fallback
+- # Ideally we would sanitize the environment across a privilege boundry
+- # (leaving bwarp into application) but flatpak etc use environment glibc
+- # sanitized environment variables as part of the sandbox setup.
+- allow pix /** -> &bwrap//&unpriv_bwrap,
+-
+- # the local include should not be used without understanding the userns
+- # restriction.
+- # Site-specific additions and overrides. See local/README for details.
+- include if exists <local/bwrap-userns-restrict>
+-}
+-
+-# The unpriv_bwrap profile is used to strip capabilities within the userns
+-profile unpriv_bwrap flags=(attach_disconnected,mediate_deleted) {
+- # not allow all, to allow for pix stack
+- allow file rwlkm /{**,},
+- allow network,
+- allow unix,
+- allow ptrace,
+- allow signal,
+- allow mqueue,
+- allow io_uring,
+- allow userns,
+- allow mount,
+- allow umount,
+- allow pivot_root,
+- allow dbus,
+-
+- # bwrap profile does stacking against itself this will keep the target
+- # profile from having elevated privileges in the container.
+- # If done recursively the stack will remove any duplicate
+- allow pix /** -> &unpriv_bwrap,
+-
+- audit deny capability,
+-
+- # the local include should not be used without understanding the userns
+- # restriction.
+- # Site-specific additions and overrides. See local/README for details.
+- include if exists <local/unpriv_bwrap>
+-}
+diff --git a/profiles/apparmor.d/bwrap-userns-restrict b/profiles/apparmor.d/bwrap-userns-restrict
+new file mode 100644
+index 000000000..9de2afc63
+--- /dev/null
++++ b/profiles/apparmor.d/bwrap-userns-restrict
+@@ -0,0 +1,85 @@
++# This profile allows almost everything and only exists to allow bwrap
++# to work on a system with user namespace restrictions being enforced.
++# bwrap is allowed access to user namespaces and capabilities within
++# the user namespace, but its children do not have capabilities,
++# blocking bwrap from being able to be used to arbitrarily by-pass the
++# user namespace restrictions.
++
++# Note: the bwrap child is stacked against the bwrap profile due to
++# bwraps use of no-new-privs.
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile bwrap /usr/bin/bwrap flags=(attach_disconnected,mediate_deleted) {
++ allow capability,
++ # not allow all, to allow for pix stack on systems that don't support
++ # rule priority.
++ #
++ # sadly we have to allow 'm' every where to allow children to work under
++ # profile stacking atm.
++ allow file rwlkm /{**,},
++ allow network,
++ allow unix,
++ allow ptrace,
++ allow signal,
++ allow mqueue,
++ allow io_uring,
++ allow userns,
++ allow mount,
++ allow umount,
++ allow pivot_root,
++ allow dbus,
++
++ # stacked like this due to no-new-privs restriction
++ # this will stack a target profile against bwrap and unpriv_bwrap
++ # Ideally
++ # - there would be a transition at userns creation first. This would allow
++ # for the bwrap profile to be tighter, and looser within the user
++ # ns. bwrap will still have to fairly loose until a transition at
++ # namespacing in general (not just user ns) is available.
++ # - there would be an independent second target as fallback
++ # This would allow for select target profiles to be used, and not
++ # necessarily stack the unpriv_bwrap in cases where this is desired
++ #
++ # the ix works here because stack will apply to ix fallback
++ # Ideally we would sanitize the environment across a privilege boundry
++ # (leaving bwarp into application) but flatpak etc use environment glibc
++ # sanitized environment variables as part of the sandbox setup.
++ allow pix /** -> &bwrap//&unpriv_bwrap,
++
++ # the local include should not be used without understanding the userns
++ # restriction.
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/bwrap-userns-restrict>
++}
++
++# The unpriv_bwrap profile is used to strip capabilities within the userns
++profile unpriv_bwrap flags=(attach_disconnected,mediate_deleted) {
++ # not allow all, to allow for pix stack
++ allow file rwlkm /{**,},
++ allow network,
++ allow unix,
++ allow ptrace,
++ allow signal,
++ allow mqueue,
++ allow io_uring,
++ allow userns,
++ allow mount,
++ allow umount,
++ allow pivot_root,
++ allow dbus,
++
++ # bwrap profile does stacking against itself this will keep the target
++ # profile from having elevated privileges in the container.
++ # If done recursively the stack will remove any duplicate
++ allow pix /** -> &unpriv_bwrap,
++
++ audit deny capability,
++
++ # the local include should not be used without understanding the userns
++ # restriction.
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/unpriv_bwrap>
++}
+--
+2.43.0
+
diff --git a/debian/patches/ubuntu/Move-the-unshare-userns-restrict-profile-out-of-extras.patch b/debian/patches/ubuntu/Move-the-unshare-userns-restrict-profile-out-of-extras.patch
new file mode 100644
index 0000000..8360826
--- /dev/null
+++ b/debian/patches/ubuntu/Move-the-unshare-userns-restrict-profile-out-of-extras.patch
@@ -0,0 +1,176 @@
+From 320fba92cfa60072434648f353ae515164531ba5 Mon Sep 17 00:00:00 2001
+From: Ryan Lee <ryan.lee at canonical.com>
+Date: Wed, 5 Feb 2025 16:23:12 -0800
+Subject: [PATCH] Move the unshare-userns-restrict profile out of extras into
+ apparmor.d
+
+---
+ .../profiles/extras => apparmor.d}/unshare-userns-restrict | 0
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+ rename profiles/{apparmor/profiles/extras => apparmor.d}/unshare-userns-restrict (100%)
+
+diff --git a/profiles/apparmor/profiles/extras/unshare-userns-restrict b/profiles/apparmor/profiles/extras/unshare-userns-restrict
+deleted file mode 100644
+index 731f18b9c..000000000
+--- a/profiles/apparmor/profiles/extras/unshare-userns-restrict
++++ /dev/null
+@@ -1,75 +0,0 @@
+-# This profile allows almost everything and only exists to allow
+-# unshare to work on a system with user namespace restrictions
+-# being enforced.
+-# unshare is allowed access to user namespaces and capabilities
+-# within the user namespace, but its children do not have
+-# capabilities, blocking unshare from being able to be used to
+-# arbitrarily by-pass the user namespace restrictions.
+-# We restrict x mapping of any code that is unknown while unshare
+-# has privilige within the namespace. To help ensure unshare can't
+-# be used to attack the kernel.
+-#
+-# disabled by default as it can break some use cases on a system that
+-# doesn't have or has disable user namespace restrictions for unconfined
+-
+-abi <abi/4.0>,
+-
+-include <tunables/global>
+-
+-profile unshare /usr/bin/unshare flags=(attach_disconnected mediate_deleted) {
+- # not allow all, to allow for pix stack on systems that don't support
+- # rule priority.
+- #
+- # sadly we have to allow 'm' every where to allow children to work under
+- # profile stacking atm.
+- allow capability,
+- allow file rwmlk /{**,},
+- allow network,
+- allow unix,
+- allow ptrace,
+- allow signal,
+- allow mqueue,
+- allow io_uring,
+- allow userns,
+- allow mount,
+- allow umount,
+- allow pivot_root,
+- allow dbus,
+- # This will stack a target profile against unpriv_unshare
+- # Most of the comments for the pix transition in bwrap-userns-restrict
+- # also apply here, with the exception of unshare not using no-new-privs
+- # Thus, we only need a two-layer stack instead of a three-layer stack
+- audit allow pix /** -> &unpriv_unshare,
+-
+- # the local include should not be used without understanding the userns
+- # restriction.
+- # Site-specific additions and overrides. See local/README for details.
+- include if exists <local/unshare-userns-restrict>
+-}
+-
+-profile unpriv_unshare flags=(attach_disconnected mediate_deleted) {
+- # not allow all, to allow for pix stack
+- allow file rwlkm /{**,},
+- allow network,
+- allow unix,
+- allow ptrace,
+- allow signal,
+- allow mqueue,
+- allow io_uring,
+- allow userns,
+- allow mount,
+- allow umount,
+- allow pivot_root,
+- allow dbus,
+-
+- # Maintain the stack against itself for further transitions
+- # If done recursively the stack will remove any duplicate
+- allow pix /** -> &unpriv_unshare,
+-
+- audit deny capability,
+-
+- # the local include should not be used without understanding the userns
+- # restriction.
+- # Site-specific additions and overrides. See local/README for details.
+- include if exists <local/unpriv_unshare>
+-}
+diff --git a/profiles/apparmor.d/unshare-userns-restrict b/profiles/apparmor.d/unshare-userns-restrict
+new file mode 100644
+index 000000000..731f18b9c
+--- /dev/null
++++ b/profiles/apparmor.d/unshare-userns-restrict
+@@ -0,0 +1,75 @@
++# This profile allows almost everything and only exists to allow
++# unshare to work on a system with user namespace restrictions
++# being enforced.
++# unshare is allowed access to user namespaces and capabilities
++# within the user namespace, but its children do not have
++# capabilities, blocking unshare from being able to be used to
++# arbitrarily by-pass the user namespace restrictions.
++# We restrict x mapping of any code that is unknown while unshare
++# has privilige within the namespace. To help ensure unshare can't
++# be used to attack the kernel.
++#
++# disabled by default as it can break some use cases on a system that
++# doesn't have or has disable user namespace restrictions for unconfined
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile unshare /usr/bin/unshare flags=(attach_disconnected mediate_deleted) {
++ # not allow all, to allow for pix stack on systems that don't support
++ # rule priority.
++ #
++ # sadly we have to allow 'm' every where to allow children to work under
++ # profile stacking atm.
++ allow capability,
++ allow file rwmlk /{**,},
++ allow network,
++ allow unix,
++ allow ptrace,
++ allow signal,
++ allow mqueue,
++ allow io_uring,
++ allow userns,
++ allow mount,
++ allow umount,
++ allow pivot_root,
++ allow dbus,
++ # This will stack a target profile against unpriv_unshare
++ # Most of the comments for the pix transition in bwrap-userns-restrict
++ # also apply here, with the exception of unshare not using no-new-privs
++ # Thus, we only need a two-layer stack instead of a three-layer stack
++ audit allow pix /** -> &unpriv_unshare,
++
++ # the local include should not be used without understanding the userns
++ # restriction.
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/unshare-userns-restrict>
++}
++
++profile unpriv_unshare flags=(attach_disconnected mediate_deleted) {
++ # not allow all, to allow for pix stack
++ allow file rwlkm /{**,},
++ allow network,
++ allow unix,
++ allow ptrace,
++ allow signal,
++ allow mqueue,
++ allow io_uring,
++ allow userns,
++ allow mount,
++ allow umount,
++ allow pivot_root,
++ allow dbus,
++
++ # Maintain the stack against itself for further transitions
++ # If done recursively the stack will remove any duplicate
++ allow pix /** -> &unpriv_unshare,
++
++ audit deny capability,
++
++ # the local include should not be used without understanding the userns
++ # restriction.
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/unpriv_unshare>
++}
+--
+2.43.0
+
diff --git a/debian/patches/ubuntu/alsamixer_mr_1517.patch b/debian/patches/ubuntu/alsamixer_mr_1517.patch
new file mode 100644
index 0000000..3523b64
--- /dev/null
+++ b/debian/patches/ubuntu/alsamixer_mr_1517.patch
@@ -0,0 +1,67 @@
+From 49babf1d17260c1a8a63963658d0351eb6672322 Mon Sep 17 00:00:00 2001
+From: Ryan Lee <ryan.lee at canonical.com>
+Date: Fri, 31 Jan 2025 17:20:31 -0800
+Subject: [PATCH] Add an Alsamixer profile
+
+Signed-off-by: Ryan Lee <ryan.lee at canonical.com>
+---
+ profiles/apparmor.d/alsamixer | 47 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 47 insertions(+)
+ create mode 100644 profiles/apparmor.d/alsamixer
+
+diff --git a/profiles/apparmor.d/alsamixer b/profiles/apparmor.d/alsamixer
+new file mode 100644
+index 000000000..24ac4e610
+--- /dev/null
++++ b/profiles/apparmor.d/alsamixer
+@@ -0,0 +1,47 @@
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile alsamixer /{usr,}/bin/alsamixer {
++ include <abstractions/base>
++ include <abstractions/consoles>
++ include <abstractions/nameservice-strict>
++ include <abstractions/dbus-session-strict>
++
++ /usr/share/terminfo/** r,
++
++ @{sys}/devices/virtual/dmi/id/sys_vendor r,
++
++ @{PROC}/@{pid}/task/@{tid}/comm rw,
++
++ # pipewire configs
++ /usr/share/pipewire/*.conf r,
++ # pulseaudio configs
++ @{etc_ro}/pulse/*.conf r,
++ @{etc_ro}/pulse/*.conf.d/ r,
++ @{etc_ro}/pulse/*.conf.d/*.conf r,
++ # alsa configs
++ /usr/share/alsa/*.conf r,
++ /usr/share/alsa/**/*.conf r,
++ @{etc_ro}/alsa/conf.d/ r,
++ @{etc_ro}/alsa/conf.d/*.conf r,
++ # alsa info files
++ @{PROC}/asound/** r,
++
++ # openSUSE-Leap 15.6 version needs to ls /dev/shm for some reason
++ /dev/shm/ r,
++ # /dev/snd devices
++ /dev/snd/controlC[0-9]* rw,
++ # Folders contain symlinks to device files in /dev/snd
++ /dev/snd/by-id/ r,
++ /dev/snd/by-path/ r,
++
++ # PulseAudio communication channels
++ owner @{HOME}/.config/pulse/cookie rk,
++ owner /run/user/@{uid}/pulse/ r,
++
++ # Pipewire communication channels
++ owner /run/user/@{uid}/pipewire-[0-9] rw,
++
++ include if exists <local/alsamixer>
++}
+--
+2.43.0
+
diff --git a/debian/patches/ubuntu/delete-the-busybox-and-nautilus-profiles.patch b/debian/patches/ubuntu/delete-the-busybox-and-nautilus-profiles.patch
new file mode 100644
index 0000000..7c9ed2a
--- /dev/null
+++ b/debian/patches/ubuntu/delete-the-busybox-and-nautilus-profiles.patch
@@ -0,0 +1,57 @@
+From 26f2b3bb491cd6dc080960a0e5c465bd7c244fef Mon Sep 17 00:00:00 2001
+From: Ryan Lee <ryan.lee at canonical.com>
+Date: Wed, 12 Feb 2025 09:42:55 -0800
+Subject: [PATCH] delete the busybox and nautilus profiles
+
+Both those profiles are for programs that are installed by default and
+that provide or open a shell (which can then be used to perform arbitrary
+actions, thus providing a bypass for the unprivileged usernamespace
+restrictions.
+
+Signed-off-by: Ryan Lee <ryan.lee at canonical.com>
+---
+ profiles/apparmor.d/busybox | 12 ------------
+ profiles/apparmor.d/nautilus | 12 ------------
+ 2 files changed, 24 deletions(-)
+ delete mode 100644 profiles/apparmor.d/busybox
+ delete mode 100644 profiles/apparmor.d/nautilus
+
+diff --git a/profiles/apparmor.d/busybox b/profiles/apparmor.d/busybox
+deleted file mode 100644
+index d726ddf0a..000000000
+--- a/profiles/apparmor.d/busybox
++++ /dev/null
+@@ -1,12 +0,0 @@
+-# This profile allows everything and only exists to give the
+-# application a name instead of having the label "unconfined"
+-
+-abi <abi/4.0>,
+-include <tunables/global>
+-
+-profile busybox /usr/bin/busybox flags=(unconfined) {
+- userns,
+-
+- # Site-specific additions and overrides. See local/README for details.
+- include if exists <local/busybox>
+-}
+diff --git a/profiles/apparmor.d/nautilus b/profiles/apparmor.d/nautilus
+deleted file mode 100644
+index d4031a0ea..000000000
+--- a/profiles/apparmor.d/nautilus
++++ /dev/null
+@@ -1,12 +0,0 @@
+-# This profile allows everything and only exists to give the
+-# application a name instead of having the label "unconfined"
+-
+-abi <abi/4.0>,
+-include <tunables/global>
+-
+-profile nautilus /usr/bin/nautilus flags=(unconfined) {
+- userns,
+-
+- # Site-specific additions and overrides. See local/README for details.
+- include if exists <local/nautilus>
+-}
+--
+2.43.0
+
diff --git a/debian/patches/ubuntu/dnstracer_mr_1366.patch b/debian/patches/ubuntu/dnstracer_mr_1366.patch
new file mode 100644
index 0000000..5aef3c2
--- /dev/null
+++ b/debian/patches/ubuntu/dnstracer_mr_1366.patch
@@ -0,0 +1,42 @@
+Author: vyomydv <vyom.yadav at canonical.com>
+MR Link: https://gitlab.com/apparmor/apparmor/-/merge_requests/1366
+Subject: Add dnstracer profile
+
+diff --git a/profiles/apparmor.d/dnstracer b/profiles/apparmor.d/dnstracer
+new file mode 100644
+index 0000000000000000000000000000000000000000..a5078cbc7ff26d074676b1b8aa0a6c63b23e79a1
+--- /dev/null
++++ b/profiles/apparmor.d/dnstracer
+@@ -0,0 +1,32 @@
++#------------------------------------------------------------------
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#------------------------------------------------------------------
++# vim: ft=apparmor
++#
++abi <abi/4.0>,
++
++include <tunables/global>
++profile dnstracer /usr/bin/dnstracer {
++ include <abstractions/base>
++ include <abstractions/nameservice-strict>
++
++ network (bind,connect,create,receive,send,setopt) inet dgram,
++ network (bind,connect,create,receive,send,setopt) inet6 dgram,
++
++ /usr/bin/dnstracer mr,
++
++ @{run}/.nscd_socket rw,
++ @{run}/nscd/socket rw,
++
++ # nss can be configured to use libvirt in host resolution
++ /var/lib/libvirt/dnsmasq/ r,
++ /var/lib/libvirt/dnsmasq/*.status r,
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/dnstracer>
++}
++
diff --git a/debian/patches/ubuntu/fix-abi-break-record-for-aa-log-record.patch b/debian/patches/ubuntu/fix-abi-break-record-for-aa-log-record.patch
deleted file mode 100644
index ccb8433..0000000
--- a/debian/patches/ubuntu/fix-abi-break-record-for-aa-log-record.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From c86c87e8868c72e5ab2084b5bf783cd5ca800a9b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Maxime=20B=C3=A9lair?= <maxime.belair at canonical.com>
-Date: Tue, 1 Oct 2024 22:06:45 +0000
-Subject: [PATCH] Fix ABI break for aa_log_record
-
----
- libraries/libapparmor/include/aalogparse.h | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
-diff --git a/libraries/libapparmor/include/aalogparse.h b/libraries/libapparmor/include/aalogparse.h
-index ced77ab47..23e292233 100644
---- a/libraries/libapparmor/include/aalogparse.h
-+++ b/libraries/libapparmor/include/aalogparse.h
-@@ -86,8 +86,6 @@ typedef struct
- char *net_foreign_addr;
- unsigned long net_foreign_port;
-
-- char *execpath;
--
- char *dbus_bus;
- char *dbus_path;
- char *dbus_interface;
-@@ -104,6 +102,7 @@ typedef struct
-
- char *net_addr;
- char *peer_addr;
-+ char *execpath;
- } aa_log_record;
-
- /**
---
-GitLab
-
diff --git a/debian/patches/ubuntu/frr_mr_1380.patch b/debian/patches/ubuntu/frr_mr_1380.patch
new file mode 100644
index 0000000..796a273
--- /dev/null
+++ b/debian/patches/ubuntu/frr_mr_1380.patch
@@ -0,0 +1,681 @@
+Author: Jorge Sancho Larraz <jorge.sancho.larraz at canonical.com>
+MR link: https://gitlab.com/apparmor/apparmor/-/merge_requests/1380
+Subject: profiles: add frr related profiles
+
+diff --git a/profiles/apparmor.d/abstractions/frr b/profiles/apparmor.d/abstractions/frr
+new file mode 100644
+index 0000000000000000000000000000000000000000..d456dad34729df44d3754b25d7f12139ac60021f
+--- /dev/null
++++ b/profiles/apparmor.d/abstractions/frr
+@@ -0,0 +1,56 @@
++# vim:syntax=apparmor
++# LOGPROF-SUGGEST: no
++# ------------------------------------------------------------------
++#
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#
++# ------------------------------------------------------------------
++
++ abi <abi/4.0>,
++
++ include <abstractions/nameservice-strict>
++
++ # Common capabilities
++ network,
++ capability net_bind_service,
++ capability chown,
++ capability setgid,
++ capability setuid,
++ capability dac_override,
++ capability dac_read_search,
++
++ / r,
++ @{run}/frr/ r,
++ @{run}/frr/zserv.api rw,
++ @{run}/frr/@{profile_name}.pid rwk,
++ @{run}/frr/@{profile_name}.vty rw,
++
++ # YANG modules
++ /usr/share/yang/ r,
++ /usr/share/yang/modules/ r,
++ /usr/share/yang/modules/libyang/ r,
++ /usr/share/yang/modules/libyang/** r,
++
++ # MGMT Backend Server https://docs.frrouting.org/en/latest/mgmtd.html#mgmtd-backend-interface
++ @{run}/frr/mgmtd_be.sock rw,
++
++ # Daemon config https://docs.frrouting.org/en/latest/basic.html
++ /etc/frr/ r,
++ /etc/frr/@{profile_name}.conf rw,
++ /etc/frr/frr.conf rw,
++
++ # Log file https://docs.frrouting.org/en/latest/basic.html
++ /var/log/frr/ w,
++ /var/log/frr/* w,
++
++ # Crash logs https://docs.frrouting.org/en/latest/setup.html#crash-logs
++ /var/tmp/frr/ w,
++ owner /var/tmp/frr/@{profile_name}.@{pid}/ w,
++ owner /var/tmp/frr/@{profile_name}.@{pid}/crashlog w,
++ owner /var/tmp/frr/@{profile_name}.@{pid}/logbuf.@{tid} rw,
++
++ include if exists <abstractions/frr.d>
+diff --git a/profiles/apparmor.d/abstractions/frr-snmp b/profiles/apparmor.d/abstractions/frr-snmp
+new file mode 100644
+index 0000000000000000000000000000000000000000..4a44af1e511ff8fdfb44c0f0a6c7e03822581d94
+--- /dev/null
++++ b/profiles/apparmor.d/abstractions/frr-snmp
+@@ -0,0 +1,26 @@
++# vim:syntax=apparmor
++# LOGPROF-SUGGEST: no
++# ------------------------------------------------------------------
++#
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#
++# ------------------------------------------------------------------
++
++ abi <abi/4.0>,
++
++ include <abstractions/openssl>
++
++ /etc/snmp/frr.conf r,
++ /etc/snmp/snmp.conf r,
++ /usr/share/snmp/mibs/{,*} r,
++ /var/lib/mibs/iana/{,*} r,
++ /var/lib/mibs/ietf/{,*} r,
++ /etc/host.conf r,
++ /etc/hosts r,
++ /etc/frr/agentx rw,
++
++ include if exists <abstractions/frr-snmp.d>
+diff --git a/profiles/apparmor.d/babeld b/profiles/apparmor.d/babeld
+new file mode 100644
+index 0000000000000000000000000000000000000000..25068d57bf4b092b529125edcb794ef59ae72ca5
+--- /dev/null
++++ b/profiles/apparmor.d/babeld
+@@ -0,0 +1,24 @@
++# vim:syntax=apparmor
++# ------------------------------------------------------------------
++#
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#
++# ------------------------------------------------------------------
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile babeld /usr/lib/frr/babeld flags=(attach_disconnected) {
++ include <abstractions/base>
++ include <abstractions/frr>
++
++ @{run}/frr/babel-state w,
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/babeld>
++}
+diff --git a/profiles/apparmor.d/bfdd b/profiles/apparmor.d/bfdd
+new file mode 100644
+index 0000000000000000000000000000000000000000..83d2369e062aa7c40736e844a6119818c1ac26ce
+--- /dev/null
++++ b/profiles/apparmor.d/bfdd
+@@ -0,0 +1,29 @@
++# vim:syntax=apparmor
++# ------------------------------------------------------------------
++#
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#
++# ------------------------------------------------------------------
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile bfdd /usr/lib/frr/bfdd flags=(attach_disconnected) {
++ include <abstractions/base>
++ include <abstractions/frr>
++
++ capability net_raw,
++ capability sys_admin,
++
++ @{run}/netns/* r,
++
++ @{run}/frr/bfdd.sock w,
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/bfdd>
++}
+diff --git a/profiles/apparmor.d/bgpd b/profiles/apparmor.d/bgpd
+new file mode 100644
+index 0000000000000000000000000000000000000000..06fdc041bde6e7c98c9a0d0329265fcb25d50863
+--- /dev/null
++++ b/profiles/apparmor.d/bgpd
+@@ -0,0 +1,30 @@
++# vim:syntax=apparmor
++# ------------------------------------------------------------------
++#
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#
++# ------------------------------------------------------------------
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile bgpd /usr/lib/frr/bgpd flags=(attach_disconnected) {
++ include <abstractions/base>
++ include <abstractions/frr>
++ include <abstractions/frr-snmp>
++
++ capability net_raw,
++ capability sys_admin,
++
++ @{run}/netns/* r,
++
++ owner @{PROC}/@{pid}/task/@{tid}/comm rw,
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/bgpd>
++}
+diff --git a/profiles/apparmor.d/eigrpd b/profiles/apparmor.d/eigrpd
+new file mode 100644
+index 0000000000000000000000000000000000000000..083db5352fca022f20a8115e571611f34aa9478f
+--- /dev/null
++++ b/profiles/apparmor.d/eigrpd
+@@ -0,0 +1,24 @@
++# vim:syntax=apparmor
++# ------------------------------------------------------------------
++#
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#
++# ------------------------------------------------------------------
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile eigrpd /usr/lib/frr/eigrpd flags=(attach_disconnected) {
++ include <abstractions/base>
++ include <abstractions/frr>
++
++ capability net_raw,
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/eigrpd>
++}
+diff --git a/profiles/apparmor.d/fabricd b/profiles/apparmor.d/fabricd
+new file mode 100644
+index 0000000000000000000000000000000000000000..4779a2aa1e8c4b7e16931a582af7127106d47d56
+--- /dev/null
++++ b/profiles/apparmor.d/fabricd
+@@ -0,0 +1,22 @@
++# vim:syntax=apparmor
++# ------------------------------------------------------------------
++#
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#
++# ------------------------------------------------------------------
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile fabricd /usr/lib/frr/fabricd flags=(attach_disconnected) {
++ include <abstractions/base>
++ include <abstractions/frr>
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/fabricd>
++}
+diff --git a/profiles/apparmor.d/isisd b/profiles/apparmor.d/isisd
+new file mode 100644
+index 0000000000000000000000000000000000000000..3bb9b78fb9d83a6434450781b837a2d9a16961d2
+--- /dev/null
++++ b/profiles/apparmor.d/isisd
+@@ -0,0 +1,28 @@
++# vim:syntax=apparmor
++# ------------------------------------------------------------------
++#
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#
++# ------------------------------------------------------------------
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile isisd /usr/lib/frr/isisd flags=(attach_disconnected) {
++ include <abstractions/base>
++ include <abstractions/frr>
++ include <abstractions/frr-snmp>
++
++ capability net_raw,
++
++ /var/lib/frr/ r,
++ /var/lib/frr/isisd.json{,.sav} rw,
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/isisd>
++}
+diff --git a/profiles/apparmor.d/ldpd b/profiles/apparmor.d/ldpd
+new file mode 100644
+index 0000000000000000000000000000000000000000..5a6e61376e61a7196a7912cd4a81ab4ac9799555
+--- /dev/null
++++ b/profiles/apparmor.d/ldpd
+@@ -0,0 +1,26 @@
++# vim:syntax=apparmor
++# ------------------------------------------------------------------
++#
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#
++# ------------------------------------------------------------------
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile ldpd /usr/lib/frr/ldpd flags=(attach_disconnected) {
++ include <abstractions/base>
++ include <abstractions/frr>
++ include <abstractions/frr-snmp>
++
++ /usr/lib/frr/ldpd ix,
++ @{run}/frr/ldpd.sock rw,
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/ldpd>
++}
+diff --git a/profiles/apparmor.d/nhrpd b/profiles/apparmor.d/nhrpd
+new file mode 100644
+index 0000000000000000000000000000000000000000..d986139adf8d18706478589225e70726eeef640f
+--- /dev/null
++++ b/profiles/apparmor.d/nhrpd
+@@ -0,0 +1,29 @@
++# vim:syntax=apparmor
++# ------------------------------------------------------------------
++#
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#
++# ------------------------------------------------------------------
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile nhrpd /usr/lib/frr/nhrpd flags=(attach_disconnected) {
++ include <abstractions/base>
++ include <abstractions/frr>
++
++ capability net_raw,
++ capability net_admin,
++
++ /usr/bin/dash ix,
++ @{PROC}/sys/net/ipv4/conf/*/send_redirects w,
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/nhrpd>
++}
++
+diff --git a/profiles/apparmor.d/ospf6d b/profiles/apparmor.d/ospf6d
+new file mode 100644
+index 0000000000000000000000000000000000000000..0f67380455705a79211f4eabcca56ec5ef9fdf3d
+--- /dev/null
++++ b/profiles/apparmor.d/ospf6d
+@@ -0,0 +1,33 @@
++# vim:syntax=apparmor
++# ------------------------------------------------------------------
++#
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#
++# ------------------------------------------------------------------
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile ospf6d /usr/lib/frr/ospf6d flags=(attach_disconnected) {
++ include <abstractions/base>
++ include <abstractions/frr>
++ include <abstractions/frr-snmp>
++
++ capability net_raw,
++ capability sys_admin,
++
++ @{run}/netns/* r,
++
++ @{run}/frr/ospf6d-gr.json w,
++
++ /var/lib/frr/ r,
++ /var/lib/frr/ospf6d.json{,.sav} rw,
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/ospf6d>
++}
+diff --git a/profiles/apparmor.d/ospfd b/profiles/apparmor.d/ospfd
+new file mode 100644
+index 0000000000000000000000000000000000000000..91262f459d22a2f029e8139aadd7729d9d2ccdc5
+--- /dev/null
++++ b/profiles/apparmor.d/ospfd
+@@ -0,0 +1,42 @@
++# vim:syntax=apparmor
++# ------------------------------------------------------------------
++#
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#
++# ------------------------------------------------------------------
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile ospfd /usr/lib/frr/ospfd flags=(attach_disconnected) {
++ include <abstractions/base>
++ include <abstractions/frr>
++ include <abstractions/frr-snmp>
++
++ capability net_raw,
++ capability sys_admin,
++
++ @{run}/netns/* r,
++
++ @{run}/frr/ospfd-gr.json w,
++
++ /var/lib/frr/ r,
++ /var/lib/frr/ospfd.json{,.sav} rw,
++
++ # For OSPFv3
++ owner /var/tmp/frr/ospfd-3.@{pid}/ w,
++ owner /var/tmp/frr/ospfd-3.@{pid}/crashlog w,
++ owner /var/tmp/frr/ospfd-3.@{pid}/logbuf.@{tid} rw,
++
++ @{run}/frr/ospfd-3.pid rwk,
++ @{run}/frr/ospfd-3.vty rw,
++ @{run}/frr/ospfd-3.json{,.sav} rw,
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/ospfd>
++}
+diff --git a/profiles/apparmor.d/pathd b/profiles/apparmor.d/pathd
+new file mode 100644
+index 0000000000000000000000000000000000000000..a636179a83dda3c4bb8e1445f49931ff08ce4e63
+--- /dev/null
++++ b/profiles/apparmor.d/pathd
+@@ -0,0 +1,22 @@
++# vim:syntax=apparmor
++# ------------------------------------------------------------------
++#
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#
++# ------------------------------------------------------------------
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile pathd /usr/lib/frr/pathd flags=(attach_disconnected) {
++ include <abstractions/base>
++ include <abstractions/frr>
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/pathd>
++}
+diff --git a/profiles/apparmor.d/pbrd b/profiles/apparmor.d/pbrd
+new file mode 100644
+index 0000000000000000000000000000000000000000..7d3b7ec6d5d2c07aac84ef9e225f14bec1a59421
+--- /dev/null
++++ b/profiles/apparmor.d/pbrd
+@@ -0,0 +1,22 @@
++# vim:syntax=apparmor
++# ------------------------------------------------------------------
++#
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#
++# ------------------------------------------------------------------
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile pbrd /usr/lib/frr/pbrd flags=(attach_disconnected) {
++ include <abstractions/base>
++ include <abstractions/frr>
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/pbrd>
++}
+diff --git a/profiles/apparmor.d/pim6d b/profiles/apparmor.d/pim6d
+new file mode 100644
+index 0000000000000000000000000000000000000000..373da03d09600e0479c2f97623ce0a76fb42bfaa
+--- /dev/null
++++ b/profiles/apparmor.d/pim6d
+@@ -0,0 +1,25 @@
++# vim:syntax=apparmor
++# ------------------------------------------------------------------
++#
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#
++# ------------------------------------------------------------------
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile pim6d /usr/lib/frr/pim6d flags=(attach_disconnected) {
++ include <abstractions/base>
++ include <abstractions/frr>
++
++ capability net_raw,
++ capability net_admin,
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/pim6d>
++}
+diff --git a/profiles/apparmor.d/pimd b/profiles/apparmor.d/pimd
+new file mode 100644
+index 0000000000000000000000000000000000000000..1ca7e626916d4edb3fd5a785115f0ddc90614f3d
+--- /dev/null
++++ b/profiles/apparmor.d/pimd
+@@ -0,0 +1,25 @@
++# vim:syntax=apparmor
++# ------------------------------------------------------------------
++#
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#
++# ------------------------------------------------------------------
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile pimd /usr/lib/frr/pimd flags=(attach_disconnected) {
++ include <abstractions/base>
++ include <abstractions/frr>
++
++ capability net_raw,
++ capability net_admin,
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/pimd>
++}
+diff --git a/profiles/apparmor.d/ripd b/profiles/apparmor.d/ripd
+new file mode 100644
+index 0000000000000000000000000000000000000000..d41e58d0c4616f8733d6b54c948d32869832ef28
+--- /dev/null
++++ b/profiles/apparmor.d/ripd
+@@ -0,0 +1,23 @@
++# vim:syntax=apparmor
++# ------------------------------------------------------------------
++#
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#
++# ------------------------------------------------------------------
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile ripd /usr/lib/frr/ripd flags=(attach_disconnected) {
++ include <abstractions/base>
++ include <abstractions/frr>
++ include <abstractions/frr-snmp>
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/ripd>
++}
+diff --git a/profiles/apparmor.d/ripngd b/profiles/apparmor.d/ripngd
+new file mode 100644
+index 0000000000000000000000000000000000000000..ea6bfa8668bb427d33e5a6c3b129d91e1750282a
+--- /dev/null
++++ b/profiles/apparmor.d/ripngd
+@@ -0,0 +1,22 @@
++# vim:syntax=apparmor
++# ------------------------------------------------------------------
++#
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#
++# ------------------------------------------------------------------
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile ripngd /usr/lib/frr/ripngd flags=(attach_disconnected) {
++ include <abstractions/base>
++ include <abstractions/frr>
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/ripngd>
++}
+diff --git a/profiles/apparmor.d/staticd b/profiles/apparmor.d/staticd
+new file mode 100644
+index 0000000000000000000000000000000000000000..61f3e1dbff13dc1a069be0c7308a04d00d421776
+--- /dev/null
++++ b/profiles/apparmor.d/staticd
+@@ -0,0 +1,27 @@
++# vim:syntax=apparmor
++# ------------------------------------------------------------------
++#
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#
++# ------------------------------------------------------------------
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile staticd /usr/lib/frr/staticd flags=(attach_disconnected) {
++ include <abstractions/base>
++ include <abstractions/frr>
++
++ /etc/frr/zebra.conf r,
++
++ owner @{PROC}/@{pid}/task/@{tid}/comm rw,
++ @{PROC}/sys/net/core/somaxconn r,
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/staticd>
++}
+diff --git a/profiles/apparmor.d/vrrpd b/profiles/apparmor.d/vrrpd
+new file mode 100644
+index 0000000000000000000000000000000000000000..bc6c1734cbc44de58a4c8f37f308d6572e7d354a
+--- /dev/null
++++ b/profiles/apparmor.d/vrrpd
+@@ -0,0 +1,22 @@
++# vim:syntax=apparmor
++# ------------------------------------------------------------------
++#
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#
++# ------------------------------------------------------------------
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile vrrpd /usr/lib/frr/vrrpd flags=(attach_disconnected) {
++ include <abstractions/base>
++ include <abstractions/frr>
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/vrrpd>
++}
diff --git a/debian/patches/ubuntu/fusermount3_mr_1514.patch b/debian/patches/ubuntu/fusermount3_mr_1514.patch
new file mode 100644
index 0000000..4fc83a5
--- /dev/null
+++ b/debian/patches/ubuntu/fusermount3_mr_1514.patch
@@ -0,0 +1,44 @@
+Author: Julia Sarris <julia.sarris at canonical.com>
+MR Link: https://gitlab.com/apparmor/apparmor/-/merge_requests/1514
+Subject: initial fusermount3 profile
+
+diff --git a/profiles/apparmor.d/fusermount3 b/profiles/apparmor.d/fusermount3
+new file mode 100644
+index 0000000000000000000000000000000000000000..d12cc00c29c68314c87177070fe9134928b90265
+--- /dev/null
++++ b/profiles/apparmor.d/fusermount3
+@@ -0,0 +1,34 @@
++abi <abi/4.0>,
++include <tunables/global>
++
++@{fuse_types} = {fuse,fuse.*,fuseblk,fusectl}
++profile fusermount3 /usr/bin/fusermount3 {
++ include <abstractions/base>
++ include <abstractions/nameservice-strict>
++
++ capability sys_admin,
++ capability dac_read_search,
++
++ mount fstype=@{fuse_types} options=(nosuid,nodev,rw) -> @{HOME}/**/,
++ mount fstype=@{fuse_types} options=(nosuid,nodev,rw) -> /mnt/{,**/},
++ mount fstype=@{fuse_types} options=(nosuid,nodev,rw) -> @{run}/user/@{uid}/*/,
++ mount fstype=@{fuse_types} options=(nosuid,nodev,rw) -> /media/**/,
++ mount fstype=@{fuse_types} options=(nosuid,nodev,rw) -> /tmp/**/,
++
++ umount @{HOME}/**/,
++ umount /mnt/{,**/},
++ umount @{run}/user/@{uid}/*/,
++ umount /media/**/,
++ umount /tmp/**/,
++
++ /dev/fuse rw,
++
++ @{etc_ro}/fuse.conf r,
++ @{PROC}/@{pid}/mounts r,
++
++ /usr/bin/fusermount3 mr,
++
++ include if exists <local/fusermount3>
++}
++
++# vim:syntax=apparmor
diff --git a/debian/patches/ubuntu/fusermount3_profile_fixup.patch b/debian/patches/ubuntu/fusermount3_profile_fixup.patch
new file mode 100644
index 0000000..ab9f857
--- /dev/null
+++ b/debian/patches/ubuntu/fusermount3_profile_fixup.patch
@@ -0,0 +1,40 @@
+From a20409cf1e3c63386f56394d2b346cdfe40cde2f Mon Sep 17 00:00:00 2001
+From: Ryan Lee <ryan.lee at canonical.com>
+Date: Thu, 20 Feb 2025 09:42:32 -0800
+Subject: [PATCH] profiles: allow ro mounts in fusermount3 profile
+
+These are needed by e.g. AppImages
+
+Closes: https://bugs.launchpad.net/bugs/2098993
+Signed-off-by: Ryan Lee <ryan.lee at canonical.com>
+---
+ profiles/apparmor.d/fusermount3 | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/profiles/apparmor.d/fusermount3 b/profiles/apparmor.d/fusermount3
+index d12cc00c2..c9d2bfca9 100644
+--- a/profiles/apparmor.d/fusermount3
++++ b/profiles/apparmor.d/fusermount3
+@@ -9,12 +9,19 @@ profile fusermount3 /usr/bin/fusermount3 {
+ capability sys_admin,
+ capability dac_read_search,
+
++ # Allow both rw and ro type mounts (e.g. AppImage uses ro)
+ mount fstype=@{fuse_types} options=(nosuid,nodev,rw) -> @{HOME}/**/,
+ mount fstype=@{fuse_types} options=(nosuid,nodev,rw) -> /mnt/{,**/},
+ mount fstype=@{fuse_types} options=(nosuid,nodev,rw) -> @{run}/user/@{uid}/*/,
+ mount fstype=@{fuse_types} options=(nosuid,nodev,rw) -> /media/**/,
+ mount fstype=@{fuse_types} options=(nosuid,nodev,rw) -> /tmp/**/,
+
++ mount fstype=@{fuse_types} options=(nosuid,nodev,ro) -> @{HOME}/**/,
++ mount fstype=@{fuse_types} options=(nosuid,nodev,ro) -> /mnt/{,**/},
++ mount fstype=@{fuse_types} options=(nosuid,nodev,ro) -> @{run}/user/@{uid}/*/,
++ mount fstype=@{fuse_types} options=(nosuid,nodev,ro) -> /media/**/,
++ mount fstype=@{fuse_types} options=(nosuid,nodev,ro) -> /tmp/**/,
++
+ umount @{HOME}/**/,
+ umount /mnt/{,**/},
+ umount @{run}/user/@{uid}/*/,
+--
+GitLab
+
diff --git a/debian/patches/ubuntu/iotop_c_mr_1520.patch b/debian/patches/ubuntu/iotop_c_mr_1520.patch
new file mode 100644
index 0000000..37693d0
--- /dev/null
+++ b/debian/patches/ubuntu/iotop_c_mr_1520.patch
@@ -0,0 +1,32 @@
+Author: Allen Huang <allen.huang at canonical.com>
+MR link: https://gitlab.com/apparmor/apparmor/-/merge_requests/1520
+Subject: Initial profile for iotop-c
+
+diff --git a/profiles/apparmor.d/iotop-c b/profiles/apparmor.d/iotop-c
+new file mode 100644
+index 0000000000000000000000000000000000000000..fc473e7ceb4bfe90b1638e1c3f1cbadede0adc38
+--- /dev/null
++++ b/profiles/apparmor.d/iotop-c
+@@ -0,0 +1,22 @@
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile iotop-c /usr/sbin/iotop-c {
++ include <abstractions/base>
++ include <abstractions/bash>
++ include <abstractions/nameservice-strict>
++
++ capability net_admin,
++ capability sys_admin,
++
++ /proc/*/cmdline r,
++ /proc/*/task/ r,
++ /usr/sbin/iotop-c mr,
++ /proc/ r,
++ /proc/sys/kernel/task_delayacct rw,
++ /proc/vmstat r,
++ owner @{HOME}/.config/iotop/iotoprc rw,
++
++ include if exists <local/iotop-c>
++}
diff --git a/debian/patches/ubuntu/irssi_mr_1332.patch b/debian/patches/ubuntu/irssi_mr_1332.patch
new file mode 100644
index 0000000..4d6edf4
--- /dev/null
+++ b/debian/patches/ubuntu/irssi_mr_1332.patch
@@ -0,0 +1,65 @@
+From a9d50600056899ed8c84964c7f226b11325c2c74 Mon Sep 17 00:00:00 2001
+From: "Leonidas S. Barbosa" <leo.barbosa at canonical.com>
+Date: Fri, 24 Jan 2025 16:48:35 -0300
+Subject: [PATCH] Adding irssi profile
+
+---
+ profiles/apparmor.d/irssi | 46 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 46 insertions(+)
+ create mode 100644 profiles/apparmor.d/irssi
+
+diff --git a/profiles/apparmor.d/irssi b/profiles/apparmor.d/irssi
+new file mode 100644
+index 000000000..78754f099
+--- /dev/null
++++ b/profiles/apparmor.d/irssi
+@@ -0,0 +1,46 @@
++#------------------------------------------------------------------
++# Copyright (C) 2024 Canonical Ltd.
++#
++# Author: Leonidas S. Barbosa (leosilva)
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++
++abi <abi/4.0>,
++
++#include <tunables/global>
++
++
++profile irssi /usr/bin/irssi {
++ #include <abstractions/base>
++ #include <abstractions/nameservice>
++ #include <abstractions/aspell>
++ #include <abstractions/bash>
++ #include <abstractions/perl>
++ #include <abstractions/python>
++ #include <abstractions/ssl_certs>
++
++ /usr/bin/irssi mr,
++
++ # Allow connections TCP/IP IPV4 and IPV6.
++ network stream,
++
++ # Allow system/global irssi config.
++ file r @{etc_ro}/irssi.conf,
++
++ # Allow access to help, scripts and themes.
++ /usr/share/irssi/** r,
++ /usr/share/terminfo/** r,
++
++ # Allow irssi use /exec command but inherit current confinement
++ /bin/dash ix,
++
++ # Allow log creation, and other specific things like access default.theme
++ owner @{HOME}/.irssi/** rwk,
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/irssi>
++
++}
++
+--
+GitLab
+
diff --git a/debian/patches/ubuntu/libapparmor-make-af_protos.h-consistent-in-different.patch b/debian/patches/ubuntu/libapparmor-make-af_protos.h-consistent-in-different.patch
deleted file mode 100644
index ac6be02..0000000
--- a/debian/patches/ubuntu/libapparmor-make-af_protos.h-consistent-in-different.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-Patch taken from upstream https://gitlab.com/apparmor/apparmor/-/merge_requests/1309
-and edited slightly to add the | prefix in the test case failure diff in the
-commit message to avoid confusing quilt.
-
-From 95c419dc45aa777196a613d41ea72ebca3a679ac Mon Sep 17 00:00:00 2001
-From: Georgia Garcia <georgia.garcia at canonical.com>
-Date: Mon, 19 Aug 2024 18:09:17 -0300
-Subject: [PATCH] libapparmor: make af_protos.h consistent in different archs
-
-af_protos.h is a generated table of the protocols created by looking
-for definitions of IPPROTO_* in netinet/in.h. Depending on the
-architecture, the order of the table may change when using -dM in the
-compiler during the extraction of the defines.
-
-This causes an issue because there is more than one IPPROTO defined
-by the value 0: IPPROTO_IP and IPPROTO_HOPOPTS which is a header
-extension used by IPv6. So if IPPROTO_HOPOPTS was first in the table,
-then protocol=0 in the audit logs would be translated to hopopts.
-
-This caused a failure in arm 32bit:
-
-|Output doesn't match expected data:
-|--- ./test_multi/testcase_unix_01.out 2024-08-15 01:47:53.000000000 +0000
-|+++ ./test_multi/out/testcase_unix_01.out 2024-08-15 23:42:10.187416392 +0000
-|@@ -12,7 +12,7 @@
-| Peer Addr: @test_abstract_socket
-| Network family: unix
-| Socket type: stream
-|-Protocol: ip
-|+Protocol: hopopts
-| Class: net
-| Epoch: 1711454639
-| Audit subid: 322
-
-By the time protocol is resolved in grammar.y, we don't have have
-access to the net family to check if it's inet6. Instead of making
-protocol dependent on the net family, make the order of the
-af_protos.h table consistent between architectures using -dD.
-
-Signed-off-by: Georgia Garcia <georgia.garcia at canonical.com>
----
- libraries/libapparmor/src/Makefile.am | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/libraries/libapparmor/src/Makefile.am b/libraries/libapparmor/src/Makefile.am
-index 9a9d12e39..239fc7506 100644
---- a/libraries/libapparmor/src/Makefile.am
-+++ b/libraries/libapparmor/src/Makefile.am
-@@ -52,7 +52,7 @@ scanner.h: scanner.l
- scanner.c: scanner.l
-
- af_protos.h:
-- echo '#include <netinet/in.h>' | $(CC) $(CPPFLAGS) -E -dM - | LC_ALL=C sed -n -e "/IPPROTO_MAX/d" -e "s/^\#define[ \\t]\\+IPPROTO_\\([A-Z0-9_]\\+\\)\\(.*\\)$$/AA_GEN_PROTO_ENT(\\UIPPROTO_\\1, \"\\L\\1\")/p" > $@
-+ echo '#include <netinet/in.h>' | $(CC) $(CPPFLAGS) -E -dD - | LC_ALL=C sed -n -e "/IPPROTO_MAX/d" -e "s/^\#define[ \\t]\\+IPPROTO_\\([A-Z0-9_]\\+\\)\\(.*\\)$$/AA_GEN_PROTO_ENT(\\UIPPROTO_\\1, \"\\L\\1\")/p" > $@
-
- lib_LTLIBRARIES = libapparmor.la
- noinst_HEADERS = grammar.h parser.h scanner.h af_protos.h private.h PMurHash.h
---
-2.45.2
-
diff --git a/debian/patches/ubuntu/libapparmor-swig-perl-typemaps.patch b/debian/patches/ubuntu/libapparmor-swig-perl-typemaps.patch
new file mode 100644
index 0000000..cd0a8a0
--- /dev/null
+++ b/debian/patches/ubuntu/libapparmor-swig-perl-typemaps.patch
@@ -0,0 +1,57 @@
+From 5730fb6d2d97b316cdbf1f3c25f6ef072ac37bdf Mon Sep 17 00:00:00 2001
+From: Ryan Lee <ryan.lee at canonical.com>
+Date: Fri, 27 Sep 2024 09:03:57 -0700
+Subject: [PATCH] Perl typemap for const char* subprofiles[]
+
+This is the only language-dependent nontrivial portion of the SWIG
+bindings, and this should be good enough for anyone who is still using the
+Perl bindings now
+
+Signed-off-by: Ryan Lee <ryan.lee at canonical.com>
+---
+ libraries/libapparmor/swig/SWIG/libapparmor.i | 29 +++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+diff --git a/libraries/libapparmor/swig/SWIG/libapparmor.i b/libraries/libapparmor/swig/SWIG/libapparmor.i
+index 9c01b182b..b695a9ad1 100644
+--- a/libraries/libapparmor/swig/SWIG/libapparmor.i
++++ b/libraries/libapparmor/swig/SWIG/libapparmor.i
+@@ -278,6 +278,35 @@ extern int aa_is_enabled(void);
+ }
+ #endif
+
++#ifdef SWIGPERL
++// Copied from perl's argcargv.i, which should be good enough for us
++%typemap(in) (const char *subprofiles[]) {
++ int i;
++ SSize_t len;
++ AV *av = (AV *)SvRV($input);
++ if (SvTYPE(av) != SVt_PVAV) {
++ SWIG_croak("in method '$symname', Expecting reference to argv array");
++ goto fail;
++ }
++ len = av_len(av) + 1;
++ $1 = (char **) malloc((len+1)*sizeof(char *));
++ for (i = 0; i < len; i++) {
++ SV **tv = av_fetch(av, i, 0);
++ $1[i] = SvPV_nolen(*tv);
++ }
++ $1[i] = NULL;
++}
++
++%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (const char *subprofiles[]) {
++ AV *av = (AV *)SvRV($input);
++ $1 = SvTYPE(av) == SVt_PVAV;
++}
++
++%typemap(freearg) (const char *subprofiles[]) {
++ free((void *)$1);
++}
++#endif
++
+ /* These should not receive the VOID_Object typemap */
+ extern int aa_change_hat(const char *subprofile, unsigned long magic_token);
+ extern int aa_change_profile(const char *profile);
+--
+GitLab
+
diff --git a/debian/patches/ubuntu/lsblk_mr_1437.patch b/debian/patches/ubuntu/lsblk_mr_1437.patch
new file mode 100644
index 0000000..e279ae1
--- /dev/null
+++ b/debian/patches/ubuntu/lsblk_mr_1437.patch
@@ -0,0 +1,57 @@
+From 8cd72afa18df92b585b282f694c796ec27360d8e Mon Sep 17 00:00:00 2001
+From: Hlib Korzhynskyy <hlib.korzhynskyy at canonical.com>
+Date: Thu, 28 Nov 2024 15:37:48 -0330
+Subject: [PATCH] Add lsblk profile
+
+---
+ profiles/apparmor.d/lsblk | 38 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 38 insertions(+)
+ create mode 100644 profiles/apparmor.d/lsblk
+
+diff --git a/profiles/apparmor.d/lsblk b/profiles/apparmor.d/lsblk
+new file mode 100644
+index 000000000..6d803c7fb
+--- /dev/null
++++ b/profiles/apparmor.d/lsblk
+@@ -0,0 +1,38 @@
++#------------------------------------------------------------------
++# Copyright (C) 2024 Canonical Ltd.
++#
++# Author: Hlib Korzhynskyy <hlib.korzhynskyy at canonical.com>
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#------------------------------------------------------------------
++# vim: ft=apparmor
++#
++
++abi <abi/4.0>,
++include <tunables/global>
++
++profile lsblk /usr/bin/lsblk {
++ include <abstractions/base>
++ include <abstractions/consoles>
++ include <abstractions/nameservice-strict>
++
++ @{sys}/block/ r,
++ @{sys}/class/block/ r,
++ @{sys}/dev/block/ r,
++
++ @{sys}/devices/pci[0-9]*:[0-9]*/** r,
++ @{sys}/devices/virtual/** r,
++ @{sys}/devices/platform/** r,
++
++ /dev/sr[0-9]* rk,
++
++ @{run}/udev/data/** r,
++
++ @{run}/mount/** r,
++ @{PROC}/swaps r,
++ owner @{PROC}/@{pid}/mountinfo r,
++
++ include if exists <local/lsblk>
++}
+--
+2.43.0
+
diff --git a/debian/patches/ubuntu/lsusb_mr_1433.patch b/debian/patches/ubuntu/lsusb_mr_1433.patch
new file mode 100644
index 0000000..1c0898e
--- /dev/null
+++ b/debian/patches/ubuntu/lsusb_mr_1433.patch
@@ -0,0 +1,60 @@
+From e7b19f04920ffbfdbef6f955de3e61f97a7726a0 Mon Sep 17 00:00:00 2001
+From: Federico Quattrin <federico.quattrin at canonical.com>
+Date: Mon, 25 Nov 2024 17:47:18 -0300
+Subject: [PATCH] added lsusb profile
+
+Signed-off-by: Federico Quattrin <federico.quattrin at canonical.com>
+---
+ profiles/apparmor.d/lsusb | 40 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 40 insertions(+)
+ create mode 100644 profiles/apparmor.d/lsusb
+
+diff --git a/profiles/apparmor.d/lsusb b/profiles/apparmor.d/lsusb
+new file mode 100644
+index 000000000..cf7fca9d7
+--- /dev/null
++++ b/profiles/apparmor.d/lsusb
+@@ -0,0 +1,40 @@
++#------------------------------------------------------------------
++# Copyright (C) 2024 Canonical Ltd.
++#
++# Author: Federico Quattrin <federico.quattrin at canonical.com>
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#------------------------------------------------------------------
++# vim: ft=apparmor
++#
++
++abi <abi/4.0>,
++include <tunables/global>
++
++profile lsusb /usr/bin/lsusb {
++ include <abstractions/base>
++
++ network netlink raw,
++
++ /dev/ r,
++ /dev/bus/usb/ r,
++ @{run}/udev/data/*usb:* r,
++ @{run}/udev/data/c*:* r,
++
++ @{sys}/bus/ r,
++ @{sys}/bus/usb/devices/ r,
++ @{sys}/class/ r,
++
++ @{sys}/devices/pci[0-9]*:[0-9]*/**/usb[0-9]**/uevent r,
++ @{sys}/devices/pci[0-9]*:[0-9]*/**/usb[0-9]**/busnum r,
++ @{sys}/devices/pci[0-9]*:[0-9]*/**/usb[0-9]**/descriptors r,
++ @{sys}/devices/pci[0-9]*:[0-9]*/**/usb[0-9]**/devnum r,
++ @{sys}/devices/pci[0-9]*:[0-9]*/**/usb[0-9]**/speed r,
++ @{sys}/devices/pci[0-9]*:[0-9]*/**/usb[0-9]**/manufacturer r,
++ @{sys}/devices/pci[0-9]*:[0-9]*/**/usb[0-9]**/product r,
++ @{sys}/devices/pci[0-9]*:[0-9]*/**/usb[0-9]**/serial r,
++
++ include if exists <local/lsusb>
++}
+--
+2.43.0
+
diff --git a/debian/patches/ubuntu/mbsync_mr_1372.patch b/debian/patches/ubuntu/mbsync_mr_1372.patch
new file mode 100644
index 0000000..ecdfd5e
--- /dev/null
+++ b/debian/patches/ubuntu/mbsync_mr_1372.patch
@@ -0,0 +1,63 @@
+From c3d905f7c2dd22aef41f21610f57393af9a9a7d8 Mon Sep 17 00:00:00 2001
+From: Eduardo Barretto <eduardo.barretto at canonical.com>
+Date: Fri, 11 Oct 2024 18:15:39 +0200
+Subject: [PATCH] Add profile for mbsync tool
+
+Source package isync
+
+Signed-off-by: Eduardo Barretto <eduardo.barretto at canonical.com>
+---
+ profiles/apparmor.d/mbsync | 41 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 41 insertions(+)
+ create mode 100644 profiles/apparmor.d/mbsync
+
+diff --git a/profiles/apparmor.d/mbsync b/profiles/apparmor.d/mbsync
+new file mode 100644
+index 000000000..7aa667e2e
+--- /dev/null
++++ b/profiles/apparmor.d/mbsync
+@@ -0,0 +1,41 @@
++#------------------------------------------------------------------
++# Copyright (C) 2024 Canonical Ltd.
++#
++# Author: Eduardo Barretto <eduardo.barretto at canonical.com>
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#------------------------------------------------------------------
++# vim: ft=apparmor
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile mbsync /usr/bin/mbsync {
++ include <abstractions/base>
++ include <abstractions/nameservice-strict>
++ include <abstractions/ssl_certs>
++
++ network inet dgram,
++ network inet stream,
++ network inet6 dgram,
++ network inet6 stream,
++ network netlink raw,
++
++ @{etc_ro}/ssl/openssl.cnf r,
++ /usr/bin/mbsync r,
++ owner @{HOME}/.mbsyncrc r,
++ owner @{HOME}/Mail/**/ r,
++ owner @{HOME}/Mail/**/.mbsyncstate rw,
++ owner @{HOME}/Mail/**/.mbsyncstate.journal rw,
++ owner @{HOME}/Mail/**/.mbsyncstate.lock wk,
++ owner @{HOME}/Mail/**/.mbsyncstate.new rw,
++ owner @{HOME}/Mail/**/.uidvalidity rwk,
++ owner @{HOME}/Mail/**/cur/* rw,
++ owner @{HOME}/Mail/**/new/* rw,
++ owner @{HOME}/Mail/**/tmp/* rw,
++
++ include if exists <local/mbsync>
++}
+--
+2.43.0
+
diff --git a/debian/patches/ubuntu/mosquitto_mr_1506.patch b/debian/patches/ubuntu/mosquitto_mr_1506.patch
new file mode 100644
index 0000000..90c3954
--- /dev/null
+++ b/debian/patches/ubuntu/mosquitto_mr_1506.patch
@@ -0,0 +1,74 @@
+From 532d4be05051ef32da34a01ae0f44a55f8da3c2e Mon Sep 17 00:00:00 2001
+From: vyomydv <vyom.yadav at canonical.com>
+Date: Mon, 27 Jan 2025 17:43:17 +0530
+Subject: [PATCH] profiles/apparmor.d: add mosquitto profile
+
+Signed-off-by: vyomydv <vyom.yadav at canonical.com>
+---
+ profiles/apparmor.d/mosquitto | 54 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 54 insertions(+)
+ create mode 100644 profiles/apparmor.d/mosquitto
+
+diff --git a/profiles/apparmor.d/mosquitto b/profiles/apparmor.d/mosquitto
+new file mode 100644
+index 000000000..37172661a
+--- /dev/null
++++ b/profiles/apparmor.d/mosquitto
+@@ -0,0 +1,54 @@
++#------------------------------------------------------------------
++# Copyright (C) 2025 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#------------------------------------------------------------------
++# vim: ft=apparmor
++#
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile mosquitto /usr/sbin/mosquitto {
++ include <abstractions/base>
++ include <abstractions/nameservice-strict>
++ include <abstractions/hosts_access>
++
++ # If run as a root user, drop privileges to mosquitto/nobody/custom-user
++ capability setgid,
++ capability setuid,
++
++ network inet stream,
++ network inet6 stream,
++ network inet dgram,
++ network inet6 dgram,
++ network netlink raw,
++
++ file @{run}/.nscd_socket rw,
++ file @{run}/nscd/socket rw,
++
++ # nss can be configured to use libvirt in host resolution
++ file /var/lib/libvirt/dnsmasq/ r,
++ file /var/lib/libvirt/dnsmasq/*.status r,
++
++ file @{run}/systemd/notify w,
++ file /usr/sbin/mosquitto mr,
++ file @{run}/mosquitto/mosquitto.pid rw,
++
++ file @{etc_ro}/mosquitto/* r,
++ file @{etc_ro}/mosquitto/conf.d/ r,
++ file @{etc_ro}/mosquitto/conf.d/** r,
++ file @{etc_ro}/mosquitto/mosquitto.conf r,
++ file @{etc_ro}/mosquitto/ca_certificates/** r,
++ file @{etc_ro}/mosquitto/certs/** r,
++
++ file /var/lib/mosquitto/mosquitto.db rwk,
++ file /var/lib/mosquitto/mosquitto.db.new rwk,
++ file /var/log/mosquitto/mosquitto.log w,
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/mosquitto>
++}
++
+--
+GitLab
+
diff --git a/debian/patches/ubuntu/netcat-openbsd_mr_1327.patch b/debian/patches/ubuntu/netcat-openbsd_mr_1327.patch
new file mode 100644
index 0000000..f925b9c
--- /dev/null
+++ b/debian/patches/ubuntu/netcat-openbsd_mr_1327.patch
@@ -0,0 +1,66 @@
+From 9a1c476d99961e8e7853a0788f8db38c6b5d9be4 Mon Sep 17 00:00:00 2001
+From: Octavio Galland <octavio.galland at canonical.com>
+Date: Thu, 12 Sep 2024 15:10:02 -0300
+Subject: [PATCH] Add netcat-openbsd profile
+
+---
+ profiles/apparmor.d/nc.openbsd | 27 +++++++++++++++++++++++++++
+ tests/profiles/nc.openbsd/task.yaml | 12 ++++++++++++
+ 2 files changed, 39 insertions(+)
+ create mode 100644 profiles/apparmor.d/nc.openbsd
+ create mode 100644 tests/profiles/nc.openbsd/task.yaml
+
+diff --git a/profiles/apparmor.d/nc.openbsd b/profiles/apparmor.d/nc.openbsd
+new file mode 100644
+index 000000000..61a41d6e9
+--- /dev/null
++++ b/profiles/apparmor.d/nc.openbsd
+@@ -0,0 +1,27 @@
++#------------------------------------------------------------------
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#------------------------------------------------------------------
++# vim: ft=apparmor
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile nc.openbsd /usr/bin/nc.openbsd {
++ include <abstractions/base>
++ include <abstractions/nameservice>
++
++ file rw /**,
++
++ # we need to enable all networking in order to allow DCCP (this also allows unix sockets)
++ network,
++
++ /usr/bin/nc.openbsd mr,
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/nc.openbsd>
++}
+diff --git a/tests/profiles/nc.openbsd/task.yaml b/tests/profiles/nc.openbsd/task.yaml
+new file mode 100644
+index 000000000..80e10e5b9
+--- /dev/null
++++ b/tests/profiles/nc.openbsd/task.yaml
+@@ -0,0 +1,12 @@
++summary: smoke test for the nc.openbsd profile
++execute: |
++ # IPv4, IPv6
++ nc -4 -l 4321 & (echo "hi" | nc -4 -q 0 127.0.0.1 4321)
++ nc -6 -l 4321 & (echo "hi" | nc -6 -q 0 ::1 4321)
++
++ # UNIX sockets
++ nc -l -U /tmp/socket & (echo "hi" | nc -q 0 -U /tmp/socket)
++ nc -l -U '@tmpsocket' & (echo "hi" | nc -q 0 -U '@tmpsocket')
++
++ # The profile is attached based on the program path.
++ "$SPREAD_PATH"/tests/bin/actual-profile-of nc.openbsd | MATCH 'nc.openbsd \(enforce\)'
+--
+2.43.0
+
diff --git a/debian/patches/ubuntu/openvpn_mr_1263.patch b/debian/patches/ubuntu/openvpn_mr_1263.patch
new file mode 100644
index 0000000..fb7ab84
--- /dev/null
+++ b/debian/patches/ubuntu/openvpn_mr_1263.patch
@@ -0,0 +1,133 @@
+From 9df9c792e98c68c1ef94123b724bac4adcfbe19d Mon Sep 17 00:00:00 2001
+From: Nishit Majithia <nishit.nm at gmail.com>
+Date: Fri, 28 Jun 2024 17:30:32 +0530
+Subject: [PATCH] Add openvpn profile
+
+Signed-off-by: Nishit Majithia <nishit.nm at gmail.com>
+---
+ profiles/apparmor.d/openvpn | 113 ++++++++++++++++++++++++++++++++++++
+ 1 file changed, 113 insertions(+)
+ create mode 100644 profiles/apparmor.d/openvpn
+
+diff --git a/profiles/apparmor.d/openvpn b/profiles/apparmor.d/openvpn
+new file mode 100644
+index 000000000..8f8772f33
+--- /dev/null
++++ b/profiles/apparmor.d/openvpn
+@@ -0,0 +1,113 @@
++#------------------------------------------------------------------
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#------------------------------------------------------------------
++# vim: ft=apparmor
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile openvpn /usr/sbin/openvpn flags=(attach_disconnected) {
++ include <abstractions/base>
++ include <abstractions/consoles>
++ include <abstractions/openssl>
++ include <abstractions/nameservice-strict>
++
++ capability dac_read_search,
++ capability dac_override,
++ capability net_admin,
++
++ # These are needed when user/group are set in a OpenVPN config file
++ capability setuid,
++ capability setgid,
++
++ # Network access rules
++ network inet dgram,
++ network inet6 dgram,
++ network raw,
++ network inet stream,
++ network inet6 stream,
++
++ # OpenVPN configuration and key files
++ file r /etc/openvpn/{,**},
++ file mr /usr/sbin/openvpn,
++
++ # To prompt password to users,
++ file mrix /usr/bin/systemd-ask-password,
++
++ # TUN/TAP device
++ file rw /dev/net/tun,
++
++ # Process-specific network route access
++ file r @{PROC}/@{pid}/net/route,
++
++ # OpenVPN log and status files
++ file rw /var/log/openvpn/*.log,
++ file rw /var/log/openvpn/ipp.txt,
++ file rw /{,var/}run/openvpn/*.{pid,status},
++
++ # integration with NetworkManager
++ file rw @{run}/NetworkManager/nm-openvpn-*,
++ file PUx /{usr/,}lib{exec,/NetworkManager}/nm-openvpn-service-openvpn-helper,
++
++ # IP tool capability for network configuration
++ file rCx /{,usr/}bin/ip,
++
++ # Sub-profile for IP tool restrictions
++ profile ip /{,usr/}bin/ip {
++ include <abstractions/base>
++
++ capability net_admin,
++
++ # Allow read access to IP tool binary
++ file r /{,usr/}bin/ip,
++
++ # Allow write access to OpenVPN log
++ file w /var/log/openvpn/openvpn.log,
++ }
++
++ # update-resolv.conf file for openvpn env set
++ file rCx /etc/openvpn/update-resolv-conf{,.sh} -> update-resolv,
++
++ # Sub-profile for /etc/openvpn/update-resolv-conf
++ profile update-resolv {
++ include <abstractions/base>
++ include <abstractions/consoles>
++ include <abstractions/nameservice-strict>
++
++ # To be able to manage firewall rules.
++ capability net_admin,
++
++ network (bind,create,getattr,getopt,receive,send,setopt) netlink raw,
++ unix (bind) type=stream addr=@[a-f0-9]*/bus/resolvconf/system,
++
++ file mrix /usr/bin/resolvectl,
++ file mrix /usr/bin/sort,
++
++ owner r /etc/openvpn/update-resolv-conf,
++ owner rw /run/dbus/system_bus_socket,
++ owner mr /usr/bin/bash,
++
++ dbus (send) bus=system path="/org/freedesktop/DBus" interface="org.freedesktop.DBus" member="Hello",
++ dbus (send) bus="system" path="/org/freedesktop/resolve1" interface="org.freedesktop.resolve1.Manager" member="SetLinkDNSEx",
++
++ file r /etc/openvpn/update-resolv-conf.sh,
++
++ file rix /bin/sh,
++ file rix /sbin/resolvconf,
++ file rix /{,usr/}bin/cut,
++ file rix /{,usr/}bin/ip,
++ file rix /{,usr/}bin/which{,.debianutils},
++ file rix /{,usr/}bin/xtables-nft-multi,
++
++ file r /etc/iproute2/rt_tables,
++ file r /etc/iproute2/rt_tables.d/,
++ }
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/openvpn>
++}
+--
+2.43.0
+
diff --git a/debian/patches/ubuntu/parser-add-support-for-prompting.patch b/debian/patches/ubuntu/parser-add-support-for-prompting.patch
deleted file mode 100644
index c583591..0000000
--- a/debian/patches/ubuntu/parser-add-support-for-prompting.patch
+++ /dev/null
@@ -1,3259 +0,0 @@
-From 60ef40f7a78c7bf3aed6ed08ab5c97da3d1ad035 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen at canonical.com>
-Date: Mon, 3 Apr 2023 21:39:03 -0700
-Subject: [PATCH] parser: add support for prompting
-
-This adds base support for prompting and extended permission tables.
-
-Signed-off-by: John Johansen <john.johansen at canonical.com>
----
- parser/af_unix.cc | 28 ++--
- parser/af_unix.h | 4
- parser/dbus.cc | 10 -
- parser/dbus.h | 6
- parser/io_uring.cc | 6
- parser/io_uring.h | 2
- parser/libapparmor_re/Makefile | 6
- parser/libapparmor_re/aare_rules.cc | 148 ++++++++++++++++++++--
- parser/libapparmor_re/aare_rules.h | 45 ++++--
- parser/libapparmor_re/chfa.cc | 167 +++++++++++++++++++++++--
- parser/libapparmor_re/chfa.h | 12 +
- parser/libapparmor_re/expr-tree.h | 19 +-
- parser/libapparmor_re/hfa.cc | 85 ++++++++++--
- parser/libapparmor_re/hfa.h | 36 ++++-
- parser/libapparmor_re/policy_compat.cc | 218 +++++++++++++++++++++++++++++++++
- parser/libapparmor_re/policy_compat.h | 25 +++
- parser/mount.cc | 26 +--
- parser/mount.h | 4
- parser/mqueue.cc | 12 -
- parser/mqueue.h | 4
- parser/network.cc | 22 +--
- parser/network.h | 9 -
- parser/parser.h | 17 +-
- parser/parser_common.c | 66 +++++++++
- parser/parser_interface.c | 106 ++++++++++++++--
- parser/parser_main.c | 42 ++++++
- parser/parser_misc.c | 19 +-
- parser/parser_policy.c | 7 +
- parser/parser_regex.c | 181 +++++++++++++++++++++++----
- parser/parser_yacc.y | 39 +++--
- parser/perms.h | 117 +++++++++++++++++
- parser/profile.cc | 6
- parser/profile.h | 15 +-
- parser/ptrace.cc | 9 -
- parser/ptrace.h | 6
- parser/rule.h | 58 +++++++-
- parser/signal.cc | 9 -
- parser/signal.h | 6
- parser/userns.cc | 8 -
- parser/userns.h | 2
- 40 files changed, 1366 insertions(+), 241 deletions(-)
- create mode 100644 parser/libapparmor_re/policy_compat.cc
- create mode 100644 parser/libapparmor_re/policy_compat.h
- create mode 100644 parser/perms.h
-
---- apparmor-4.0.0-beta4.orig/parser/af_unix.cc
-+++ apparmor-4.0.0-beta4/parser/af_unix.cc
-@@ -33,7 +33,7 @@
- /* See unix(7) for autobind address definition */
- #define autobind_address_pattern "\\x00[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]";
-
--int parse_unix_perms(const char *str_perms, perms_t *perms, int fail)
-+int parse_unix_perms(const char *str_perms, perm32_t *perms, int fail)
- {
- return parse_X_perms("unix", AA_VALID_NET_PERMS, str_perms, perms, fail);
- }
-@@ -113,7 +113,7 @@
- downgrade = false;
- }
-
--unix_rule::unix_rule(perms_t perms_p, struct cond_entry *conds,
-+unix_rule::unix_rule(perm32_t perms_p, struct cond_entry *conds,
- struct cond_entry *peer_conds):
- af_rule(AF_UNIX), addr(NULL), peer_addr(NULL)
- {
-@@ -191,7 +191,7 @@
- #define CMD_OPT 4
-
- void unix_rule::downgrade_rule(Profile &prof) {
-- perms_t mask = (perms_t) -1;
-+ perm32_t mask = (perm32_t) -1;
-
- if (!prof.net.allow && !prof.net.alloc_net_table())
- yyerror(_("Memory allocation error."));
-@@ -318,7 +318,7 @@
- std::ostringstream buffer;
- std::string buf;
-
-- perms_t mask = perms;
-+ perm32_t mask = perms;
-
- /* always generate a downgraded rule. This doesn't change generated
- * policy size and allows the binary policy to be loaded against
-@@ -344,7 +344,7 @@
- write_to_prot(buffer);
- if ((mask & AA_NET_CREATE) && !has_peer_conds()) {
- buf = buffer.str();
-- if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY,
-+ if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode,
- map_perms(AA_NET_CREATE),
- map_perms(audit == AUDIT_FORCE ? AA_NET_CREATE : 0),
- parseopts))
-@@ -369,7 +369,7 @@
- tmp << "\\x00";
-
- buf = tmp.str();
-- if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY,
-+ if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode,
- map_perms(AA_NET_BIND),
- map_perms(audit == AUDIT_FORCE ? AA_NET_BIND : 0),
- parseopts))
-@@ -394,7 +394,7 @@
- AA_LOCAL_NET_PERMS & ~AA_LOCAL_NET_CMD;
- if (mask & local_mask) {
- buf = buffer.str();
-- if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY,
-+ if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode,
- map_perms(mask & local_mask),
- map_perms(audit == AUDIT_FORCE ? mask & local_mask : 0),
- parseopts))
-@@ -408,7 +408,7 @@
- /* TODO: backlog conditional: for now match anything*/
- tmp << "..";
- buf = tmp.str();
-- if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY,
-+ if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode,
- map_perms(AA_NET_LISTEN),
- map_perms(audit == AUDIT_FORCE ? AA_NET_LISTEN : 0),
- parseopts))
-@@ -421,10 +421,12 @@
- /* TODO: sockopt conditional: for now match anything */
- tmp << "..";
- buf = tmp.str();
-- if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY,
-- map_perms(mask & AA_NET_OPT),
-- map_perms(audit == AUDIT_FORCE ? AA_NET_OPT : 0),
-- parseopts))
-+ if (!prof.policy.rules->add_rule(buf.c_str(),
-+ rule_mode,
-+ map_perms(mask & AA_NET_OPT),
-+ map_perms(audit == AUDIT_FORCE ?
-+ AA_NET_OPT : 0),
-+ parseopts))
- goto fail;
- }
- mask &= ~AA_LOCAL_NET_PERMS | AA_NET_ACCEPT;
-@@ -442,7 +444,7 @@
- goto fail;
-
- buf = buffer.str();
-- if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, map_perms(perms & AA_PEER_NET_PERMS), map_perms(audit == AUDIT_FORCE ? perms & AA_PEER_NET_PERMS : 0), parseopts))
-+ if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode, map_perms(perms & AA_PEER_NET_PERMS), map_perms(audit == AUDIT_FORCE ? perms & AA_PEER_NET_PERMS : 0), parseopts))
- goto fail;
- }
-
---- apparmor-4.0.0-beta4.orig/parser/af_unix.h
-+++ apparmor-4.0.0-beta4/parser/af_unix.h
-@@ -24,7 +24,7 @@
- #include "profile.h"
- #include "af_rule.h"
-
--int parse_unix_perms(const char *str_mode, perms_t *perms, int fail);
-+int parse_unix_perms(const char *str_mode, perm32_t *perms, int fail);
-
- class unix_rule: public af_rule {
- void write_to_prot(std::ostringstream &buffer);
-@@ -39,7 +39,7 @@
- bool downgrade = true;
-
- unix_rule(unsigned int type_p, audit_t audit_p, rule_mode_t rule_mode_p);
-- unix_rule(perms_t perms, struct cond_entry *conds,
-+ unix_rule(perm32_t perms, struct cond_entry *conds,
- struct cond_entry *peer_conds);
- virtual ~unix_rule()
- {
---- apparmor-4.0.0-beta4.orig/parser/dbus.cc
-+++ apparmor-4.0.0-beta4/parser/dbus.cc
-@@ -30,7 +30,7 @@
- #include "dbus.h"
-
-
--int parse_dbus_perms(const char *str_perms, perms_t *perms, int fail)
-+int parse_dbus_perms(const char *str_perms, perm32_t *perms, int fail)
- {
- return parse_X_perms("DBus", AA_VALID_DBUS_PERMS, str_perms, perms, fail);
- }
-@@ -66,7 +66,7 @@
- }
- }
-
--dbus_rule::dbus_rule(perms_t perms_p, struct cond_entry *conds,
-+dbus_rule::dbus_rule(perm32_t perms_p, struct cond_entry *conds,
- struct cond_entry *peer_conds):
- perms_rule_t(AA_CLASS_DBUS), bus(NULL), name(NULL), peer_label(NULL), path(NULL), interface(NULL), member(NULL)
- {
-@@ -274,20 +274,20 @@
- }
-
- if (perms & AA_DBUS_BIND) {
-- if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms & AA_DBUS_BIND,
-+ if (!prof.policy.rules->add_rule_vec(rule_mode, perms & AA_DBUS_BIND,
- audit == AUDIT_FORCE ? perms & AA_DBUS_BIND : 0,
- 2, vec, parseopts, false))
- goto fail;
- }
- if (perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE)) {
-- if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY,
-+ if (!prof.policy.rules->add_rule_vec(rule_mode,
- perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE),
- audit == AUDIT_FORCE ? perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE) : 0,
- 6, vec, parseopts, false))
- goto fail;
- }
- if (perms & AA_DBUS_EAVESDROP) {
-- if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY,
-+ if (!prof.policy.rules->add_rule_vec(rule_mode,
- perms & AA_DBUS_EAVESDROP,
- audit == AUDIT_FORCE ? perms & AA_DBUS_EAVESDROP : 0,
- 1, vec, parseopts, false))
---- apparmor-4.0.0-beta4.orig/parser/dbus.h
-+++ apparmor-4.0.0-beta4/parser/dbus.h
-@@ -23,7 +23,7 @@
- #include "rule.h"
- #include "profile.h"
-
--extern int parse_dbus_perms(const char *str_mode, perms_t *mode, int fail);
-+extern int parse_dbus_perms(const char *str_mode, perm32_t *mode, int fail);
-
- class dbus_rule: public perms_rule_t {
- void move_conditionals(struct cond_entry *conds);
-@@ -40,7 +40,7 @@
- char *interface;
- char *member;
-
-- dbus_rule(perms_t perms_p, struct cond_entry *conds,
-+ dbus_rule(perm32_t perms_p, struct cond_entry *conds,
- struct cond_entry *peer_conds);
- virtual ~dbus_rule() {
- free(bus);
-@@ -51,7 +51,7 @@
- free(member);
- };
- virtual bool valid_prefix(const prefixes &p, const char *&error) {
-- if (p.owner) {
-+ if (p.owner != OWNER_UNSPECIFIED) {
- error = "owner prefix not allowed on dbus rules";
- return false;
- }
---- apparmor-4.0.0-beta4.orig/parser/io_uring.cc
-+++ apparmor-4.0.0-beta4/parser/io_uring.cc
-@@ -47,7 +47,7 @@
- }
- }
-
--io_uring_rule::io_uring_rule(perms_t perms_p, struct cond_entry *conds, struct cond_entry *ring_conds):
-+io_uring_rule::io_uring_rule(perm32_t perms_p, struct cond_entry *conds, struct cond_entry *ring_conds):
- perms_rule_t(AA_CLASS_IO_URING), label(NULL)
- {
- if (perms_p) {
-@@ -122,14 +122,14 @@
- }
-
- if (perms & AA_VALID_IO_URING_PERMS) {
-- if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, perms,
-+ if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode, perms,
- audit == AUDIT_FORCE ? perms : 0,
- parseopts))
- goto fail;
-
- if (perms & AA_IO_URING_OVERRIDE_CREDS) {
- buf = buffer.str(); /* update buf to have label */
-- if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY,
-+ if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode,
- perms, audit == AUDIT_FORCE ? perms : 0,
- parseopts))
- goto fail;
---- apparmor-4.0.0-beta4.orig/parser/io_uring.h
-+++ apparmor-4.0.0-beta4/parser/io_uring.h
-@@ -31,7 +31,7 @@
- public:
- char *label;
-
-- io_uring_rule(perms_t perms, struct cond_entry *conds, struct cond_entry *ring_conds);
-+ io_uring_rule(perm32_t perms, struct cond_entry *conds, struct cond_entry *ring_conds);
- virtual ~io_uring_rule()
- {
- free(label);
---- apparmor-4.0.0-beta4.orig/parser/libapparmor_re/Makefile
-+++ apparmor-4.0.0-beta4/parser/libapparmor_re/Makefile
-@@ -22,17 +22,19 @@
-
- UNITTESTS = tst_parse
-
--libapparmor_re.a: parse.o expr-tree.o hfa.o chfa.o aare_rules.o
-+libapparmor_re.a: parse.o expr-tree.o hfa.o chfa.o aare_rules.o policy_compat.o
- ${AR} ${ARFLAGS} $@ $^
-
- expr-tree.o: expr-tree.cc expr-tree.h
-
--hfa.o: hfa.cc apparmor_re.h hfa.h ../immunix.h
-+hfa.o: hfa.cc apparmor_re.h hfa.h ../immunix.h policy_compat.h
-
- aare_rules.o: aare_rules.cc aare_rules.h apparmor_re.h expr-tree.h hfa.h chfa.h parse.h ../immunix.h
-
- chfa.o: chfa.cc chfa.h ../immunix.h
-
-+policy_compat.o: policy_compat.cc policy_compat.h ../perms.h ../immunix.h
-+
- parse.o : parse.cc apparmor_re.h expr-tree.h
-
- parse.cc : parse.y parse.h flex-tables.h ../immunix.h
---- apparmor-4.0.0-beta4.orig/parser/libapparmor_re/aare_rules.cc
-+++ apparmor-4.0.0-beta4/parser/libapparmor_re/aare_rules.cc
-@@ -44,10 +44,10 @@
- expr_map.clear();
- }
-
--bool aare_rules::add_rule(const char *rule, int deny, uint32_t perms,
-- uint32_t audit, optflags const &opts)
-+bool aare_rules::add_rule(const char *rule, rule_mode_t mode, perm32_t perms,
-+ perm32_t audit, optflags const &opts)
- {
-- return add_rule_vec(deny, perms, audit, 1, &rule, opts, false);
-+ return add_rule_vec(mode, perms, audit, 1, &rule, opts, false);
- }
-
- void aare_rules::add_to_rules(Node *tree, Node *perms)
-@@ -71,7 +71,7 @@
- return new CatNode(new CatNode(l, new CharNode(transchar(-1, true))), r);
- }
-
--bool aare_rules::add_rule_vec(int deny, uint32_t perms, uint32_t audit,
-+bool aare_rules::add_rule_vec(rule_mode_t mode, perm32_t perms, perm32_t audit,
- int count, const char **rulev, optflags const &opts,
- bool oob)
- {
-@@ -107,7 +107,7 @@
- if (reverse)
- flip_tree(tree);
-
-- accept = unique_perms.insert(deny, perms, audit, exact_match);
-+ accept = unique_perms.insert(mode, perms, audit, exact_match);
-
- if (opts.dump & DUMP_DFA_RULE_EXPR) {
- const char *separator;
-@@ -123,8 +123,11 @@
- }
- cerr << " -> ";
- tree->dump(cerr);
-- if (deny)
-+ // TODO: split out from prefixes class
-+ if (mode == RULE_DENY)
- cerr << " deny";
-+ else if (mode == RULE_PROMPT)
-+ cerr << " prompt";
- cerr << " (0x" << hex << perms <<"/" << audit << dec << ")";
- accept->dump(cerr);
- cerr << "\n\n";
-@@ -189,16 +192,16 @@
- return true;
- }
-
--/* create a dfa from the ruleset
-+/* create a chfa from the ruleset
- * returns: buffer contain dfa tables, @size set to the size of the tables
- * else NULL on failure, @min_match_len set to the shortest string
- * that can match the dfa for determining xmatch priority.
- */
--void *aare_rules::create_dfa(size_t *size, int *min_match_len, optflags const &opts,
-- bool filedfa)
-+CHFA *aare_rules::create_chfa(int *min_match_len,
-+ vector <aa_perms> &perms_table,
-+ optflags const &opts, bool filedfa,
-+ bool extended_perms, bool prompt)
- {
-- char *buffer = NULL;
--
- /* finish constructing the expr tree from the different permission
- * set nodes */
- PermExprMap::iterator i = expr_map.begin();
-@@ -247,7 +250,7 @@
- }
- }
-
-- stringstream stream;
-+ CHFA *chfa = NULL;
- try {
- DFA dfa(root, opts, filedfa);
- if (opts.dump & DUMP_DFA_UNIQ_PERMS)
-@@ -304,10 +307,45 @@
- dfa.dump_diff_encode(cerr);
- }
-
-- CHFA chfa(dfa, eq, opts);
-+ //cerr << "Checking extended perms " << extended_perms << "\n";
-+ if (extended_perms) {
-+ //cerr << "creating permstable\n";
-+ dfa.compute_perms_table(perms_table, prompt);
-+ }
-+ chfa = new CHFA(dfa, eq, opts, extended_perms, prompt);
- if (opts.dump & DUMP_DFA_TRANS_TABLE)
-- chfa.dump(cerr);
-- chfa.flex_table(stream, "");
-+ chfa->dump(cerr);
-+ }
-+ catch(int error) {
-+ return NULL;
-+ }
-+
-+ return chfa;
-+}
-+
-+/* create a dfa from the ruleset
-+ * returns: buffer contain dfa tables, @size set to the size of the tables
-+ * else NULL on failure, @min_match_len set to the shortest string
-+ * that can match the dfa for determining xmatch priority.
-+ */
-+void *aare_rules::create_dfablob(size_t *size, int *min_match_len,
-+ vector <aa_perms> &perms_table,
-+ optflags const &opts, bool filedfa,
-+ bool extended_perms, bool prompt)
-+{
-+ char *buffer = NULL;
-+ stringstream stream;
-+
-+ try {
-+ CHFA *chfa = create_chfa(min_match_len, perms_table,
-+ opts, filedfa, extended_perms,
-+ prompt);
-+ if (!chfa) {
-+ *size = 0;
-+ return NULL;
-+ }
-+ chfa->flex_table(stream, "");
-+ delete (chfa);
- }
- catch(int error) {
- *size = 0;
-@@ -323,5 +361,85 @@
- if (!buffer)
- return NULL;
- buf->sgetn(buffer, *size);
-+
-+ return buffer;
-+}
-+
-+
-+/* create a dfa from the ruleset
-+ * returns: buffer contain dfa tables, @size set to the size of the tables
-+ * else NULL on failure, @min_match_len set to the shortest string
-+ * that can match the dfa for determining xmatch priority.
-+ */
-+void *aare_rules::create_welded_dfablob(aare_rules *file_rules,
-+ size_t *size, int *min_match_len,
-+ size_t *new_start,
-+ vector <aa_perms> &perms_table,
-+ optflags const &opts,
-+ bool extended_perms, bool prompt)
-+{
-+ int file_min_len;
-+ vector <aa_perms> file_perms;
-+ CHFA *file_chfa;
-+ try {
-+ file_chfa = file_rules->create_chfa(&file_min_len,
-+ file_perms, opts,
-+ true, extended_perms, prompt);
-+ if (!file_chfa) {
-+ *size = 0;
-+ return NULL;
-+ }
-+ }
-+ catch(int error) {
-+ *size = 0;
-+ return NULL;
-+ }
-+
-+ CHFA *policy_chfa;
-+ try {
-+ policy_chfa = create_chfa(min_match_len,
-+ perms_table, opts,
-+ false, extended_perms, prompt);
-+ if (!policy_chfa) {
-+ delete file_chfa;
-+ *size = 0;
-+ return NULL;
-+ }
-+ }
-+ catch(int error) {
-+ delete file_chfa;
-+ *size = 0;
-+ return NULL;
-+ }
-+
-+ stringstream stream;
-+ try {
-+ policy_chfa->weld_file_to_policy(*file_chfa, *new_start,
-+ extended_perms, prompt,
-+ perms_table, file_perms);
-+ policy_chfa->flex_table(stream, "");
-+ }
-+ catch(int error) {
-+ delete (file_chfa);
-+ delete (policy_chfa);
-+ *size = 0;
-+ return NULL;
-+ }
-+ delete file_chfa;
-+ delete policy_chfa;
-+
-+ /* write blob to buffer */
-+ stringbuf *buf = stream.rdbuf();
-+
-+ buf->pubseekpos(0);
-+ *size = buf->in_avail();
-+ if (file_min_len < *min_match_len)
-+ *min_match_len = file_min_len;
-+
-+ char *buffer = (char *)malloc(*size);
-+ if (!buffer)
-+ return NULL;
-+ buf->sgetn(buffer, *size);
-+
- return buffer;
- }
---- apparmor-4.0.0-beta4.orig/parser/libapparmor_re/aare_rules.h
-+++ apparmor-4.0.0-beta4/parser/libapparmor_re/aare_rules.h
-@@ -21,22 +21,28 @@
- #ifndef __LIBAA_RE_RULES_H
- #define __LIBAA_RE_RULES_H
-
-+#include <vector>
-+
- #include <stdint.h>
-
- #include "../common_optarg.h"
- #include "apparmor_re.h"
-+#include "chfa.h"
- #include "expr-tree.h"
-+#include "../immunix.h"
-+#include "../perms.h"
-+#include "../rule.h"
-
- class UniquePerm {
- public:
-- bool deny;
-+ rule_mode_t mode;
- bool exact_match;
- uint32_t perms;
- uint32_t audit;
-
- bool operator<(UniquePerm const &rhs)const
- {
-- if (deny == rhs.deny) {
-+ if (mode >= rhs.mode) {
- if (exact_match == rhs.exact_match) {
- if (perms == rhs.perms)
- return audit < rhs.audit;
-@@ -44,7 +50,7 @@
- }
- return exact_match;
- }
-- return deny;
-+ return true; // mode < rhs.mode
- }
- };
-
-@@ -65,15 +71,17 @@
- nodes.clear();
- }
-
-- Node *insert(bool deny, uint32_t perms, uint32_t audit,
-+ Node *insert(rule_mode_t mode, uint32_t perms, uint32_t audit,
- bool exact_match)
- {
-- UniquePerm tmp = { deny, exact_match, perms, audit };
-+ UniquePerm tmp = { mode, exact_match, perms, audit };
- iterator res = nodes.find(tmp);
- if (res == nodes.end()) {
- Node *node;
-- if (deny)
-+ if (mode == RULE_DENY)
- node = new DenyMatchFlag(perms, audit);
-+ else if (mode == RULE_PROMPT)
-+ node = new PromptMatchFlag(perms, audit);
- else if (exact_match)
- node = new ExactMatchFlag(perms, audit);
- else
-@@ -101,13 +109,26 @@
- aare_rules(int reverse): root(NULL), unique_perms(), expr_map(), reverse(reverse), rule_count(0) { };
- ~aare_rules();
-
-- bool add_rule(const char *rule, int deny, uint32_t perms,
-- uint32_t audit, optflags const &opts);
-- bool add_rule_vec(int deny, uint32_t perms, uint32_t audit, int count,
-- const char **rulev, optflags const &opts, bool oob);
-+ bool add_rule(const char *rule, rule_mode_t mode, perm32_t perms,
-+ perm32_t audit, optflags const &opts);
-+ bool add_rule_vec(rule_mode_t mode, perm32_t perms, perm32_t audit,
-+ int count, const char **rulev, optflags const &opts,
-+ bool oob);
- bool append_rule(const char *rule, bool oob, bool with_perm, optflags const &opts);
-- void *create_dfa(size_t *size, int *min_match_len, optflags const &opts,
-- bool filedfa);
-+ CHFA *create_chfa(int *min_match_len,
-+ vector <aa_perms> &perms_table,
-+ optflags const &opts, bool filedfa,
-+ bool extended_perms, bool prompt);
-+ void *create_dfablob(size_t *size, int *min_match_len,
-+ vector <aa_perms> &perms_table,
-+ optflags const &opts,
-+ bool filedfa, bool extended_perms, bool prompt);
-+ void *create_welded_dfablob(aare_rules *file_rules,
-+ size_t *size, int *min_match_len,
-+ size_t *new_start,
-+ vector <aa_perms> &perms_table,
-+ optflags const &opts,
-+ bool extended_perms, bool prompt);
- };
-
- #endif /* __LIBAA_RE_RULES_H */
---- apparmor-4.0.0-beta4.orig/parser/libapparmor_re/chfa.cc
-+++ apparmor-4.0.0-beta4/parser/libapparmor_re/chfa.cc
-@@ -32,6 +32,7 @@
- #include "hfa.h"
- #include "chfa.h"
- #include "../immunix.h"
-+#include "../policydb.h"
- #include "flex-tables.h"
-
- void CHFA::init_free_list(vector<pair<size_t, size_t> > &free_list,
-@@ -46,11 +47,15 @@
- free_list[free_list.size() - 1].second = 0;
- }
-
-+
- /**
- * new Construct the transition table.
-+ *
-+ * TODO: split dfaflags into separate control and dump so we can fold in
-+ * permtable index flag
- */
--CHFA::CHFA(DFA &dfa, map<transchar, transchar> &eq, optflags const &opts):
-- eq(eq)
-+CHFA::CHFA(DFA &dfa, map<transchar, transchar> &eq, optflags const &opts,
-+ bool permindex, bool prompt): eq(eq)
- {
- if (opts.dump & DUMP_DFA_TRANS_PROGRESS)
- fprintf(stderr, "Compressing HFA:\r");
-@@ -101,18 +106,29 @@
- num.insert(make_pair(dfa.nonmatching, num.size()));
-
- accept.resize(max(dfa.states.size(), (size_t) 2));
-- accept2.resize(max(dfa.states.size(), (size_t) 2));
-+ if (permindex) {
-+ accept[0] = dfa.nonmatching->idx;
-+ accept[1] = dfa.start->idx;
-+ } else {
-+ uint32_t accept3;
-+ accept2.resize(max(dfa.states.size(), (size_t) 2));
-+ dfa.nonmatching->map_perms_to_accept(accept[0],
-+ accept2[0],
-+ accept3,
-+ prompt);
-+ dfa.start->map_perms_to_accept(accept[1],
-+ accept2[1],
-+ accept3,
-+ prompt);
-+ }
- next_check.resize(max(optimal, (size_t) dfa.max_range));
- free_list.resize(next_check.size());
-
-- accept[0] = 0;
-- accept2[0] = 0;
- first_free = 1;
- init_free_list(free_list, 0, 1);
-
-+ start = dfa.start;
- insert_state(free_list, dfa.start, dfa);
-- accept[1] = 0;
-- accept2[1] = 0;
- num.insert(make_pair(dfa.start, num.size()));
-
- int count = 2;
-@@ -120,9 +136,15 @@
- if (!(opts.control & CONTROL_DFA_TRANS_HIGH)) {
- for (Partition::iterator i = dfa.states.begin(); i != dfa.states.end(); i++) {
- if (*i != dfa.nonmatching && *i != dfa.start) {
-+ uint32_t accept3;
- insert_state(free_list, *i, dfa);
-- accept[num.size()] = (*i)->perms.allow;
-- accept2[num.size()] = PACK_AUDIT_CTL((*i)->perms.audit, (*i)->perms.quiet & (*i)->perms.deny);
-+ if (permindex)
-+ accept[num.size()] = (*i)->idx;
-+ else
-+ (*i)->map_perms_to_accept(accept[num.size()],
-+ accept2[num.size()],
-+ accept3,
-+ prompt);
- num.insert(make_pair(*i, num.size()));
- }
- if (opts.dump & (DUMP_DFA_TRANS_PROGRESS)) {
-@@ -137,9 +159,15 @@
- i != order.end(); i++) {
- if (i->second != dfa.nonmatching &&
- i->second != dfa.start) {
-+ uint32_t accept3;
- insert_state(free_list, i->second, dfa);
-- accept[num.size()] = i->second->perms.allow;
-- accept2[num.size()] = PACK_AUDIT_CTL(i->second->perms.audit, i->second->perms.quiet & i->second->perms.deny);
-+ if (permindex)
-+ accept[num.size()] = i->second->idx;
-+ else
-+ i->second->map_perms_to_accept(accept[num.size()],
-+ accept2[num.size()],
-+ accept3,
-+ prompt);
- num.insert(make_pair(i->second, num.size()));
- }
- if (opts.dump & (DUMP_DFA_TRANS_PROGRESS)) {
-@@ -425,7 +453,7 @@
- th.th_hsize = htonl(hsize);
- th.th_ssize = htonl(hsize +
- flex_table_size(accept.begin(), accept.end()) +
-- flex_table_size(accept2.begin(), accept2.end()) +
-+ (accept2.size() ? flex_table_size(accept2.begin(), accept2.end()) : 0) +
- (eq.size() ? flex_table_size(equiv_vec.begin(), equiv_vec.end()) : 0) +
- flex_table_size(base_vec.begin(), base_vec.end()) +
- flex_table_size(default_vec.begin(), default_vec.end()) +
-@@ -436,7 +464,9 @@
- os << fill64(sizeof(th) + sizeof(th_version) + strlen(name) + 1);
-
- write_flex_table(os, YYTD_ID_ACCEPT, accept.begin(), accept.end());
-- write_flex_table(os, YYTD_ID_ACCEPT2, accept2.begin(), accept2.end());
-+ if (accept2.size())
-+ write_flex_table(os, YYTD_ID_ACCEPT2, accept2.begin(),
-+ accept2.end());
- if (eq.size())
- write_flex_table(os, YYTD_ID_EC, equiv_vec.begin(),
- equiv_vec.end());
-@@ -445,3 +475,114 @@
- write_flex_table(os, YYTD_ID_NXT, next_vec.begin(), next_vec.end());
- write_flex_table(os, YYTD_ID_CHK, check_vec.begin(), check_vec.end());
- }
-+
-+/*
-+ * @file_chfa: chfa to add on to the policy chfa
-+ * @new_start: new start state for where the @file_dfa is in the new chfa
-+ *
-+ * Make a new chfa that is a combination of policy and file chfas. It
-+ * assumes policy is built with AA_CLASS_FILE support transition. The
-+ * resultant chfa will have file states and indexes offset except for
-+ * start and null states.
-+ *
-+ * NOTE:
-+ * - modifies chfa
-+ * requires:
-+ * - no ec
-+ * - policy chfa has transitions state[start].next[AA_CLASS_FILE]
-+ * - policy perms table is build if using permstable
-+
-+ */
-+void CHFA::weld_file_to_policy(CHFA &file_chfa, size_t &new_start,
-+ bool accept_idx, bool prompt,
-+ vector <aa_perms> &policy_perms,
-+ vector <aa_perms> &file_perms)
-+{
-+ // doesn't support remapping eq classes yet
-+ if (eq.size() > 0 || file_chfa.eq.size() > 0)
-+ throw 1;
-+
-+ size_t old_base_size = default_base.size();
-+ size_t old_next_size = next_check.size();
-+
-+ const State *nonmatching = default_base[0].first;
-+ //const State *start = default_base[1].first;
-+ const State *file_nonmatching = file_chfa.default_base[0].first;
-+
-+ // renumber states from file_dfa by appending to policy dfa
-+ num.insert(make_pair(file_nonmatching, 0)); // remap to policy nonmatching
-+ for (map<const State *, size_t>::iterator i = file_chfa.num.begin(); i != file_chfa.num.end() ; i++) {
-+ if (i->first == file_nonmatching)
-+ continue;
-+ num.insert(make_pair(i->first, i->second + old_base_size));
-+ }
-+
-+ // handle default and base table expansion, and setup renumbering
-+ // while we remap file_nonmatch within the table, we still keep its
-+ // slot.
-+ bool first = true;
-+ for (DefaultBase::iterator i = file_chfa.default_base.begin(); i != file_chfa.default_base.end(); i++) {
-+ const State *def;
-+ size_t base;
-+ if (first) {
-+ first = false;
-+ // remap file_nonmatch to nonmatch
-+ def = nonmatching;
-+ base = 0;
-+ } else {
-+ def = i->first;
-+ base = i->second + old_next_size;
-+ }
-+ default_base.push_back(make_pair(def, base));
-+ }
-+
-+ // mapping for these are handled by num[]
-+ for (NextCheck::iterator i = file_chfa.next_check.begin(); i != file_chfa.next_check.end(); i++) {
-+ next_check.push_back(*i);
-+ }
-+
-+ // append file perms to policy perms, and rework permsidx if needed
-+ if (accept_idx) {
-+ // policy idx double
-+ // file + doubled offset
-+ // Requires: policy perms table, so we can double and
-+ // update indexes
-+ // * file perm idx to start on even idx
-+ // * policy perms table size to double and entries
-+ // to repeat
-+ assert(accept.size() == old_base_size);
-+ accept.resize(accept.size() + file_chfa.accept.size());
-+ size_t size = policy_perms.size();
-+ policy_perms.resize(size*2 + file_perms.size());
-+ // shift and double the policy perms
-+ for (size_t i = size - 1; size >= 0; i--) {
-+ policy_perms[i*2] = policy_perms[i];
-+ policy_perms[i*2 + 1] = policy_perms[i];
-+ }
-+ // update policy accept idx for the new shifted perms table
-+ for (size_t i = 0; i < old_base_size; i++) {
-+ accept[i] = accept[i]*2;
-+ }
-+ // copy over file perms
-+ for (size_t i = 0; i < file_perms.size(); i++) {
-+ policy_perms[size*2 + i] = file_perms[i];
-+ }
-+ // shift file accept indexs
-+ for (size_t i = 0; i < file_chfa.accept.size(); i++) {
-+ accept[old_base_size + i] = file_chfa.accept[i] + size*2;
-+ }
-+ } else {
-+ // perms are stored in accept just append the perms
-+ size_t size = accept.size();
-+ accept.resize(size + file_chfa.accept.size());
-+ for (size_t i = 0; i < file_chfa.accept.size(); i++) {
-+ accept[size + i] = file_chfa.accept[i];
-+ accept2[size + i] = file_chfa.accept2[i];
-+ }
-+ }
-+
-+ // Rework transition state[start].next[AA_CLASS_FILE]
-+ next_check[default_base[1].second + AA_CLASS_FILE].first = file_chfa.start;
-+
-+ new_start = num[file_chfa.start];
-+}
---- apparmor-4.0.0-beta4.orig/parser/libapparmor_re/chfa.h
-+++ apparmor-4.0.0-beta4/parser/libapparmor_re/chfa.h
-@@ -16,7 +16,7 @@
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- *
-- * Create a compressed hfa (chfa) from and hfa
-+ * Create a compressed hfa (chfa) from an hfa
- */
- #ifndef __LIBAA_RE_CHFA_H
- #define __LIBAA_RE_CHFA_H
-@@ -25,6 +25,7 @@
- #include <vector>
-
- #include "hfa.h"
-+#include "../perms.h"
-
- #define BASE32_FLAGS 0xff000000
- #define DiffEncodeBit32 0x80000000
-@@ -37,7 +38,9 @@
- typedef vector<pair<const State *, size_t> > DefaultBase;
- typedef vector<pair<const State *, const State *> > NextCheck;
- public:
-- CHFA(DFA &dfa, map<transchar, transchar> &eq, optflags const &opts);
-+ CHFA(void);
-+ CHFA(DFA &dfa, map<transchar, transchar> &eq, optflags const &opts,
-+ bool permindex, bool prompt);
- void dump(ostream & os);
- void flex_table(ostream &os, const char *name);
- void init_free_list(vector<pair<size_t, size_t> > &free_list,
-@@ -46,12 +49,17 @@
- StateTrans &cases);
- void insert_state(vector<pair<size_t, size_t> > &free_list,
- State *state, DFA &dfa);
-+ void weld_file_to_policy(CHFA &file_chfa, size_t &new_start,
-+ bool accept_idx, bool prompt,
-+ vector <aa_perms> &policy_perms,
-+ vector <aa_perms> &file_perms);
-
- private:
- vector<uint32_t> accept;
- vector<uint32_t> accept2;
- DefaultBase default_base;
- NextCheck next_check;
-+ const State *start;
- map<const State *, size_t> num;
- map<transchar, transchar> eq;
- transchar max_eq;
---- apparmor-4.0.0-beta4.orig/parser/libapparmor_re/expr-tree.h
-+++ apparmor-4.0.0-beta4/parser/libapparmor_re/expr-tree.h
-@@ -41,6 +41,7 @@
-
- #include <stdint.h>
-
-+#include "../perms.h"
- #include "apparmor_re.h"
-
- using namespace std;
-@@ -885,19 +886,19 @@
-
- class MatchFlag: public AcceptNode {
- public:
-- MatchFlag(uint32_t flag, uint32_t audit): flag(flag), audit(audit)
-+ MatchFlag(perm32_t perms, perm32_t audit): perms(perms), audit(audit)
- {
- type_flags |= NODE_TYPE_MATCHFLAG;
- }
-- ostream &dump(ostream &os) { return os << "< 0x" << hex << flag << '>'; }
-+ ostream &dump(ostream &os) { return os << "< 0x" << hex << perms << '>'; }
-
-- uint32_t flag;
-- uint32_t audit;
-+ perm32_t perms;
-+ perm32_t audit;
- };
-
- class ExactMatchFlag: public MatchFlag {
- public:
-- ExactMatchFlag(uint32_t flag, uint32_t audit): MatchFlag(flag, audit)
-+ ExactMatchFlag(perm32_t perms, perm32_t audit): MatchFlag(perms, audit)
- {
- type_flags |= NODE_TYPE_EXACTMATCHFLAG;
- }
-@@ -905,12 +906,18 @@
-
- class DenyMatchFlag: public MatchFlag {
- public:
-- DenyMatchFlag(uint32_t flag, uint32_t quiet): MatchFlag(flag, quiet)
-+ DenyMatchFlag(perm32_t perms, perm32_t quiet): MatchFlag(perms, quiet)
- {
- type_flags |= NODE_TYPE_DENYMATCHFLAG;
- }
- };
-
-+class PromptMatchFlag: public MatchFlag {
-+public:
-+ PromptMatchFlag(perm32_t prompt, perm32_t audit): MatchFlag(prompt, audit) {}
-+};
-+
-+
- /* Traverse the syntax tree depth-first in an iterator-like manner. */
- class depth_first_traversal {
- stack<Node *>pos;
---- apparmor-4.0.0-beta4.orig/parser/libapparmor_re/hfa.cc
-+++ apparmor-4.0.0-beta4/parser/libapparmor_re/hfa.cc
-@@ -31,11 +31,12 @@
- #include <iostream>
- #include <fstream>
- #include <string.h>
--
-+#include <stdint.h>
- #include "expr-tree.h"
- #include "hfa.h"
-+#include "policy_compat.h"
- #include "../immunix.h"
--
-+#include "../perms.h"
-
- ostream &operator<<(ostream &os, const CacheStats &cache)
- {
-@@ -537,6 +538,7 @@
- << i->deny << " audit:" << i->audit
- << " quiet:" << i->quiet << dec << "\n";
- }
-+ //TODO: add prompt
- }
-
- /* Remove dead or unreachable states */
-@@ -644,10 +646,13 @@
- return c;
- }
-
-+
-+typedef pair<uint64_t,uint64_t> uint128_t;
-+
- /* minimize the number of dfa states */
- void DFA::minimize(optflags const &opts)
- {
-- map<pair<uint64_t, size_t>, Partition *> perm_map;
-+ map<pair<uint128_t, size_t>, Partition *> perm_map;
- list<Partition *> partitions;
-
- /* Set up the initial partitions
-@@ -664,16 +669,18 @@
- int final_accept = 0;
- for (Partition::iterator i = states.begin(); i != states.end(); i++) {
- size_t hash = 0;
-- uint64_t permtype = ((uint64_t) (PACK_AUDIT_CTL((*i)->perms.audit, (*i)->perms.quiet & (*i)->perms.deny)) << 32) | (uint64_t) (*i)->perms.allow;
-- pair<uint64_t, size_t> group = make_pair(permtype, hash);
-- map<pair<uint64_t, size_t>, Partition *>::iterator p = perm_map.find(group);
-+ uint128_t permtype;
-+ permtype.first = ((uint64_t) (PACK_AUDIT_CTL((*i)->perms.audit, (*i)->perms.quiet & (*i)->perms.deny)) << 32);
-+ permtype.second = (uint64_t) (*i)->perms.allow | ((uint64_t) (*i)->perms.prompt << 32);
-+ pair<uint128_t, size_t> group = make_pair(permtype, hash);
-+ map<pair<uint128_t, size_t>, Partition *>::iterator p = perm_map.find(group);
- if (p == perm_map.end()) {
- Partition *part = new Partition();
- part->push_back(*i);
- perm_map.insert(make_pair(group, part));
- partitions.push_back(part);
- (*i)->partition = part;
-- if (permtype)
-+ if (permtype.first || permtype.second)
- accept_count++;
- } else {
- (*i)->partition = p->second;
-@@ -1300,6 +1307,46 @@
- }
- }
-
-+void DFA::compute_perms_table_ent(State *state, size_t pos,
-+ vector <aa_perms> &perms_table,
-+ bool prompt)
-+{
-+ uint32_t accept1, accept2, accept3;
-+
-+ // until front end doesn't map the way it does
-+ state->map_perms_to_accept(accept1, accept2, accept3, prompt);
-+ if (filedfa) {
-+ state->idx = pos * 2;
-+ perms_table[pos*2] = compute_fperms_user(accept1, accept2, accept3);
-+ perms_table[pos*2 + 1] = compute_fperms_other(accept1, accept2, accept3);
-+ } else {
-+ state->idx = pos;
-+ perms_table[pos] = compute_perms_entry(accept1, accept2, accept3);
-+ }
-+}
-+
-+void DFA::compute_perms_table(vector <aa_perms> &perms_table, bool prompt)
-+{
-+ size_t mult = filedfa ? 2 : 1;
-+ size_t pos = 2;
-+
-+ assert(states.size() >= 2);
-+ perms_table.resize(states.size() * mult);
-+
-+ // nonmatching and start need to be 0 and 1 so handle outside of loop
-+ if (filedfa)
-+ compute_perms_table_ent(nonmatching, 0, perms_table, prompt);
-+ compute_perms_table_ent(start, 1, perms_table, prompt);
-+
-+ for (Partition::iterator i = states.begin(); i != states.end(); i++) {
-+ if (*i == nonmatching || *i == start)
-+ continue;
-+ compute_perms_table_ent(*i, pos, perms_table, prompt);
-+ pos++;
-+ }
-+}
-+
-+
- #if 0
- typedef set <ImportantNode *>AcceptNodes;
- map<ImportantNode *, AcceptNodes> dominance(DFA & dfa)
-@@ -1329,7 +1376,7 @@
- }
- #endif
-
--static inline int diff_qualifiers(uint32_t perm1, uint32_t perm2)
-+static inline int diff_qualifiers(perm32_t perm1, perm32_t perm2)
- {
- return ((perm1 & AA_EXEC_TYPE) && (perm2 & AA_EXEC_TYPE) &&
- (perm1 & AA_EXEC_TYPE) != (perm2 & AA_EXEC_TYPE));
-@@ -1343,8 +1390,9 @@
- int accept_perms(NodeVec *state, perms_t &perms, bool filedfa)
- {
- int error = 0;
-- uint32_t exact_match_allow = 0;
-- uint32_t exact_audit = 0;
-+ perm32_t exact_match_allow = 0;
-+ perm32_t exact_match_prompt = 0;
-+ perm32_t exact_audit = 0;
-
- perms.clear();
-
-@@ -1359,26 +1407,31 @@
- if (match->is_type(NODE_TYPE_EXACTMATCHFLAG)) {
- /* exact match only ever happens with x */
- if (filedfa && !is_merged_x_consistent(exact_match_allow,
-- match->flag))
-+ match->perms))
- error = 1;;
-- exact_match_allow |= match->flag;
-+ exact_match_allow |= match->perms;
- exact_audit |= match->audit;
- } else if (match->is_type(NODE_TYPE_DENYMATCHFLAG)) {
-- perms.deny |= match->flag;
-+ perms.deny |= match->perms;
- perms.quiet |= match->audit;
-+ } else if (dynamic_cast<PromptMatchFlag *>(match)) {
-+ perms.prompt |= match->perms;
-+ perms.audit |= match->audit;
- } else {
-- if (filedfa && !is_merged_x_consistent(perms.allow, match->flag))
-+ if (filedfa && !is_merged_x_consistent(perms.allow, match->perms))
- error = 1;
-- perms.allow |= match->flag;
-+ perms.allow |= match->perms;
- perms.audit |= match->audit;
- }
- }
-
- if (filedfa) {
- perms.allow |= exact_match_allow & ~(ALL_AA_EXEC_TYPE);
-+ perms.prompt |= exact_match_prompt & ~(ALL_AA_EXEC_TYPE);
- perms.audit |= exact_audit & ~(ALL_AA_EXEC_TYPE);
- } else {
- perms.allow |= exact_match_allow;
-+ perms.prompt |= exact_match_prompt;
- perms.audit |= exact_audit;
- }
- if (exact_match_allow & AA_USER_EXEC) {
-@@ -1399,6 +1452,8 @@
-
- perms.allow &= ~perms.deny;
- perms.quiet &= perms.deny;
-+ perms.prompt &= ~perms.deny;
-+ perms.prompt &= ~perms.allow;
-
- if (error)
- fprintf(stderr, "profile has merged rule with conflicting x modifiers\n");
---- apparmor-4.0.0-beta4.orig/parser/libapparmor_re/hfa.h
-+++ apparmor-4.0.0-beta4/parser/libapparmor_re/hfa.h
-@@ -27,11 +27,15 @@
- #include <list>
- #include <map>
- #include <vector>
-+#include <iostream>
-
- #include <assert.h>
- #include <stdint.h>
-
- #include "expr-tree.h"
-+#include "policy_compat.h"
-+#include "../rule.h"
-+extern int prompt_compat_mode;
-
- #define DiffEncodeFlag 1
-
-@@ -49,16 +53,16 @@
- public:
- perms_t(void): allow(0), deny(0), audit(0), quiet(0), exact(0) { };
-
-- bool is_accept(void) { return (allow | audit | quiet); }
-+ bool is_accept(void) { return (allow | prompt | audit | quiet); }
-
- void dump(ostream &os)
- {
- os << " (0x " << hex
-- << allow << "/" << deny << "/" << audit << "/" << quiet
-+ << allow << "/" << deny << "/" << "/" << prompt << "/" << audit << "/" << quiet
- << ')' << dec;
- }
-
-- void clear(void) { allow = deny = audit = quiet = 0; }
-+ void clear(void) { allow = deny = prompt = audit = quiet = 0; }
- void add(perms_t &rhs, bool filedfa)
- {
- deny |= rhs.deny;
-@@ -95,6 +99,7 @@
- allow = (allow | (rhs.allow & ~ALL_AA_EXEC_TYPE));
- else
- allow |= rhs.allow;
-+ prompt |= rhs.prompt;
- audit |= rhs.audit;
- quiet = (quiet | rhs.quiet);
-
-@@ -112,6 +117,7 @@
- {
- if (deny) {
- allow &= ~deny;
-+ prompt &= ~deny;
- quiet &= deny;
- deny = 0;
- return !is_accept();
-@@ -125,12 +131,14 @@
- return allow < rhs.allow;
- if (deny < rhs.deny)
- return deny < rhs.deny;
-+ if (prompt < rhs.prompt)
-+ return prompt < rhs.prompt;
- if (audit < rhs.audit)
- return audit < rhs.audit;
- return quiet < rhs.quiet;
- }
-
-- uint32_t allow, deny, audit, quiet, exact;
-+ perm32_t allow, deny, prompt, audit, quiet, exact;
- };
-
- int accept_perms(NodeVec *state, perms_t &perms, bool filedfa);
-@@ -198,7 +206,7 @@
- class State {
- public:
- State(int l, ProtoState &n, State *other, bool filedfa):
-- label(l), flags(0), perms(), trans()
-+ label(l), flags(0), idx(0), perms(), trans()
- {
- int error;
-
-@@ -248,9 +256,20 @@
- void flatten_relative(State *, int upper_bound);
-
- int apply_and_clear_deny(void) { return perms.apply_and_clear_deny(); }
-+ void map_perms_to_accept(perm32_t &accept1, perm32_t &accept2,
-+ perm32_t &accept3, bool prompt)
-+ {
-+ accept1 = perms.allow;
-+ if (prompt && prompt_compat_mode == PROMPT_COMPAT_DEV)
-+ accept2 = PACK_AUDIT_CTL(perms.prompt, perms.quiet & perms.deny);
-+ else
-+ accept2 = PACK_AUDIT_CTL(perms.audit, perms.quiet & perms.deny);
-+ accept3 = perms.prompt;
-+ }
-
- int label;
- int flags;
-+ int idx;
- perms_t perms;
- StateTrans trans;
- State *otherwise;
-@@ -298,7 +317,6 @@
- }
- };
-
--
- /* Transitions in the DFA. */
- class DFA {
- void dump_node_to_dfa(void);
-@@ -341,6 +359,12 @@
- map<transchar, transchar> equivalence_classes(optflags const &flags);
- void apply_equivalence_classes(map<transchar, transchar> &eq);
-
-+ void compute_perms_table_ent(State *state, size_t pos,
-+ vector <aa_perms> &perms_table,
-+ bool prompt);
-+ void compute_perms_table(vector <aa_perms> &perms_table,
-+ bool prompt);
-+
- unsigned int diffcount;
- int oob_range;
- int max_range;
---- /dev/null
-+++ apparmor-4.0.0-beta4/parser/libapparmor_re/policy_compat.cc
-@@ -0,0 +1,218 @@
-+/*
-+ * Copyright (c) 2022
-+ * Canonical, Ltd. (All rights reserved)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of version 2 of the GNU General Public
-+ * License published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, contact Novell, Inc. or Canonical
-+ * Ltd.
-+ */
-+/*
-+ * This is a set of functions to provide convertion from old style permission
-+ * mappings, to new style kernel mappings. It is based on the kernel to
-+ * as the kernel needs this for backwards compatibility. This allows the
-+ * userspace to convert to the new permission mapping without reworking
-+ * the internal dfa permission tracking.
-+ *
-+ * In the future this code will be converted to go the reverse direction
-+ * i.e. new mappings into old, which the parser will need for backwards
-+ * compat with old kernels.
-+ */
-+
-+#include <stdint.h>
-+#include <iostream>
-+
-+#include "policy_compat.h"
-+#include "../perms.h"
-+#include "../rule.h"
-+extern int prompt_compat_mode;
-+
-+
-+/* remap old accept table embedded permissions to separate permission table */
-+static uint32_t dfa_map_xindex(uint16_t mask)
-+{
-+ uint16_t old_index = (mask >> 10) & 0xf;
-+ uint32_t index = 0;
-+
-+ if (mask & 0x100)
-+ index |= AA_X_UNSAFE;
-+ if (mask & 0x200)
-+ index |= AA_X_INHERIT;
-+ if (mask & 0x80)
-+ index |= AA_X_UNCONFINED;
-+
-+ if (old_index == 1) {
-+ index |= AA_X_UNCONFINED;
-+ } else if (old_index == 2) {
-+ index |= AA_X_NAME;
-+ } else if (old_index == 3) {
-+ index |= AA_X_NAME | AA_X_CHILD;
-+ } else if (old_index) {
-+ index |= AA_X_TABLE;
-+ index |= old_index - 4;
-+ }
-+
-+ return index;
-+}
-+
-+/*
-+ * map old dfa inline permissions to new format
-+ */
-+#define dfa_user_allow(accept1) (((accept1) & 0x7f) | \
-+ ((accept1) & 0x80000000))
-+#define dfa_user_xbits(accept1) (((accept1) >> 7) & 0x7f)
-+#define dfa_user_audit(accept1, accept2) ((accept2) & 0x7f)
-+#define dfa_user_quiet(accept1, accept2) (((accept2) >> 7) & 0x7f)
-+#define dfa_user_xindex(accept1) \
-+ (dfa_map_xindex(accept1 & 0x3fff))
-+
-+#define dfa_other_allow(accept1) ((((accept1) >> 14) & \
-+ 0x7f) | \
-+ ((accept1) & 0x80000000))
-+#define dfa_other_xbits(accept1) \
-+ ((((accept1) >> 7) >> 14) & 0x7f)
-+#define dfa_other_audit(accept1, accept2) (((accept2) >> 14) & 0x7f)
-+#define dfa_other_quiet(accept1, accept2) \
-+ ((((accept2) >> 7) >> 14) & 0x7f)
-+#define dfa_other_xindex(accept1) \
-+ dfa_map_xindex((accept1 >> 14) & 0x3fff)
-+
-+/**
-+ * map_old_perms - map old file perms layout to the new layout
-+ * @old: permission set in old mapping
-+ *
-+ * Returns: new permission mapping
-+ */
-+static uint32_t map_old_perms(uint32_t old)
-+{
-+ uint32_t perm = old & 0xf;
-+
-+ if (old & AA_MAY_READ)
-+ perm |= AA_MAY_GETATTR | AA_MAY_OPEN;
-+ if (old & AA_MAY_WRITE)
-+ perm |= AA_MAY_SETATTR | AA_MAY_CREATE | AA_MAY_DELETE |
-+ AA_MAY_CHMOD | AA_MAY_CHOWN | AA_MAY_OPEN;
-+ if (old & 0x10)
-+ perm |= AA_MAY_LINK;
-+ /* the old mapping lock and link_subset flags where overlaid
-+ * and use was determined by part of a pair that they were in
-+ */
-+ if (old & 0x20)
-+ perm |= AA_MAY_LOCK | AA_LINK_SUBSET;
-+ if (old & 0x40) /* AA_EXEC_MMAP */
-+ perm |= AA_EXEC_MMAP;
-+
-+ return perm;
-+}
-+
-+static void compute_fperms_allow(struct aa_perms *perms, uint32_t accept1)
-+{
-+ perms->allow |= AA_MAY_GETATTR;
-+
-+ /* change_profile wasn't determined by ownership in old mapping */
-+ if (accept1 & 0x80000000)
-+ perms->allow |= AA_MAY_CHANGE_PROFILE;
-+ if (accept1 & 0x40000000)
-+ perms->allow |= AA_MAY_ONEXEC;
-+}
-+
-+struct aa_perms compute_fperms_user(uint32_t accept1, uint32_t accept2,
-+ uint32_t accept3)
-+{
-+ struct aa_perms perms = { };
-+
-+ perms.allow = map_old_perms(dfa_user_allow(accept1));
-+ perms.prompt = map_old_perms(dfa_user_allow(accept3));
-+ perms.audit = map_old_perms(dfa_user_audit(accept1, accept2));
-+ perms.quiet = map_old_perms(dfa_user_quiet(accept1, accept2));
-+ if (prompt_compat_mode != PROMPT_COMPAT_PERMSV1)
-+ perms.xindex = dfa_user_xindex(accept1);
-+
-+ compute_fperms_allow(&perms, accept1);
-+ perms.prompt &= ~(perms.allow | perms.deny);
-+ return perms;
-+}
-+
-+struct aa_perms compute_fperms_other(uint32_t accept1, uint32_t accept2,
-+ uint32_t accept3)
-+{
-+ struct aa_perms perms = { };
-+
-+ perms.allow = map_old_perms(dfa_other_allow(accept1));
-+ perms.prompt = map_old_perms(dfa_other_allow(accept3));
-+ perms.audit = map_old_perms(dfa_other_audit(accept1, accept2));
-+ perms.quiet = map_old_perms(dfa_other_quiet(accept1, accept2));
-+ if (prompt_compat_mode != PROMPT_COMPAT_PERMSV1)
-+ perms.xindex = dfa_other_xindex(accept1);
-+
-+ compute_fperms_allow(&perms, accept1);
-+ perms.prompt &= ~(perms.allow | perms.deny);
-+ return perms;
-+}
-+
-+static uint32_t map_other(uint32_t x)
-+{
-+ return ((x & 0x3) << 8) | /* SETATTR/GETATTR */
-+ ((x & 0x1c) << 18) | /* ACCEPT/BIND/LISTEN */
-+ ((x & 0x60) << 19); /* SETOPT/GETOPT */
-+}
-+
-+static uint32_t map_xbits(uint32_t x)
-+{
-+ return ((x & 0x1) << 7) |
-+ ((x & 0x7e) << 9);
-+}
-+
-+struct aa_perms compute_perms_entry(uint32_t accept1, uint32_t accept2,
-+ uint32_t accept3)
-+// don't need to worry about version internally within the parser
-+// uint32_t version)
-+{
-+ struct aa_perms perms = { };
-+
-+ perms.allow = dfa_user_allow(accept1);
-+ perms.prompt = dfa_user_allow(accept3);
-+ perms.audit = dfa_user_audit(accept1, accept2);
-+ perms.quiet = dfa_user_quiet(accept1, accept2);
-+
-+ /*
-+ * This mapping is convulated due to history.
-+ * v1-v4: only file perms, which are handled by compute_fperms
-+ * v5: added policydb which dropped user conditional to gain new
-+ * perm bits, but had to map around the xbits because the
-+ * userspace compiler was still munging them.
-+ * v9: adds using the xbits in policydb because the compiler now
-+ * supports treating policydb permission bits different.
-+ * Unfortunately there is no way to force auditing on the
-+ * perms represented by the xbits
-+ */
-+ perms.allow |= map_other(dfa_other_allow(accept1));
-+ // v9 encoding never rolled out. AA_MAY_LOCK needed to fix
-+ // non fs unix locking see kernel commit
-+ // 1cf26c3d2c4c apparmor: fix apparmor mediating locking non-fs unix sockets
-+ //if (VERSION_LE(version, v8))
-+ perms.allow |= AA_MAY_LOCK;
-+ //else
-+ // perms.allow |= map_xbits(dfa_user_xbits(dfa, state));
-+
-+ /*
-+ * for v5-v9 perm mapping in the policydb, the other set is used
-+ * to extend the general perm set
-+ */
-+ perms.prompt |= map_other(dfa_other_allow(accept3));
-+ perms.audit |= map_other(dfa_other_audit(accept1, accept2));
-+ perms.quiet |= map_other(dfa_other_quiet(accept1, accept2));
-+ //if (VERSION_GT(version, v8))
-+ // perms.quiet |= map_xbits(dfa_other_xbits(dfa, state));
-+
-+ return perms;
-+}
-+
---- /dev/null
-+++ apparmor-4.0.0-beta4/parser/libapparmor_re/policy_compat.h
-@@ -0,0 +1,25 @@
-+/*
-+ * Copyright (c) 2022
-+ * Canonical, Ltd. (All rights reserved)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of version 2 of the GNU General Public
-+ * License published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, contact Novell, Inc. or Canonical
-+ * Ltd.
-+ */
-+#ifndef __AA_POLICY_COMPAT_H
-+#define __AA_POLICY_COMPAT_H
-+
-+struct aa_perms compute_fperms_user(uint32_t accept1, uint32_t accept2, uint32_t accept3);
-+struct aa_perms compute_fperms_other(uint32_t accept1, uint32_t accept2, uint32_t accept3);
-+struct aa_perms compute_perms_entry(uint32_t accept1, uint32_t accept2, uint32_t accept3);
-+
-+#endif /* __AA_POLICY_COMPAT_H */
---- apparmor-4.0.0-beta4.orig/parser/mount.cc
-+++ apparmor-4.0.0-beta4/parser/mount.cc
-@@ -478,7 +478,7 @@
-
- mnt_rule::mnt_rule(struct cond_entry *src_conds, char *device_p,
- struct cond_entry *dst_conds unused, char *mnt_point_p,
-- perms_t perms_p):
-+ perm32_t perms_p):
- perms_rule_t(AA_CLASS_MOUNT),
- mnt_point(mnt_point_p), device(device_p), trans(NULL), opts(NULL),
- flagsv(0), opt_flagsv(0)
-@@ -784,7 +784,7 @@
-
- vec[3] = flagsbuf;
-
-- perms_t tmpperms, tmpaudit;
-+ perm32_t tmpperms, tmpaudit;
- if (opts) {
- tmpperms = AA_MATCH_CONT;
- tmpaudit = 0;
-@@ -797,7 +797,7 @@
- * if a data match is required this only has AA_MATCH_CONT perms
- * else it has full perms
- */
-- if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, tmpperms, tmpaudit, 4,
-+ if (!prof.policy.rules->add_rule_vec(rule_mode, tmpperms, tmpaudit, 4,
- vec, parseopts, false))
- goto fail;
- count++;
-@@ -808,7 +808,7 @@
- if (!build_mnt_opts(optsbuf, opts))
- goto fail;
- vec[4] = optsbuf.c_str();
-- if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms,
-+ if (!prof.policy.rules->add_rule_vec(rule_mode, perms,
- (audit == AUDIT_FORCE ? perms : 0),
- 5, vec, parseopts, false))
- goto fail;
-@@ -850,7 +850,7 @@
- opt_flags & MS_BIND_FLAGS))
- goto fail;
- vec[3] = flagsbuf;
-- if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0,
-+ if (!prof.policy.rules->add_rule_vec(rule_mode, perms, audit == AUDIT_FORCE ? perms : 0,
- 4, vec,
- parseopts, false))
- goto fail;
-@@ -907,7 +907,7 @@
- opt_flags & MS_MAKE_FLAGS))
- goto fail;
- vec[3] = flagsbuf;
-- if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0,
-+ if (!prof.policy.rules->add_rule_vec(rule_mode, perms, audit == AUDIT_FORCE ? perms : 0,
- 4, vec,
- parseopts, false))
- goto fail;
-@@ -950,7 +950,7 @@
- opt_flags & MS_MOVE_FLAGS))
- goto fail;
- vec[3] = flagsbuf;
-- if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0,
-+ if (!prof.policy.rules->add_rule_vec(rule_mode, perms, audit == AUDIT_FORCE ? perms : 0,
- 4, vec,
- parseopts, false))
- goto fail;
-@@ -993,7 +993,7 @@
- goto fail;
- vec[3] = flagsbuf;
-
-- perms_t tmpperms, tmpaudit;
-+ perm32_t tmpperms, tmpaudit;
- if (opts) {
- tmpperms = AA_MATCH_CONT;
- tmpaudit = 0;
-@@ -1002,7 +1002,7 @@
- tmpaudit = audit == AUDIT_FORCE ? perms : 0;
- }
- /* rule for match without required data || data MATCH_CONT */
-- if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, tmpperms, tmpaudit, 4,
-+ if (!prof.policy.rules->add_rule_vec(rule_mode, tmpperms, tmpaudit, 4,
- vec, parseopts, false))
- goto fail;
- count++;
-@@ -1013,7 +1013,7 @@
- if (!build_mnt_opts(optsbuf, opts))
- goto fail;
- vec[4] = optsbuf.c_str();
-- if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms,
-+ if (!prof.policy.rules->add_rule_vec(rule_mode, perms,
- audit == AUDIT_FORCE ? perms : 0,
- 5, vec, parseopts, false))
- goto fail;
-@@ -1105,7 +1105,7 @@
- if (!convert_entry(mntbuf, mnt_point))
- goto fail;
- vec[0] = mntbuf.c_str();
-- if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms,
-+ if (!prof.policy.rules->add_rule_vec(rule_mode, perms,
- (audit == AUDIT_FORCE ? perms : 0), 1, vec,
- parseopts, false))
- goto fail;
-@@ -1120,7 +1120,7 @@
- if (!clear_and_convert_entry(devbuf, device))
- goto fail;
- vec[1] = devbuf.c_str();
-- if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms,
-+ if (!prof.policy.rules->add_rule_vec(rule_mode, perms,
- (audit == AUDIT_FORCE ? perms : 0), 2, vec,
- parseopts, false))
- goto fail;
-@@ -1141,7 +1141,7 @@
- void mnt_rule::post_parse_profile(Profile &prof)
- {
- if (trans) {
-- perms_t perms = 0;
-+ perm32_t perms = 0;
- int n = add_entry_to_x_table(&prof, trans);
- if (!n) {
- PERROR("Profile %s has too many specified profile transitions.\n", prof.name);
---- apparmor-4.0.0-beta4.orig/parser/mount.h
-+++ apparmor-4.0.0-beta4/parser/mount.h
-@@ -152,7 +152,7 @@
-
- mnt_rule(struct cond_entry *src_conds, char *device_p,
- struct cond_entry *dst_conds unused, char *mnt_point_p,
-- perms_t perms_p);
-+ perm32_t perms_p);
- virtual ~mnt_rule()
- {
- free_value_list(opts);
-@@ -163,7 +163,7 @@
- }
-
- virtual bool valid_prefix(const prefixes &p, const char *&error) {
-- if (p.owner) {
-+ if (p.owner != OWNER_UNSPECIFIED) {
- error = "owner prefix not allowed on mount rules";
- return false;
- }
---- apparmor-4.0.0-beta4.orig/parser/mqueue.cc
-+++ apparmor-4.0.0-beta4/parser/mqueue.cc
-@@ -25,7 +25,7 @@
- #include <iostream>
- #include <sstream>
-
--int parse_mqueue_perms(const char *str_perms, perms_t *perms, int fail)
-+int parse_mqueue_perms(const char *str_perms, perm32_t *perms, int fail)
- {
- return parse_X_perms("mqueue", AA_VALID_MQUEUE_PERMS, str_perms, perms, fail);
- }
-@@ -86,7 +86,7 @@
- }
- }
-
--mqueue_rule::mqueue_rule(perms_t perms_p, struct cond_entry *conds, char *qname_p):
-+mqueue_rule::mqueue_rule(perm32_t perms_p, struct cond_entry *conds, char *qname_p):
- // mqueue uses multiple classes, arbitrary choice to represent group
- // withing the AST
- perms_rule_t(AA_CLASS_POSIX_MQUEUE),
-@@ -231,10 +231,10 @@
- /* store perms at name match so label doesn't need
- * to be checked
- */
-- if (!label && !prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, map_mqueue_perms(perms), audit == AUDIT_FORCE ? map_mqueue_perms(perms) : 0, 1, vec, parseopts, false))
-+ if (!label && !prof.policy.rules->add_rule_vec(rule_mode , map_mqueue_perms(perms), audit == AUDIT_FORCE ? map_mqueue_perms(perms) : 0, 1, vec, parseopts, false))
- goto fail;
- /* also provide label match with perm */
-- if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, map_mqueue_perms(perms), audit == AUDIT_FORCE ? map_mqueue_perms(perms) : 0, size, vec, parseopts, false))
-+ if (!prof.policy.rules->add_rule_vec(rule_mode, map_mqueue_perms(perms), audit == AUDIT_FORCE ? map_mqueue_perms(perms) : 0, size, vec, parseopts, false))
- goto fail;
- }
- }
-@@ -266,10 +266,10 @@
- }
-
- if (perms & AA_VALID_SYSV_MQ_PERMS) {
-- if (!label && !prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, map_mqueue_perms(perms), audit == AUDIT_FORCE ? map_mqueue_perms(perms) : 0, 1, vec, parseopts, false))
-+ if (!label && !prof.policy.rules->add_rule_vec(rule_mode, map_mqueue_perms(perms), audit == AUDIT_FORCE ? map_mqueue_perms(perms) : 0, 1, vec, parseopts, false))
- goto fail;
- /* also provide label match with perm */
-- if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, map_mqueue_perms(perms), audit == AUDIT_FORCE ? map_mqueue_perms(perms) : 0, size, vec, parseopts, false))
-+ if (!prof.policy.rules->add_rule_vec(rule_mode, map_mqueue_perms(perms), audit == AUDIT_FORCE ? map_mqueue_perms(perms) : 0, size, vec, parseopts, false))
- goto fail;
- }
- }
---- apparmor-4.0.0-beta4.orig/parser/mqueue.h
-+++ apparmor-4.0.0-beta4/parser/mqueue.h
-@@ -84,7 +84,7 @@
- ((mask & (AA_MQUEUE_GETATTR | AA_MQUEUE_SETATTR)) << (AA_OTHER_SHIFT - 8));
- }
-
--int parse_mqueue_perms(const char *str_perms, perms_t *perms, int fail);
-+int parse_mqueue_perms(const char *str_perms, perm32_t *perms, int fail);
-
- class mqueue_rule: public perms_rule_t {
- void move_conditionals(struct cond_entry *conds);
-@@ -93,7 +93,7 @@
- char *qname;
- char *label;
-
-- mqueue_rule(perms_t perms, struct cond_entry *conds, char *qname = NULL);
-+ mqueue_rule(perm32_t perms, struct cond_entry *conds, char *qname = NULL);
- virtual ~mqueue_rule()
- {
- free(qname);
---- apparmor-4.0.0-beta4.orig/parser/network.cc
-+++ apparmor-4.0.0-beta4/parser/network.cc
-@@ -29,7 +29,7 @@
-
- #define ALL_TYPES 0x43e
-
--int parse_net_perms(const char *str_mode, perms_t *mode, int fail)
-+int parse_net_perms(const char *str_mode, perm32_t *mode, int fail)
- {
- return parse_X_perms("net", AA_VALID_NET_PERMS, str_mode, mode, fail);
- }
-@@ -401,7 +401,7 @@
- network_perms[family].second |= protocol;
- }
-
--network_rule::network_rule(perms_t perms_p, struct cond_entry *conds,
-+network_rule::network_rule(perm32_t perms_p, struct cond_entry *conds,
- struct cond_entry *peer_conds):
- dedup_perms_rule_t(AA_CLASS_NETV8), label(NULL)
- {
-@@ -441,7 +441,7 @@
- }
- }
-
--network_rule::network_rule(perms_t perms_p, const char *family, const char *type,
-+network_rule::network_rule(perm32_t perms_p, const char *family, const char *type,
- const char *protocol, struct cond_entry *conds,
- struct cond_entry *peer_conds):
- dedup_perms_rule_t(AA_CLASS_NETV8), label(NULL)
-@@ -494,7 +494,7 @@
- }
- }
-
--network_rule::network_rule(perms_t perms_p, unsigned int family, unsigned int type):
-+network_rule::network_rule(perm32_t perms_p, unsigned int family, unsigned int type):
- dedup_perms_rule_t(AA_CLASS_NETV8), label(NULL)
- {
- network_map[family].push_back({ family, type, 0xFFFFFFFF });
-@@ -653,7 +653,7 @@
- bool network_rule::gen_ip_conds(Profile &prof, std::list<std::ostringstream> &streams, ip_conds &entry, bool is_peer, bool is_cmd)
- {
- std::string buf;
-- perms_t cond_perms;
-+ perm32_t cond_perms;
- std::list<std::ostringstream> ip_streams;
-
- for (auto &oss : streams) {
-@@ -697,7 +697,7 @@
-
- buf = oss.str();
- /* AA_CONT_MATCH mapping (cond_perms) only applies to perms, not audit */
-- if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, cond_perms,
-+ if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode, cond_perms,
- dedup_perms_rule_t::audit == AUDIT_FORCE ? map_perms(perms) : 0,
- parseopts))
- return false;
-@@ -710,7 +710,7 @@
- oss << "\\x00"; /* null transition */
-
- buf = oss.str();
-- if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, cond_perms,
-+ if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode, cond_perms,
- dedup_perms_rule_t::audit == AUDIT_FORCE ? map_perms(perms) : 0,
- parseopts))
- return false;
-@@ -735,7 +735,7 @@
-
- if (!features_supports_inet || (family != AF_INET && family != AF_INET6)) {
- buf = buffer.str();
-- if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, map_perms(perms),
-+ if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode, map_perms(perms),
- dedup_perms_rule_t::audit == AUDIT_FORCE ? map_perms(perms) : 0,
- parseopts))
- return false;
-@@ -745,7 +745,7 @@
- buf = buffer.str();
- /* create perms need to be generated excluding the rest of the perms */
- if (perms & AA_NET_CREATE) {
-- if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, map_perms(perms & AA_NET_CREATE) | (AA_CONT_MATCH << 1),
-+ if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode, map_perms(perms & AA_NET_CREATE) | (AA_CONT_MATCH << 1),
- dedup_perms_rule_t::audit == AUDIT_FORCE ? map_perms(perms & AA_NET_CREATE) : 0,
- parseopts))
- return false;
-@@ -797,7 +797,7 @@
- /* length of queue allowed - not used for now */
- listen_buffer << "..";
- buf = listen_buffer.str();
-- if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, map_perms(perms),
-+ if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode, map_perms(perms),
- dedup_perms_rule_t::audit == AUDIT_FORCE ? map_perms(perms) : 0,
- parseopts))
- return false;
-@@ -816,7 +816,7 @@
- /* socket mapping - not used for now */
- opt_buffer << "..";
- buf = opt_buffer.str();
-- if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, map_perms(perms),
-+ if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode, map_perms(perms),
- dedup_perms_rule_t::audit == AUDIT_FORCE ? map_perms(perms) : 0,
- parseopts))
- return false;
---- apparmor-4.0.0-beta4.orig/parser/network.h
-+++ apparmor-4.0.0-beta4/parser/network.h
-@@ -107,8 +107,9 @@
- ((mask & (AA_NET_SETOPT | AA_NET_GETOPT)) >> 5); /* 5 + (AA_OTHER_SHIFT - 24) */
- };
-
--int parse_net_perms(const char *str_mode, perms_t *perms, int fail);
-+
- size_t get_af_max();
-+int parse_net_perms(const char *str_mode, perm32_t *perms, int fail);
- int net_find_type_val(const char *type);
- const char *net_find_type_name(int type);
- const char *net_find_af_name(unsigned int af);
-@@ -158,12 +159,12 @@
- * static elements to maintain compatibility with
- * AA_CLASS_NET */
- network_rule(): dedup_perms_rule_t(AA_CLASS_NETV8), label(NULL) { }
-- network_rule(perms_t perms_p, struct cond_entry *conds,
-+ network_rule(perm32_t perms_p, struct cond_entry *conds,
- struct cond_entry *peer_conds);
-- network_rule(perms_t perms_p, const char *family, const char *type,
-+ network_rule(perm32_t perms_p, const char *family, const char *type,
- const char *protocol, struct cond_entry *conds,
- struct cond_entry *peer_conds);
-- network_rule(perms_t perms_p, unsigned int family, unsigned int type);
-+ network_rule(perm32_t perms_p, unsigned int family, unsigned int type);
- virtual ~network_rule()
- {
- peer.free_conds();
---- apparmor-4.0.0-beta4.orig/parser/parser.h
-+++ apparmor-4.0.0-beta4/parser/parser.h
-@@ -122,7 +122,7 @@
- char *nt_name;
- Profile *prof; /* Special profile defined
- * just for this executable */
-- perms_t perms; /* perms is 'or' of AA_* bits */
-+ perm32_t perms; /* perms is 'or' of AA_* bits */
- audit_t audit;
- rule_mode_t rule_mode;
-
-@@ -324,6 +324,7 @@
- /* The parser fills this variable in automatically */
- #define PROFILE_NAME_VARIABLE "profile_name"
-
-+
- /* from parser_common.c */
- extern uint32_t policy_version;
- extern uint32_t parser_abi_version;
-@@ -358,6 +359,10 @@
- extern int features_supports_flag_interruptible;
- extern int features_supports_flag_signal;
- extern int kernel_supports_oob;
-+extern int kernel_supports_promptdev;
-+extern int kernel_supports_permstable32;
-+extern int kernel_supports_permstable32_v1;
-+extern int prompt_compat_mode;
- extern int conf_verbose;
- extern int conf_quiet;
- extern int names_only;
-@@ -373,6 +378,10 @@
-
- extern void pwarnf(bool werr, const char *fmt, ...) __attribute__((__format__(__printf__, 2, 3)));
- extern void common_warn_once(const char *name, const char *msg, const char **warned_name);
-+bool prompt_compat_mode_supported(int mode);
-+int default_prompt_compat_mode();
-+void print_prompt_compat_mode(FILE *f);
-+
-
- #define pwarn(F, args...) do { if (parseopts.warn & (F)) pwarnf((parseopts.Werror & (F)), ## args); } while (0)
-
-@@ -448,12 +457,12 @@
- extern int get_keyword_token(const char *keyword);
- extern int get_rlimit(const char *name);
- extern char *process_var(const char *var);
--extern perms_t parse_perms(const char *permstr);
--extern int parse_X_perms(const char *X, int valid, const char *str_perms, perms_t *perms, int fail);
-+extern perm32_t parse_perms(const char *permstr);
-+extern int parse_X_perms(const char *X, int valid, const char *str_perms, perm32_t *perms, int fail);
- bool label_contains_ns(const char *label);
- bool parse_label(bool *_stack, char **_ns, char **_name,
- const char *label, bool yyerr);
--extern struct cod_entry *new_entry(char *id, perms_t perms, char *link_id);
-+extern struct cod_entry *new_entry(char *id, perm32_t perms, char *link_id);
-
- /* returns -1 if value != true or false, otherwise 0 == false, 1 == true */
- extern int str_to_boolean(const char* str);
---- apparmor-4.0.0-beta4.orig/parser/parser_common.c
-+++ apparmor-4.0.0-beta4/parser/parser_common.c
-@@ -86,6 +86,10 @@
- int features_supports_flag_interruptible = 0;
- int features_supports_flag_signal = 0;
- int kernel_supports_oob = 0; /* out of band transitions */
-+int kernel_supports_promptdev = 0; /* prompt via audit perms */
-+int kernel_supports_permstable32 = 0; /* extended permissions */
-+int kernel_supports_permstable32_v1 = 0; /* extended permissions */
-+int prompt_compat_mode = PROMPT_COMPAT_UNKNOWN;
- int conf_verbose = 0;
- int conf_quiet = 0;
- int names_only = 0;
-@@ -165,3 +169,65 @@
- if (parseopts.Werror & WARN_RULE_NOT_ENFORCED)
- exit(1);
- }
-+
-+bool prompt_compat_mode_supported(int mode)
-+{
-+ if (mode == PROMPT_COMPAT_PERMSV2 &&
-+ (kernel_supports_permstable32 && !kernel_supports_permstable32_v1))
-+ return true;
-+ /*
-+ else if (mode == PROMPT_COMPAT_DEV &&
-+ kernel_supports_promptdev)
-+ return true;
-+ */
-+ else if (mode == PROMPT_COMPAT_FLAG &&
-+ kernel_supports_permstable32)
-+ return true;
-+ /*
-+ else if (mode == PROMPT_COMPAT_PERMSV1 &&
-+ (kernel_supports_permstable32_v1))
-+ return true;
-+ */
-+ else if (mode == PROMPT_COMPAT_IGNORE)
-+ return true;
-+
-+ return false;
-+}
-+
-+int default_prompt_compat_mode()
-+{
-+ if (prompt_compat_mode_supported(PROMPT_COMPAT_PERMSV2))
-+ return PROMPT_COMPAT_PERMSV2;
-+ if (prompt_compat_mode_supported(PROMPT_COMPAT_DEV))
-+ return PROMPT_COMPAT_DEV;
-+ if (prompt_compat_mode_supported(PROMPT_COMPAT_FLAG))
-+ return PROMPT_COMPAT_FLAG;
-+ if (prompt_compat_mode_supported(PROMPT_COMPAT_PERMSV1))
-+ return PROMPT_COMPAT_PERMSV1;
-+ if (prompt_compat_mode_supported(PROMPT_COMPAT_IGNORE))
-+ return PROMPT_COMPAT_IGNORE;
-+ return PROMPT_COMPAT_IGNORE;
-+}
-+
-+void print_prompt_compat_mode(FILE *f)
-+{
-+ switch (prompt_compat_mode) {
-+ case PROMPT_COMPAT_IGNORE:
-+ fprintf(f, "ignore");
-+ break;
-+ case PROMPT_COMPAT_FLAG:
-+ fprintf(f, "flag");
-+ break;
-+ case PROMPT_COMPAT_PERMSV2:
-+ fprintf(f, "permsv2");
-+ break;
-+ case PROMPT_COMPAT_PERMSV1:
-+ fprintf(f, "permsv1");
-+ break;
-+ case PROMPT_COMPAT_DEV:
-+ fprintf(stderr, "dev");
-+ break;
-+ default:
-+ fprintf(f, "Unknown prompt compat mode '%d'", prompt_compat_mode);
-+ }
-+}
---- apparmor-4.0.0-beta4.orig/parser/parser_interface.c
-+++ apparmor-4.0.0-beta4/parser/parser_interface.c
-@@ -323,10 +323,49 @@
- sd_write8(buf, SD_LISTEND);
- }
-
--void sd_serialize_dfa(std::ostringstream &buf, void *dfa, size_t size)
-+void sd_serialize_perm(std::ostringstream &buf, aa_perms &perms)
- {
-- if (dfa)
-+ sd_write_uint32(buf, 0); /* reserved */
-+ sd_write_uint32(buf, perms.allow);
-+ sd_write_uint32(buf, perms.deny);
-+ sd_write_uint32(buf, perms.subtree);
-+ sd_write_uint32(buf, perms.cond);
-+ sd_write_uint32(buf, perms.kill);
-+ sd_write_uint32(buf, perms.complain);
-+ sd_write_uint32(buf, perms.prompt);
-+ sd_write_uint32(buf, perms.audit);
-+ sd_write_uint32(buf, perms.quiet);
-+ sd_write_uint32(buf, perms.hide);
-+ sd_write_uint32(buf, perms.xindex);
-+ sd_write_uint32(buf, perms.tag);
-+ sd_write_uint32(buf, perms.label);
-+}
-+
-+void sd_serialize_permstable(std::ostringstream &buf, vector <aa_perms> &perms_table)
-+{
-+ sd_write_struct(buf, "perms");
-+ sd_write_name(buf, "version");
-+ sd_write_uint32(buf, 1);
-+ sd_write_array(buf, NULL, perms_table.size());
-+ for (size_t i = 0; i < perms_table.size(); i++) {
-+ sd_serialize_perm(buf, perms_table[i]);
-+ }
-+ sd_write_arrayend(buf);
-+ sd_write_structend(buf);
-+}
-+
-+void sd_serialize_dfa(std::ostringstream &buf, void *dfa, size_t size,
-+ vector <aa_perms> &perms_table)
-+{
-+ if (dfa) {
-+ if (kernel_supports_permstable32 && perms_table.size() > 0) {
-+ //fprintf(stderr, "writing perms table %d\n", size);
-+ sd_serialize_permstable(buf, perms_table);
-+ } else {
-+ //fprintf(stderr, "skipping permtable32 %d, size %d\n", kernel_supports_permstable32, perms_table.size());
-+ }
- sd_write_aligned_blob(buf, dfa, size, "aadfa");
-+ }
- }
-
- void sd_serialize_rlimits(std::ostringstream &buf, struct aa_rlimits *limits)
-@@ -344,10 +383,13 @@
- sd_write_structend(buf);
- }
-
--void sd_serialize_xtable(std::ostringstream &buf, char **table)
-+void sd_serialize_xtable(std::ostringstream &buf, char **table,
-+ size_t min_size)
- {
-- int count;
-- if (!table[4])
-+ size_t count;
-+ size_t size;
-+
-+ if (!table[4] && min_size == 0)
- return;
- sd_write_struct(buf, "xtable");
- count = 0;
-@@ -356,9 +398,11 @@
- count++;
- }
-
-- sd_write_array(buf, NULL, count);
-- for (int i = 4; i < count + 4; i++) {
-- int len = strlen(table[i]) + 1;
-+ size = max(min_size, count);
-+
-+ sd_write_array(buf, NULL, size);
-+ for (size_t i = 4; i < count + 4; i++) {
-+ size_t len = strlen(table[i]) + 1;
-
- /* if its a namespace make sure the second : is overwritten
- * with 0, so that the namespace and name are \0 separated
-@@ -369,6 +413,14 @@
- }
- sd_write_strn(buf, table[i], len, NULL);
- }
-+ if (min_size > count) {
-+ //fprintf(stderr, "Adding padding to xtable count %lu, min %lu\n", count, min_size);
-+ for (; count < min_size; count++) {
-+ /* fill with null strings */
-+ sd_write_strn(buf, "\000", 1, NULL);
-+ }
-+ }
-+
- sd_write_arrayend(buf);
- sd_write_structend(buf);
- }
-@@ -411,7 +463,7 @@
- /* only emit this if current kernel at least supports "create" */
- if (perms_create) {
- if (profile->xmatch) {
-- sd_serialize_dfa(buf, profile->xmatch, profile->xmatch_size);
-+ sd_serialize_dfa(buf, profile->xmatch, profile->xmatch_size, profile->xmatch_perms_table);
- sd_write_uint32(buf, profile->xmatch_len);
- }
- }
-@@ -485,14 +537,42 @@
-
- if (profile->policy.dfa) {
- sd_write_struct(buf, "policydb");
-- sd_serialize_dfa(buf, profile->policy.dfa, profile->policy.size);
-+ sd_serialize_dfa(buf, profile->policy.dfa, profile->policy.size,
-+ profile->policy.perms_table);
-+ if (kernel_supports_permstable32) {
-+ // fprintf(stderr, "profile %s: policy xtable\n", profile->name);
-+ // TODO: this is dummy exec make dependent on V1
-+ sd_serialize_xtable(buf, profile->exec_table,
-+ profile->uses_prompt_rules && prompt_compat_mode == PROMPT_COMPAT_PERMSV1 ?
-+ profile->policy.perms_table.size() : 0);
-+ }
- sd_write_structend(buf);
- }
-
- /* either have a single dfa or lists of different entry types */
-- sd_serialize_dfa(buf, profile->dfa.dfa, profile->dfa.size);
-- sd_serialize_xtable(buf, profile->exec_table);
--
-+ if (profile->uses_prompt_rules && prompt_compat_mode == PROMPT_COMPAT_PERMSV1) {
-+ /* special compat mode to work around verification problem */
-+ sd_serialize_dfa(buf, profile->policy.dfa, profile->policy.size,
-+ profile->policy.perms_table);
-+ sd_write_name(buf, "dfa_start");
-+ sd_write_uint32(buf, profile->policy.file_start);
-+ if (profile->policy.dfa) {
-+ // fprintf(stderr, "profile %s: policy xtable\n", profile->name);
-+ // TODO: this is dummy exec make dependent on V1
-+ sd_serialize_xtable(buf, profile->exec_table,
-+ //permstable32_v1 workaround
-+ profile->policy.perms_table.size());
-+ }
-+ } else {
-+ sd_serialize_dfa(buf, profile->dfa.dfa, profile->dfa.size,
-+ profile->dfa.perms_table);
-+ if (profile->dfa.dfa) {
-+ // fprintf(stderr, "profile %s: dfa xtable\n", profile->name);
-+ sd_serialize_xtable(buf, profile->exec_table,
-+ //??? work around
-+ profile->dfa.perms_table.size());
-+ }
-+ }
- sd_write_structend(buf);
- }
-
---- apparmor-4.0.0-beta4.orig/parser/parser_main.c
-+++ apparmor-4.0.0-beta4/parser/parser_main.c
-@@ -137,6 +137,8 @@
- #define EARLY_ARG_CONFIG_FILE 142
- #define ARG_WERROR 143
- #define ARG_ESTIMATED_COMPILE_SIZE 144
-+#define ARG_PROMPT_COMPAT 145
-+#define ARG_PRINT_PROMPT_COMPAT 146
-
- /* Make sure to update BOTH the short and long_options */
- static const char *short_options = "ad::f:h::rRVvI:b:BCD:NSm:M:qQn:XKTWkL:O:po:j:";
-@@ -192,6 +194,8 @@
- {"override-policy-abi", 1, 0, ARG_OVERRIDE_POLICY_ABI}, /* no short option */
- {"config-file", 1, 0, EARLY_ARG_CONFIG_FILE}, /* early option, no short option */
- {"estimated-compile-size", 1, 0, ARG_ESTIMATED_COMPILE_SIZE}, /* no short option, not in help */
-+ {"prompt-compat", 1, 0, ARG_PROMPT_COMPAT}, /* no short option */
-+ {"print-prompt-compat", 1, 0, ARG_PRINT_PROMPT_COMPAT}, /* no short option */
-
- {NULL, 0, 0, 0},
- };
-@@ -789,6 +793,30 @@
- estimated_job_size = tmp * mult;
- }
- break;
-+ case ARG_PROMPT_COMPAT:
-+ if (strcmp(optarg, "permsv2") == 0) {
-+ prompt_compat_mode = PROMPT_COMPAT_PERMSV2;
-+ } else if (strcmp(optarg, "permsv1") == 0) {
-+ prompt_compat_mode = PROMPT_COMPAT_PERMSV1;
-+ } else if (strcmp(optarg, "default") == 0) {
-+ prompt_compat_mode = default_prompt_compat_mode();
-+ } else if (strcmp(optarg, "dev") == 0) {
-+ prompt_compat_mode = PROMPT_COMPAT_DEV;
-+ } else if (strcmp(optarg, "ignore") == 0) {
-+ prompt_compat_mode = PROMPT_COMPAT_IGNORE;
-+ } else if (strcmp(optarg, "flag") == 0) {
-+ prompt_compat_mode = PROMPT_COMPAT_FLAG;
-+ } else {
-+ PERROR("%s: Invalid --prompt-compat option '%s'\n",
-+ progname, optarg);
-+ exit(1);
-+ }
-+ break;
-+ case ARG_PRINT_PROMPT_COMPAT:
-+ fprintf(stderr, "Prompt compat mode: ");
-+ print_prompt_compat_mode(stderr);
-+ fprintf(stderr, "\n");
-+ break;
- default:
- /* 'unrecognized option' error message gets printed by getopt_long() */
- exit(1);
-@@ -1541,6 +1569,20 @@
- else if (aa_features_supports(*features, "policy/versions/v6"))
- kernel_abi_version = 6;
-
-+ kernel_supports_promptdev = aa_features_supports(*features, "policy/perms_compatprompt");
-+ kernel_supports_permstable32 = aa_features_supports(*features, "policy/permstable32");
-+ if (kernel_supports_permstable32) {
-+ //fprintf(stderr, "kernel supports prompt\n");
-+ }
-+ kernel_supports_permstable32_v1 = aa_features_supports(*features, "policy/permstable32_version/0x000001");
-+ if (kernel_supports_permstable32_v1) {
-+ //fprintf(stderr, "kernel supports prompt_v1\n");
-+ }
-+
-+ /* set default prompt_compat_mode to the best that is supported */
-+ if (prompt_compat_mode == PROMPT_COMPAT_UNKNOWN) {
-+ prompt_compat_mode = default_prompt_compat_mode();
-+ }
- if (!kernel_supports_diff_encode)
- /* clear diff_encode because it is not supported */
- parseopts.control &= ~CONTROL_DFA_DIFF_ENCODE;
---- apparmor-4.0.0-beta4.orig/parser/parser_misc.c
-+++ apparmor-4.0.0-beta4/parser/parser_misc.c
-@@ -97,6 +97,7 @@
- {"audit", TOK_AUDIT},
- {"deny", TOK_DENY},
- {"allow", TOK_ALLOW},
-+ {"prompt", TOK_PROMPT},
- {"set", TOK_SET},
- {"rlimit", TOK_RLIMIT},
- {"alias", TOK_ALIAS},
-@@ -565,12 +566,12 @@
- }
- }
-
--static perms_t parse_sub_perms(const char *str_perms, const char *perms_desc unused)
-+static perm32_t parse_sub_perms(const char *str_perms, const char *perms_desc unused)
- {
-
- #define IS_DIFF_QUAL(perms, q) (((perms) & AA_MAY_EXEC) && (((perms) & AA_EXEC_TYPE) != ((q) & AA_EXEC_TYPE)))
-
-- perms_t perms = 0;
-+ perm32_t perms = 0;
- const char *p;
-
- PDEBUG("Parsing perms: %s\n", str_perms);
-@@ -583,7 +584,7 @@
- char thisc = *p;
- char next = *(p + 1);
- char lower;
-- perms_t tperms = 0;
-+ perm32_t tperms = 0;
-
- reeval:
- switch (thisc) {
-@@ -741,9 +742,9 @@
- return perms;
- }
-
--perms_t parse_perms(const char *str_perms)
-+perm32_t parse_perms(const char *str_perms)
- {
-- perms_t tmp, perms = 0;
-+ perm32_t tmp, perms = 0;
- tmp = parse_sub_perms(str_perms, "");
- perms = SHIFT_PERMS(tmp, AA_USER_SHIFT);
- perms |= SHIFT_PERMS(tmp, AA_OTHER_SHIFT);
-@@ -752,9 +753,9 @@
- return perms;
- }
-
--static int parse_X_sub_perms(const char *X, const char *str_perms, perms_t *result, int fail, const char *perms_desc unused)
-+static int parse_X_sub_perms(const char *X, const char *str_perms, perm32_t *result, int fail, const char *perms_desc unused)
- {
-- perms_t perms = 0;
-+ perm32_t perms = 0;
- const char *p;
-
- PDEBUG("Parsing %s perms: %s\n", X, str_perms);
-@@ -812,7 +813,7 @@
- return 1;
- }
-
--int parse_X_perms(const char *X, int valid, const char *str_perms, perms_t *perms, int fail)
-+int parse_X_perms(const char *X, int valid, const char *str_perms, perm32_t *perms, int fail)
- {
- *perms = 0;
- if (!parse_X_sub_perms(X, str_perms, perms, fail, ""))
-@@ -975,7 +976,7 @@
- return false;
- }
-
--struct cod_entry *new_entry(char *id, perms_t perms, char *link_id)
-+struct cod_entry *new_entry(char *id, perm32_t perms, char *link_id)
- {
- struct cod_entry *entry = NULL;
-
---- apparmor-4.0.0-beta4.orig/parser/parser_policy.c
-+++ apparmor-4.0.0-beta4/parser/parser_policy.c
-@@ -240,6 +240,13 @@
- }
-
- error = post_process_policy_list(profile->hat_table, debug_only);
-+
-+ if (prompt_compat_mode == PROMPT_COMPAT_DEV && profile->uses_prompt_rules)
-+ profile->flags.flags |= FLAG_PROMPT_COMPAT;
-+
-+ else if (prompt_compat_mode == PROMPT_COMPAT_FLAG && profile->uses_prompt_rules)
-+ profile->flags.mode = MODE_PROMPT;
-+
- return error;
- }
-
---- apparmor-4.0.0-beta4.orig/parser/parser_regex.c
-+++ apparmor-4.0.0-beta4/parser/parser_regex.c
-@@ -507,7 +507,8 @@
- aare_rules *rules = new aare_rules();
- if (!rules)
- return FALSE;
-- if (!rules->add_rule(tbuf.c_str(), 0, AA_MAY_EXEC, 0, parseopts)) {
-+ if (!rules->add_rule(tbuf.c_str(), RULE_ALLOW,
-+ AA_MAY_EXEC, 0, parseopts)) {
- delete rules;
- return FALSE;
- }
-@@ -520,7 +521,9 @@
- ptype = convert_aaregex_to_pcre(alt->name, 0,
- glob_default,
- tbuf, &len);
-- if (!rules->add_rule(tbuf.c_str(), 0, AA_MAY_EXEC, 0, parseopts)) {
-+ if (!rules->add_rule(tbuf.c_str(),
-+ RULE_ALLOW, AA_MAY_EXEC,
-+ 0, parseopts)) {
- delete rules;
- return FALSE;
- }
-@@ -569,7 +572,13 @@
- }
- }
- build:
-- prof->xmatch = rules->create_dfa(&prof->xmatch_size, &prof->xmatch_len, parseopts, true);
-+ /* xmatch doesn't use file dfa exec mode bits NOT the owner
-+ * conditional and for just MAY_EXEC can be processed as
-+ * none file perms
-+ *
-+ * we don't need to build xmatch for permstable32, so don't
-+ */
-+ prof->xmatch = rules->create_dfablob(&prof->xmatch_size, &prof->xmatch_len, prof->xmatch_perms_table, parseopts, false, false, false);
- delete rules;
- if (!prof->xmatch)
- return FALSE;
-@@ -580,7 +589,7 @@
-
- static int warn_change_profile = 1;
-
--static bool is_change_profile_perms(perms_t perms)
-+static bool is_change_profile_perms(perm32_t perms)
- {
- /**
- * A change_profile entry will have the AA_CHANGE_PROFILE bit set.
-@@ -635,14 +644,14 @@
- if (entry->rule_mode == RULE_DENY) {
- if ((entry->perms & ~AA_LINK_BITS) &&
- !is_change_profile_perms(entry->perms) &&
-- !dfarules->add_rule(tbuf.c_str(), entry->rule_mode == RULE_DENY,
-+ !dfarules->add_rule(tbuf.c_str(), entry->rule_mode,
- entry->perms & ~(AA_LINK_BITS | AA_CHANGE_PROFILE),
- entry->audit == AUDIT_FORCE ? entry->perms & ~(AA_LINK_BITS | AA_CHANGE_PROFILE) : 0,
- parseopts))
- return FALSE;
- } else if (!is_change_profile_perms(entry->perms)) {
- if (!dfarules->add_rule(tbuf.c_str(),
-- entry->rule_mode == RULE_DENY, entry->perms,
-+ entry->rule_mode, entry->perms,
- entry->audit == AUDIT_FORCE ? entry->perms : 0,
- parseopts))
- return FALSE;
-@@ -667,7 +676,7 @@
- perms |= LINK_TO_LINK_SUBSET(perms);
- vec[1] = "/[^/].*";
- }
-- if (!dfarules->add_rule_vec(entry->rule_mode == RULE_DENY, perms, entry->audit == AUDIT_FORCE ? perms & AA_LINK_BITS : 0, 2, vec, parseopts, false))
-+ if (!dfarules->add_rule_vec(entry->rule_mode, perms, entry->audit == AUDIT_FORCE ? perms & AA_LINK_BITS : 0, 2, vec, parseopts, false))
- return FALSE;
- }
- if (is_change_profile_perms(entry->perms)) {
-@@ -718,13 +727,13 @@
- }
-
- /* regular change_profile rule */
-- if (!dfarules->add_rule_vec(entry->rule_mode == RULE_DENY,
-+ if (!dfarules->add_rule_vec(entry->rule_mode,
- AA_CHANGE_PROFILE | onexec_perms,
- 0, index - 1, &vec[1], parseopts, false))
- return FALSE;
-
- /* onexec rules - both rules are needed for onexec */
-- if (!dfarules->add_rule_vec(entry->rule_mode == RULE_DENY, onexec_perms,
-+ if (!dfarules->add_rule_vec(entry->rule_mode, onexec_perms,
- 0, 1, vec, parseopts, false))
- return FALSE;
-
-@@ -733,7 +742,7 @@
- * unsafe exec transitions
- */
- onexec_perms |= (entry->perms & (AA_EXEC_BITS | ALL_AA_EXEC_UNSAFE));
-- if (!dfarules->add_rule_vec(entry->rule_mode == RULE_DENY, onexec_perms,
-+ if (!dfarules->add_rule_vec(entry->rule_mode, onexec_perms,
- 0, index, vec, parseopts, false))
- return FALSE;
- }
-@@ -767,10 +776,17 @@
- if (!post_process_entries(prof))
- goto out;
-
-- if (prof->dfa.rules->rule_count > 0) {
-+ /* under permstable32_v1 we weld file and policydb together, so
-+ * don't create the file blob here
-+ */
-+ if (prof->dfa.rules->rule_count > 0 && prompt_compat_mode != PROMPT_COMPAT_PERMSV1) {
- int xmatch_len = 0;
-- prof->dfa.dfa = prof->dfa.rules->create_dfa(&prof->dfa.size,
-- &xmatch_len, parseopts, true);
-+ //fprintf(stderr, "Creating file DFA %d\n", kernel_supports_permstable32);
-+ prof->dfa.dfa = prof->dfa.rules->create_dfablob(&prof->dfa.size,
-+ &xmatch_len, prof->dfa.perms_table,
-+ parseopts, true,
-+ prof->uses_prompt_rules && (prompt_compat_mode == PROMPT_COMPAT_PERMSV2),
-+ prof->uses_prompt_rules);
- delete prof->dfa.rules;
- prof->dfa.rules = NULL;
- if (!prof->dfa.dfa)
-@@ -967,6 +983,80 @@
- return TRUE;
- }
-
-+
-+static bool gen_net_rule(Profile *prof, u16 family, unsigned int type_mask,
-+ bool audit, rule_mode_t rmode) {
-+ std::ostringstream buffer;
-+ std::string buf;
-+
-+ buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_NETV8;
-+ buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << ((family & 0xff00) >> 8);
-+ buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << (family & 0xff);
-+ if (type_mask > 0xffff) {
-+ buffer << "..";
-+ } else {
-+ buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << ((type_mask & 0xff00) >> 8);
-+ buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << (type_mask & 0xff);
-+ }
-+ buf = buffer.str();
-+ if (!prof->policy.rules->add_rule(buf.c_str(), rmode, map_perms(AA_VALID_NET_PERMS),
-+ audit ? map_perms(AA_VALID_NET_PERMS) : 0,
-+ parseopts))
-+ return false;
-+
-+ return true;
-+}
-+
-+static bool gen_af_rules(Profile *prof, u16 family, unsigned int type_mask,
-+ unsigned int audit_mask, rule_mode_t rmode)
-+{
-+ if (type_mask > 0xffff && audit_mask > 0xffff) {
-+ /* instead of generating multiple rules wild card type */
-+ return gen_net_rule(prof, family, type_mask, audit_mask, rmode);
-+ } else {
-+ int t;
-+ /* generate rules for types that are set */
-+ for (t = 0; t < 16; t++) {
-+ if (type_mask & (1 << t)) {
-+ if (!gen_net_rule(prof, family, t,
-+ audit_mask & (1 << t),
-+ rmode))
-+ return false;
-+ }
-+ }
-+ }
-+
-+ return true;
-+}
-+
-+bool post_process_policydb_net(Profile *prof)
-+{
-+ u16 af;
-+
-+ /* no network rules defined so we don't have generate them */
-+ if (!prof->net.allow)
-+ return true;
-+
-+ /* generate rules if the af has something set */
-+ for (af = AF_UNSPEC; af < get_af_max(); af++) {
-+ if (prof->net.allow[af] ||
-+ prof->net.deny[af] ||
-+ prof->net.audit[af] ||
-+ prof->net.quiet[af]) {
-+ if (!gen_af_rules(prof, af, prof->net.allow[af],
-+ prof->net.audit[af],
-+ { RULE_ALLOW}))
-+ return false;
-+ if (!gen_af_rules(prof, af, prof->net.deny[af],
-+ prof->net.quiet[af],
-+ { RULE_DENY}))
-+ return false;
-+ }
-+ }
-+
-+ return true;
-+}
-+
- #define MAKE_STR(X) #X
- #define CLASS_STR(X) "\\d" MAKE_STR(X)
- #define MAKE_SUB_STR(X) "\\000" MAKE_STR(X)
-@@ -984,6 +1074,7 @@
- static const char *mediates_posix_mqueue = CLASS_STR(AA_CLASS_POSIX_MQUEUE);
- static const char *mediates_sysv_mqueue = CLASS_STR(AA_CLASS_SYSV_MQUEUE);
- static const char *mediates_io_uring = CLASS_STR(AA_CLASS_IO_URING);
-+static const char *deny_file = ".*";
-
- int process_profile_policydb(Profile *prof)
- {
-@@ -1002,44 +1093,78 @@
-
- /* note: this activates fs based unix domain sockets mediation on connect */
- if (kernel_abi_version > 5 &&
-- !prof->policy.rules->add_rule(mediates_file, 0, AA_MAY_READ, 0, parseopts))
-+ !prof->policy.rules->add_rule(mediates_file, RULE_ALLOW, AA_MAY_READ, 0, parseopts))
- goto out;
- if (features_supports_mount &&
-- !prof->policy.rules->add_rule(mediates_mount, 0, AA_MAY_READ, 0, parseopts))
-+ !prof->policy.rules->add_rule(mediates_mount, RULE_ALLOW, AA_MAY_READ, 0, parseopts))
- goto out;
- if (features_supports_dbus &&
-- !prof->policy.rules->add_rule(mediates_dbus, 0, AA_MAY_READ, 0, parseopts))
-+ !prof->policy.rules->add_rule(mediates_dbus, RULE_ALLOW, AA_MAY_READ, 0, parseopts))
- goto out;
- if (features_supports_signal &&
-- !prof->policy.rules->add_rule(mediates_signal, 0, AA_MAY_READ, 0, parseopts))
-+ !prof->policy.rules->add_rule(mediates_signal, RULE_ALLOW, AA_MAY_READ, 0, parseopts))
- goto out;
- if (features_supports_ptrace &&
-- !prof->policy.rules->add_rule(mediates_ptrace, 0, AA_MAY_READ, 0, parseopts))
-+ !prof->policy.rules->add_rule(mediates_ptrace, RULE_ALLOW, AA_MAY_READ, 0, parseopts))
- goto out;
- if (features_supports_networkv8 &&
-- !prof->policy.rules->add_rule(mediates_netv8, 0, AA_MAY_READ, 0, parseopts))
-+ !prof->policy.rules->add_rule(mediates_netv8, RULE_ALLOW, AA_MAY_READ, 0, parseopts))
- goto out;
- if (features_supports_unix &&
-- (!prof->policy.rules->add_rule(mediates_extended_net, 0, AA_MAY_READ, 0, parseopts) ||
-- !prof->policy.rules->add_rule(mediates_net_unix, 0, AA_MAY_READ, 0, parseopts)))
-+ (!prof->policy.rules->add_rule(mediates_extended_net, RULE_ALLOW, AA_MAY_READ, 0, parseopts) ||
-+ !prof->policy.rules->add_rule(mediates_net_unix, RULE_ALLOW, AA_MAY_READ, 0, parseopts)))
- goto out;
- if (features_supports_userns &&
-- !prof->policy.rules->add_rule(mediates_ns, 0, AA_MAY_READ, 0, parseopts))
-+ !prof->policy.rules->add_rule(mediates_ns, RULE_ALLOW, AA_MAY_READ, 0, parseopts))
- goto out;
- if (features_supports_posix_mqueue &&
-- !prof->policy.rules->add_rule(mediates_posix_mqueue, 0, AA_MAY_READ, 0, parseopts))
-+ !prof->policy.rules->add_rule(mediates_posix_mqueue, RULE_ALLOW, AA_MAY_READ, 0, parseopts))
- goto out;
- if (features_supports_sysv_mqueue &&
-- !prof->policy.rules->add_rule(mediates_sysv_mqueue, 0, AA_MAY_READ, 0, parseopts))
-+ !prof->policy.rules->add_rule(mediates_sysv_mqueue, RULE_ALLOW, AA_MAY_READ, 0, parseopts))
- goto out;
- if (features_supports_io_uring &&
-- !prof->policy.rules->add_rule(mediates_io_uring, 0, AA_MAY_READ, 0, parseopts))
-+ !prof->policy.rules->add_rule(mediates_io_uring, RULE_ALLOW, AA_MAY_READ, 0, parseopts))
- goto out;
-
-- if (prof->policy.rules->rule_count > 0) {
-+ if (prompt_compat_mode == PROMPT_COMPAT_PERMSV1) {
-+ // MUST have file and policy
-+ // This requires file rule processing happen first
-+ if (!prof->dfa.rules->rule_count) {
-+ // add null dfa
-+ if (!prof->dfa.rules->add_rule(deny_file, RULE_DENY, AA_MAY_READ, 0, parseopts))
-+ goto out;
-+ }
-+ if (!prof->policy.rules->rule_count) {
-+ if (!prof->policy.rules->add_rule(mediates_file, RULE_DENY, AA_MAY_READ, 0, parseopts))
-+ goto out;
-+ }
-+ int xmatch_len = 0;
-+ prof->policy.dfa = prof->policy.rules->create_welded_dfablob(
-+ prof->dfa.rules,
-+ &prof->policy.size,
-+ &xmatch_len,
-+ &prof->policy.file_start,
-+ prof->policy.perms_table, parseopts,
-+ kernel_supports_permstable32_v1,
-+ prof->uses_prompt_rules);
-+ delete prof->policy.rules;
-+ delete prof->dfa.rules;
-+ prof->policy.rules = NULL;
-+ prof->dfa.rules = NULL;
-+ if (!prof->policy.dfa)
-+ goto out;
-+ } else if (prof->policy.rules->rule_count > 0 &&
-+ // yes not needed as covered above, just making sure
-+ // this doesn't get messed up in the future
-+ prompt_compat_mode != PROMPT_COMPAT_PERMSV1) {
- int xmatch_len = 0;
-- prof->policy.dfa = prof->policy.rules->create_dfa(&prof->policy.size,
-- &xmatch_len, parseopts, false);
-+ prof->policy.dfa = prof->policy.rules->create_dfablob(&prof->policy.size,
-+ &xmatch_len,
-+ prof->policy.perms_table,
-+ parseopts, false,
-+ prof->uses_prompt_rules && (prompt_compat_mode == PROMPT_COMPAT_PERMSV2),
-+ prof->uses_prompt_rules);
- delete prof->policy.rules;
-
- prof->policy.rules = NULL;
---- apparmor-4.0.0-beta4.orig/parser/parser_yacc.y
-+++ apparmor-4.0.0-beta4/parser/parser_yacc.y
-@@ -63,10 +63,10 @@
-
- int parser_token = 0;
-
--struct cod_entry *do_file_rule(char *id, perms_t perms, char *link_id, char *nt);
-+struct cod_entry *do_file_rule(char *id, perm32_t perms, char *link_id, char *nt);
- mnt_rule *do_mnt_rule(struct cond_entry *src_conds, char *src,
- struct cond_entry *dst_conds, char *dst,
-- perms_t perms);
-+ perm32_t perms);
- mnt_rule *do_pivot_rule(struct cond_entry *old, char *root,
- char *transition);
- static void abi_features(char *filename, bool search);
-@@ -115,6 +115,7 @@
- %token TOK_AUDIT
- %token TOK_DENY
- %token TOK_ALLOW
-+%token TOK_PROMPT
- %token TOK_PROFILE
- %token TOK_SET
- %token TOK_ALIAS
-@@ -211,7 +212,7 @@
- prefix_rule_t *prefix_entry;
-
- flagvals flags;
-- perms_t fperms;
-+ perm32_t fperms;
- uint64_t cap;
- unsigned int allowed_protocol;
- char *set_var;
-@@ -221,6 +222,7 @@
- struct cond_entry *cond_entry;
- struct cond_entry_list cond_entry_list;
- int boolean;
-+ owner_t owner;
- struct prefixes prefix;
- IncludeCache_t *includecache;
- audit_t audit;
-@@ -265,7 +267,7 @@
- %type <id> opt_id_or_var
- %type <boolean> opt_subset_flag
- %type <audit> opt_audit_flag
--%type <boolean> opt_owner_flag
-+%type <owner> opt_owner_flag
- %type <boolean> opt_profile_flag
- %type <boolean> opt_flags
- %type <rule_mode> opt_rule_mode
-@@ -625,13 +627,14 @@
- opt_audit_flag: { /* nothing */ $$ = AUDIT_UNSPECIFIED; }
- | TOK_AUDIT { $$ = AUDIT_FORCE; };
-
--opt_owner_flag: { /* nothing */ $$ = 0; }
-- | TOK_OWNER { $$ = 1; };
-- | TOK_OTHER { $$ = 2; };
-+opt_owner_flag: { /* nothing */ $$ = OWNER_UNSPECIFIED; }
-+ | TOK_OWNER { $$ = OWNER_SPECIFIED; };
-+ | TOK_OTHER { $$ = OWNER_NOT; };
-
- opt_rule_mode: { /* nothing */ $$ = RULE_UNSPECIFIED; }
- | TOK_ALLOW { $$ = RULE_ALLOW; }
- | TOK_DENY { $$ = RULE_DENY; }
-+ | TOK_PROMPT { $$ = RULE_PROMPT; }
-
- opt_prefix: opt_audit_flag opt_rule_mode opt_owner_flag
- {
-@@ -674,8 +677,11 @@
- {
- struct cod_entry *entry, *tmp;
-
-- PDEBUG("matched: %s%s%sblock\n", $2.audit == AUDIT_FORCE ? "audit " : "",
-- $2.rule_mode == RULE_DENY ? "deny " : "", $2.owner ? "owner " : "");
-+ PDEBUG("matched: %s%s%sblock\n",
-+ $2.audit == AUDIT_FORCE ? "audit " : "",
-+ $2.rule_mode == RULE_DENY ? "deny " : "",
-+ $2.rule_mode == RULE_PROMPT ? "prompt " : "",
-+ $2.owner == OWNER_SPECIFIED ? "owner " : "");
- list_for_each_safe($3->entries, entry, tmp) {
- const char *error;
- entry->next = NULL;
-@@ -741,8 +747,8 @@
- PDEBUG("rules change_profile: (%s)\n", $3->name);
- if (!$3)
- yyerror(_("Assert: `change_profile' returned NULL."));
-- if ($2.owner)
-- yyerror(_("owner prefix not allowed on unix rules"));
-+ if ($2.owner != OWNER_UNSPECIFIED)
-+ yyerror(_("owner conditional not allowed on unix rules"));
- if (($2.rule_mode == RULE_DENY) && $2.audit == AUDIT_FORCE) {
- $3->rule_mode = RULE_DENY;
- } else if ($2.rule_mode == RULE_DENY) {
-@@ -757,8 +763,8 @@
-
- rules: rules opt_prefix capability
- {
-- if ($2.owner)
-- yyerror(_("owner prefix not allowed on capability rules"));
-+ if ($2.owner != OWNER_UNSPECIFIED)
-+ yyerror(_("owner conditional not allowed on capability rules"));
-
- if ($2.rule_mode == RULE_DENY && $2.audit == AUDIT_FORCE) {
- $1->caps.deny |= $3;
-@@ -1557,7 +1563,7 @@
- change_profile: TOK_CHANGE_PROFILE opt_exec_mode opt_id opt_named_transition TOK_END_OF_RULE
- {
- struct cod_entry *entry;
-- perms_t perms = AA_CHANGE_PROFILE;
-+ perm32_t perms = AA_CHANGE_PROFILE;
- int exec_mode = $2;
- char *exec = $3;
- char *target = $4;
-@@ -1665,7 +1671,7 @@
- exit(1);
- }
-
--struct cod_entry *do_file_rule(char *id, perms_t perms, char *link_id, char *nt)
-+struct cod_entry *do_file_rule(char *id, perm32_t perms, char *link_id, char *nt)
- {
- struct cod_entry *entry;
- PDEBUG("Matched: tok_id (%s) tok_perms (0x%x)\n", id, perms);
-@@ -1706,7 +1712,7 @@
-
- mnt_rule *do_mnt_rule(struct cond_entry *src_conds, char *src,
- struct cond_entry *dst_conds, char *dst,
-- perms_t perms)
-+ perm32_t perms)
- {
- if (verify_mnt_conds(src_conds, MNT_SRC_OPT) != 0)
- yyerror(_("bad mount rule"));
-@@ -1804,4 +1810,3 @@
- }
-
- };
--
---- /dev/null
-+++ apparmor-4.0.0-beta4/parser/perms.h
-@@ -0,0 +1,117 @@
-+/*
-+ * Copyright (c) 2022
-+ * Canonical, Ltd. (All rights reserved)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of version 2 of the GNU General Public
-+ * License published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, contact Novell, Inc. or Canonical
-+ * Ltd.
-+ */
-+#ifndef __AA_PERM_H
-+#define __AA_PERM_H
-+
-+/* this represents permissions as used as part of the state machine in
-+ * the kernel.
-+ * It is possible this will get further mapped for compatibility with
-+ * older versions
-+ */
-+
-+#include <stdint.h>
-+#include <sys/apparmor.h>
-+
-+/* same as in immunix.h - make it so they can both be included or used alone */
-+#ifndef AA_MAY_EXEC
-+#define AA_MAY_EXEC 1
-+#define AA_MAY_WRITE 2
-+#define AA_MAY_READ 4
-+#define AA_MAY_APPEND 8
-+#endif
-+
-+#ifndef AA_MAY_CREATE
-+// these are in apparmor.h
-+#define AA_MAY_CREATE 0x0010
-+#define AA_MAY_DELETE 0x0020
-+#define AA_MAY_OPEN 0x0040
-+#define AA_MAY_RENAME 0x0080 /* pair */
-+
-+#define AA_MAY_SETATTR 0x0100 /* meta write */
-+#define AA_MAY_GETATTR 0x0200 /* meta read */
-+#define AA_MAY_SETCRED 0x0400 /* security cred/attr */
-+#define AA_MAY_GETCRED 0x0800
-+
-+#define AA_MAY_CHMOD 0x1000 /* pair */
-+#define AA_MAY_CHOWN 0x2000 /* pair */
-+#endif
-+#define AA_MAY_CHGRP 0x4000 /* pair */
-+#ifndef AA_MAY_CREATE
-+#define AA_MAY_LOCK 0x8000 /* LINK_SUBSET overlaid */
-+
-+#define AA_EXEC_MMAP 0x00010000
-+#endif
-+#define AA_MAY_MPROT 0x00020000 /* extend conditions */
-+#ifndef AA_MAY_CREATE
-+#define AA_MAY_LINK 0x00040000 /* pair */
-+#endif
-+#define AA_MAY_SNAPSHOT 0x00080000 /* pair */
-+
-+#define AA_MAY_DELEGATE
-+#define AA_CONT_MATCH 0x08000000
-+
-+#define AA_MAY_STACK 0x10000000
-+#define AA_MAY_ONEXEC 0x20000000 /* either stack or change_profile */
-+#define AA_MAY_CHANGE_PROFILE 0x40000000
-+#define AA_MAY_CHANGEHAT 0x80000000
-+
-+#define AA_LINK_SUBSET AA_MAY_LOCK /* overlaid */
-+
-+
-+/*
-+ * The xindex is broken into 3 parts
-+ * - index - an index into either the exec name table or the variable table
-+ * - exec type - which determines how the executable name and index are used
-+ * - flags - which modify how the destination name is applied
-+ */
-+#define AA_X_INDEX_MASK AA_INDEX_MASK
-+
-+#define AA_X_TYPE_MASK 0x0c000000
-+#define AA_X_NONE AA_INDEX_NONE
-+#define AA_X_NAME 0x04000000 /* use executable name px */
-+#define AA_X_TABLE 0x08000000 /* use a specified name ->n# */
-+
-+#define AA_X_UNSAFE 0x10000000
-+#define AA_X_CHILD 0x20000000
-+#define AA_X_INHERIT 0x40000000
-+#define AA_X_UNCONFINED 0x80000000
-+
-+typedef uint32_t perm32_t;
-+
-+struct aa_perms {
-+ perm32_t allow;
-+ perm32_t deny; /* explicit deny, or conflict if allow also set */
-+
-+ perm32_t subtree; /* allow perm on full subtree only when allow is set */
-+ perm32_t cond; /* set only when ~allow and ~deny */
-+
-+ perm32_t kill; /* set only when ~allow | deny */
-+ perm32_t complain; /* accumulates only used when ~allow & ~deny */
-+ perm32_t prompt; /* accumulates only used when ~allow & ~deny */
-+
-+ perm32_t audit; /* set only when allow is set */
-+ perm32_t quiet; /* set only when ~allow | deny */
-+ perm32_t hide; /* set only when ~allow | deny */
-+
-+
-+ uint32_t xindex;
-+ uint32_t tag; /* tag string index, if present */
-+ uint32_t label; /* label string index, if present */
-+};
-+
-+#endif /* __AA_PERM_H */
---- apparmor-4.0.0-beta4.orig/parser/profile.cc
-+++ apparmor-4.0.0-beta4/parser/profile.cc
-@@ -161,6 +161,8 @@
- {
- entry->next = prof->entries;
- prof->entries = entry;
-+ if (entry->rule_mode == RULE_PROMPT)
-+ prof->uses_prompt_rules = true;
- }
-
- static int add_named_transition(Profile *prof, struct cod_entry *entry)
-@@ -269,11 +271,11 @@
- void post_process_file_entries(Profile *prof)
- {
- struct cod_entry *entry;
-- perms_t cp_perms = 0;
-+ perm32_t cp_perms = 0;
-
- list_for_each(prof->entries, entry) {
- if (entry->nt_name) {
-- perms_t perms = 0;
-+ perm32_t perms = 0;
- int n = add_named_transition(prof, entry);
- if (!n) {
- PERROR("Profile %s has too many specified profile transitions.\n", prof->name);
---- apparmor-4.0.0-beta4.orig/parser/profile.h
-+++ apparmor-4.0.0-beta4/parser/profile.h
-@@ -15,6 +15,7 @@
- #define __AA_PROFILE_H
-
- #include <set>
-+#include <vector>
- #include <string>
- #include <iostream>
-
-@@ -24,6 +25,8 @@
- #include "libapparmor_re/aare_rules.h"
- #include "network.h"
- #include "signal.h"
-+#include "immunix.h"
-+#include "perms.h"
-
- class Profile;
-
-@@ -120,6 +123,7 @@
- #define FLAG_DEBUG1 2
- #define FLAG_DEBUG2 4
- #define FLAG_INTERRUPTIBLE 8
-+#define FLAG_PROMPT_COMPAT 0x10
-
- /* sigh, used in parse union so needs trivial constructors. */
- class flagvals {
-@@ -199,6 +203,10 @@
- os << ", attach_disconnected.path=" << disconnected_path;
- if (signal)
- os << ", kill.signal=" << signal;
-+
-+ if (flags & FLAG_PROMPT_COMPAT)
-+ os << ", prompt_dev";
-+
- os << "\n";
-
- return os;
-@@ -291,12 +299,14 @@
- aare_rules *rules;
- void *dfa;
- size_t size;
--
-+ size_t file_start; /* special start in welded dfa */
-+ vector <aa_perms> perms_table;
- dfa_stuff(void): rules(NULL), dfa(NULL), size(0) { }
- };
-
- class Profile {
- public:
-+ bool uses_prompt_rules;
- char *ns;
- char *name;
- char *attachment;
-@@ -304,7 +314,7 @@
- void *xmatch;
- size_t xmatch_size;
- int xmatch_len;
--
-+ vector <aa_perms> xmatch_perms_table;
- struct cond_entry_list xattrs;
-
- /* char *sub_name; */ /* subdomain name or NULL */
-@@ -330,6 +340,7 @@
-
- Profile(void)
- {
-+ uses_prompt_rules = false;
- ns = name = attachment = NULL;
- altnames = NULL;
- xmatch = NULL;
---- apparmor-4.0.0-beta4.orig/parser/ptrace.cc
-+++ apparmor-4.0.0-beta4/parser/ptrace.cc
-@@ -24,7 +24,7 @@
- #include <string>
- #include <sstream>
-
--int parse_ptrace_perms(const char *str_perms, perms_t *perms, int fail)
-+int parse_ptrace_perms(const char *str_perms, perm32_t *perms, int fail)
- {
- return parse_X_perms("ptrace", AA_VALID_PTRACE_PERMS, str_perms, perms, fail);
- }
-@@ -47,7 +47,7 @@
- }
- }
-
--ptrace_rule::ptrace_rule(perms_t perms_p, struct cond_entry *conds):
-+ptrace_rule::ptrace_rule(perm32_t perms_p, struct cond_entry *conds):
- perms_rule_t(AA_CLASS_PTRACE), peer_label(NULL)
- {
- if (perms_p) {
-@@ -133,8 +133,9 @@
-
- buf = buffer.str();
- if (perms & AA_VALID_PTRACE_PERMS) {
-- if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0,
-- parseopts))
-+ if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode, perms,
-+ audit == AUDIT_FORCE ? perms : 0,
-+ parseopts))
- goto fail;
- }
-
---- apparmor-4.0.0-beta4.orig/parser/ptrace.h
-+++ apparmor-4.0.0-beta4/parser/ptrace.h
-@@ -27,14 +27,14 @@
- #define AA_VALID_PTRACE_PERMS (AA_MAY_READ | AA_MAY_TRACE | AA_MAY_READBY | \
- AA_MAY_TRACEDBY)
-
--int parse_ptrace_perms(const char *str_perms, perms_t *perms, int fail);
-+int parse_ptrace_perms(const char *str_perms, perm32_t *perms, int fail);
-
- class ptrace_rule: public perms_rule_t {
- void move_conditionals(struct cond_entry *conds);
- public:
- char *peer_label;
-
-- ptrace_rule(perms_t perms, struct cond_entry *conds);
-+ ptrace_rule(perm32_t perms, struct cond_entry *conds);
- virtual ~ptrace_rule()
- {
- free(peer_label);
-@@ -45,7 +45,7 @@
- virtual int gen_policy_re(Profile &prof);
-
- virtual bool valid_prefix(const prefixes &p, const char *&error) {
-- if (p.owner) {
-+ if (p.owner != OWNER_UNSPECIFIED) {
- error = "owner prefix not allowed on ptrace rules";
- return false;
- }
---- apparmor-4.0.0-beta4.orig/parser/rule.h
-+++ apparmor-4.0.0-beta4/parser/rule.h
-@@ -22,10 +22,19 @@
- #include <list>
- #include <ostream>
-
-+#include "perms.h"
- #include "policydb.h"
-
- using namespace std;
-
-+#define PROMPT_COMPAT_UNKNOWN 0
-+#define PROMPT_COMPAT_IGNORE 1
-+#define PROMPT_COMPAT_PERMSV2 2
-+#define PROMPT_COMPAT_DEV 3
-+#define PROMPT_COMPAT_FLAG 4
-+#define PROMPT_COMPAT_PERMSV1 5
-+
-+
- class Profile;
-
- #define RULE_NOT_SUPPORTED 0
-@@ -151,9 +160,10 @@
- typedef std::list<rule_t *> RuleList;
-
- /* Not classes so they can be used in the bison front end */
--typedef uint32_t perms_t;
- typedef enum { AUDIT_UNSPECIFIED, AUDIT_FORCE, AUDIT_QUIET } audit_t;
--typedef enum { RULE_UNSPECIFIED, RULE_ALLOW, RULE_DENY } rule_mode_t;
-+typedef enum { RULE_UNSPECIFIED, RULE_ALLOW, RULE_DENY, RULE_PROMPT } rule_mode_t;
-+typedef enum { OWNER_UNSPECIFIED, OWNER_SPECIFIED, OWNER_NOT } owner_t;
-+
-
- /* NOTE: we can not have a constructor for class prefixes. This is
- * because it will break bison, and we would need to transition to
-@@ -165,7 +175,7 @@
- public:
- audit_t audit;
- rule_mode_t rule_mode;
-- int owner;
-+ owner_t owner;
-
- ostream &dump(ostream &os)
- {
-@@ -183,6 +193,13 @@
- }
-
- switch (rule_mode) {
-+ case RULE_ALLOW:
-+ if (output)
-+ os << " ";
-+
-+ os << "allow";
-+ output = true;
-+ break;
- case RULE_DENY:
- if (output)
- os << " ";
-@@ -190,15 +207,32 @@
- os << "deny";
- output = true;
- break;
-+ case RULE_PROMPT:
-+ if (output)
-+ os << " ";
-+
-+ os << "prompt";
-+ output = true;
-+ break;
- default:
- break;
- }
-
-- if (owner) {
-+ switch (owner) {
-+ case OWNER_SPECIFIED:
- if (output)
- os << " ";
- os << "owner";
- output = true;
-+ break;
-+ case OWNER_NOT:
-+ if (output)
-+ os << " ";
-+ os << "!owner";
-+ output = true;
-+ break;
-+ default:
-+ break;
- }
-
- if (output)
-@@ -216,9 +250,9 @@
- return -1;
- if ((uint) rule_mode > (uint) rhs.rule_mode)
- return 1;
-- if (owner < rhs.owner)
-+ if ((uint) owner < (uint) rhs.owner)
- return -1;
-- if (owner > rhs.owner)
-+ if ((uint) owner > (uint) rhs.owner)
- return 1;
- return 0;
- }
-@@ -228,7 +262,7 @@
- return true;
- if ((uint) rule_mode < (uint) rhs.rule_mode)
- return true;
-- if (owner < rhs.owner)
-+ if ((uint) owner < (uint) rhs.owner)
- return true;
- return false;
- }
-@@ -241,7 +275,7 @@
- /* Must construct prefix here see note on prefixes */
- audit = AUDIT_UNSPECIFIED;
- rule_mode = RULE_UNSPECIFIED;
-- owner = 0;
-+ owner = OWNER_UNSPECIFIED;
- };
-
- virtual bool valid_prefix(const prefixes &p, const char *&error) = 0;
-@@ -271,13 +305,15 @@
-
- /* owner !owner conflicts */
- if (p.owner) {
-- if (owner && owner != p.owner) {
-+ if (owner != OWNER_UNSPECIFIED &&
-+ owner != p.owner) {
- error = "conflicting owner prefix";
- return false;
- }
- owner = p.owner;
- }
-
-+ /* TODO: MOVE this ! */
- /* does the prefix imply a modifier */
- if (p.rule_mode == RULE_DENY && p.audit == AUDIT_FORCE) {
- rule_mode = RULE_DENY;
-@@ -393,7 +429,7 @@
- return os;
- }
-
-- perms_t perms, saved;
-+ perm32_t perms, saved;
- };
-
- // alternate perms rule class that only does dedup instead of perms merging
-@@ -418,7 +454,7 @@
- return os;
- }
-
-- perms_t perms;
-+ perm32_t perms;
- };
-
-
---- apparmor-4.0.0-beta4.orig/parser/signal.cc
-+++ apparmor-4.0.0-beta4/parser/signal.cc
-@@ -116,7 +116,7 @@
- };
-
-
--int parse_signal_perms(const char *str_perms, perms_t *perms, int fail)
-+int parse_signal_perms(const char *str_perms, perm32_t *perms, int fail)
- {
- return parse_X_perms("signal", AA_VALID_SIGNAL_PERMS, str_perms, perms, fail);
- }
-@@ -173,7 +173,7 @@
- }
- }
-
--signal_rule::signal_rule(perms_t perms_p, struct cond_entry *conds):
-+signal_rule::signal_rule(perm32_t perms_p, struct cond_entry *conds):
- perms_rule_t(AA_CLASS_SIGNAL), signals(), peer_label(NULL)
- {
- if (perms_p) {
-@@ -316,8 +316,9 @@
-
- buf = buffer.str();
- if (perms & (AA_MAY_SEND | AA_MAY_RECEIVE)) {
-- if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0,
-- parseopts))
-+ if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode,
-+ perms, audit == AUDIT_FORCE ? perms : 0,
-+ parseopts))
- goto fail;
- }
-
---- apparmor-4.0.0-beta4.orig/parser/signal.h
-+++ apparmor-4.0.0-beta4/parser/signal.h
-@@ -32,7 +32,7 @@
- typedef set<int> Signals;
-
- int find_signal_mapping(const char *sig);
--int parse_signal_perms(const char *str_perms, perms_t *perms, int fail);
-+int parse_signal_perms(const char *str_perms, perm32_t *perms, int fail);
-
- class signal_rule: public perms_rule_t {
- void extract_sigs(struct value_list **list);
-@@ -41,13 +41,13 @@
- Signals signals;
- char *peer_label;
-
-- signal_rule(perms_t perms, struct cond_entry *conds);
-+ signal_rule(perm32_t perms, struct cond_entry *conds);
- virtual ~signal_rule() {
- signals.clear();
- free(peer_label);
- };
- virtual bool valid_prefix(const prefixes &p, const char *&error) {
-- if (p.owner) {
-+ if (p.owner != OWNER_UNSPECIFIED) {
- error = "owner prefix not allowed on signal rules";
- return false;
- }
---- apparmor-4.0.0-beta4.orig/parser/userns.cc
-+++ apparmor-4.0.0-beta4/parser/userns.cc
-@@ -40,7 +40,7 @@
- }
- }
-
--userns_rule::userns_rule(perms_t perms_p, struct cond_entry *conds):
-+userns_rule::userns_rule(perm32_t perms_p, struct cond_entry *conds):
- perms_rule_t(AA_CLASS_NS)
- {
- if (perms_p) {
-@@ -95,9 +95,9 @@
- buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_NS;
- buf = buffer.str();
- if (perms & AA_VALID_USERNS_PERMS) {
-- if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, perms,
-- audit == AUDIT_FORCE ? perms : 0,
-- parseopts))
-+ if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode, perms,
-+ audit == AUDIT_FORCE ? perms : 0,
-+ parseopts))
- goto fail;
- }
-
---- apparmor-4.0.0-beta4.orig/parser/userns.h
-+++ apparmor-4.0.0-beta4/parser/userns.h
-@@ -26,7 +26,7 @@
- class userns_rule: public perms_rule_t {
- void move_conditionals(struct cond_entry *conds);
- public:
-- userns_rule(perms_t perms, struct cond_entry *conds);
-+ userns_rule(perm32_t perms, struct cond_entry *conds);
- virtual ~userns_rule()
- {
- };
diff --git a/debian/patches/ubuntu/parser-fix-integer-overflow-bug-in-rule-priority-com.patch b/debian/patches/ubuntu/parser-fix-integer-overflow-bug-in-rule-priority-com.patch
deleted file mode 100644
index e60c5a7..0000000
--- a/debian/patches/ubuntu/parser-fix-integer-overflow-bug-in-rule-priority-com.patch
+++ /dev/null
@@ -1,129 +0,0 @@
-From 9637fbd3b965a47a0629df55f156173ee8f6a177 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen at canonical.com>
-Date: Thu, 15 Aug 2024 13:22:19 -0700
-Subject: [PATCH 1/2] parser: fix integer overflow bug in rule priority
- comparisons
-
-There is an integer overflow when comparing priorities when cmp is
-used because it uses subtraction to find lessthan, equal, and greater
-than in one operation.
-
-But INT_MAX and INT_MIN are being used by priorities and this results
-in INT_MAX - INT_MIN and INT_MIN - INT_MAX which are both overflows
-causing an incorrect comparison result and selection of the wrong
-rule permission.
-
-Signed-off-by: John Johansen <john.johansen at canonical.com>
----
- parser/immunix.h | 4 ++++
- parser/libapparmor_re/hfa.h | 4 ++--
- parser/parser.h | 8 +++++---
- parser/parser_regex.c | 6 +++---
- parser/parser_yacc.y | 8 ++++----
- 5 files changed, 18 insertions(+), 12 deletions(-)
-
-diff --git a/parser/immunix.h b/parser/immunix.h
-index 357a2d16a..4f18096da 100644
---- a/parser/immunix.h
-+++ b/parser/immunix.h
-@@ -175,6 +175,10 @@ static inline int is_merged_x_consistent(int a, int b)
- return 1;
- }
-
-+/* ensure we don't overflow when using minus to generate a comparison */
-+#define PRIORITY_MIN ((INT_MIN >> 1) + 1)
-+#define PRIORITY_MAX (INT_MAX >> 1)
-+
- #endif /* ! _IMMUNIX_H */
-
- /* LocalWords: MMAP
-diff --git a/parser/libapparmor_re/hfa.h b/parser/libapparmor_re/hfa.h
-index 3c6afb071..a52ace7d7 100644
---- a/parser/libapparmor_re/hfa.h
-+++ b/parser/libapparmor_re/hfa.h
-@@ -52,7 +52,7 @@ ostream &operator<<(ostream &os, State &state);
-
- class perms_t {
- public:
-- perms_t(void): priority(INT_MIN), allow(0), deny(0), prompt(0), audit(0), quiet(0), exact(0) { };
-+ perms_t(void): priority(PRIORITY_MIN), allow(0), deny(0), prompt(0), audit(0), quiet(0), exact(0) { };
-
- bool is_accept(void) { return (allow | deny | prompt | audit | quiet); }
-
-@@ -68,7 +68,7 @@ public:
- }
-
- void clear(void) {
-- priority = INT_MIN;
-+ priority = PRIORITY_MIN;
- allow = deny = prompt = audit = quiet = exact = 0;
- }
- void clear(int p) {
-diff --git a/parser/parser.h b/parser/parser.h
-index 6f0425c81..82dd9e812 100644
---- a/parser/parser.h
-+++ b/parser/parser.h
-@@ -54,11 +54,13 @@ using namespace std;
- extern int parser_token;
-
- /* Arbitrary max and minimum priority that userspace can specify, internally
-- * we handle up to INT_MAX and INT_MIN. Do not ever allow INT_MAX, see
-+ * we handle up to PRIORITY_MAX and PRIORITY_MIN. Do not ever allow INT_MAX,
-+ * or INT_MIN because cmp uses subtraction and it can cause overflow
-+ * see
- * note on mediates_priority
- */
--#define MAX_PRIORITY 1000
--#define MIN_PRIORITY -1000
-+#define MAX_INPUT_PRIORITY 1000
-+#define MIN_INPUT_PRIORITY -1000
-
- #define WARN_RULE_NOT_ENFORCED 0x1
- #define WARN_RULE_DOWNGRADED 0x2
-diff --git a/parser/parser_regex.c b/parser/parser_regex.c
-index fd245e7e9..6232b5620 100644
---- a/parser/parser_regex.c
-+++ b/parser/parser_regex.c
-@@ -1093,9 +1093,9 @@ static const char *deny_file = ".*";
- *
- * Note: it turns out the above bug does exist for dbus rules in parsers
- * that do not support priority, and we don't have a way to fix it.
-- * We fix it here by capping user specified priority to be < INT_MAX.
-+ * We fix it here by capping user specified priority to be < PRIORITY_MAX.
- */
--static int mediates_priority = INT_MAX;
-+static int mediates_priority = PRIORITY_MAX;
-
- /* some rule types unfortunately encoded permissions on the class byte
- * to fix the above bug, they need a different solution. The generic
-@@ -1106,7 +1106,7 @@ static int mediates_priority = INT_MAX;
- * and it is guaranteed to have the same priority as the highest priority
- * rule.
- */
--static int perms_onclass_mediates_priority = INT_MIN;
-+static int perms_onclass_mediates_priority = PRIORITY_MIN;
-
- int process_profile_policydb(Profile *prof)
- {
-diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y
-index 532ddb55a..657ea586c 100644
---- a/parser/parser_yacc.y
-+++ b/parser/parser_yacc.y
-@@ -640,10 +640,10 @@ opt_priority: { $$ = 0; }
- yyerror("invalid priority %s", $3);
- free($3);
- /* see note on mediates_priority */
-- if (tmp > MAX_PRIORITY)
-- yyerror("invalid priority %l > %d", tmp, MAX_PRIORITY);
-- if (tmp < MIN_PRIORITY)
-- yyerror("invalid priority %l > %d", tmp, MIN_PRIORITY);
-+ if (tmp > MAX_INPUT_PRIORITY)
-+ yyerror("invalid priority %l > %d", tmp, MAX_INPUT_PRIORITY);
-+ if (tmp < MIN_INPUT_PRIORITY)
-+ yyerror("invalid priority %l > %d", tmp, MIN_INPUT_PRIORITY);
- $$ = tmp;
- }
-
---
-2.43.0
-
diff --git a/debian/patches/ubuntu/parser-fix-pam_apparmor-regression-test-failures.patch b/debian/patches/ubuntu/parser-fix-pam_apparmor-regression-test-failures.patch
index 421cd99..4868724 100644
--- a/debian/patches/ubuntu/parser-fix-pam_apparmor-regression-test-failures.patch
+++ b/debian/patches/ubuntu/parser-fix-pam_apparmor-regression-test-failures.patch
@@ -18,11 +18,11 @@ Signed-off-by: John Johansen <john.johansen at canonical.com>
parser/tst/minimize.sh | 2 +-
3 files changed, 4 insertions(+), 7 deletions(-)
-diff --git a/parser/parser_main.c b/parser/parser_main.c
-index a1c7d9c08..14d05a086 100644
---- a/parser/parser_main.c
-+++ b/parser/parser_main.c
-@@ -1583,10 +1583,7 @@ static bool get_kernel_features(struct aa_features **features)
+Index: b/parser/parser_main.c
+===================================================================
+--- a/parser/parser_main.c 2025-01-16 09:40:08.611271620 -0800
++++ b/parser/parser_main.c 2025-01-16 09:40:08.608271587 -0800
+@@ -1583,10 +1583,7 @@
}
kernel_supports_permstable32_v1 = aa_features_supports(*features, "policy/permstable32_version/0x000001");
if (kernel_supports_permstable32_v1) {
@@ -34,11 +34,11 @@ index a1c7d9c08..14d05a086 100644
}
/* set default prompt_compat_mode to the best that is supported */
-diff --git a/parser/parser_regex.c b/parser/parser_regex.c
-index 7810458d5..fd245e7e9 100644
---- a/parser/parser_regex.c
-+++ b/parser/parser_regex.c
-@@ -791,7 +791,7 @@ int process_profile_regex(Profile *prof)
+Index: b/parser/parser_regex.c
+===================================================================
+--- a/parser/parser_regex.c 2025-01-16 09:40:08.611271620 -0800
++++ b/parser/parser_regex.c 2025-01-16 09:40:08.608271587 -0800
+@@ -791,7 +791,7 @@
prof->dfa.dfa = prof->dfa.rules->create_dfablob(&prof->dfa.size,
&xmatch_len, prof->dfa.perms_table,
parseopts, true,
@@ -47,7 +47,7 @@ index 7810458d5..fd245e7e9 100644
prof->uses_prompt_rules);
delete prof->dfa.rules;
prof->dfa.rules = NULL;
-@@ -1199,7 +1199,7 @@ int process_profile_policydb(Profile *prof)
+@@ -1200,7 +1200,7 @@
&xmatch_len,
prof->policy.perms_table,
parseopts, false,
@@ -56,19 +56,16 @@ index 7810458d5..fd245e7e9 100644
prof->uses_prompt_rules);
delete prof->policy.rules;
-diff --git a/parser/tst/minimize.sh b/parser/tst/minimize.sh
-index 054831fe8..93bbd17a2 100755
---- a/parser/tst/minimize.sh
-+++ b/parser/tst/minimize.sh
-@@ -155,7 +155,7 @@ echo "ok"
+Index: b/parser/tst/minimize.sh
+===================================================================
+--- a/parser/tst/minimize.sh 2025-01-16 09:40:08.611271620 -0800
++++ b/parser/tst/minimize.sh 2025-01-16 09:40:08.608271587 -0800
+@@ -155,7 +155,7 @@
## NOTE: change count from 6 to 7 when extend perms is not dependent on
## prompt rules being present
echo -n "Minimize profiles extended no-filter audit deny perms "
--if [ "$(echo "/t { /a r, /b w, /c a, /d l, /e k, /f m, audit deny /** w, }" | ${APPARMOR_PARSER} -M features_files/features.extended-perms-no-policydb -QT -O minimize -O no-filter-deny -D dfa-states 2>&1 | grep -v '<==' | grep -c '^{.*} 0 (.*)$')" -ne 7 ] ; then
-+if [ "$(echo "/t { /a r, /b w, /c a, /d l, /e k, /f m, audit deny /** w, }" | ${APPARMOR_PARSER} -M features_files/features.extended-perms-no-policydb -QT -O minimize -O no-filter-deny -D dfa-states 2>&1 | grep -v '<==' | grep -c '^{.*} 0 (.*)$')" -ne 6 ] ; then
+-if [ "$(echo "/t { /a r, /b w, /c a, /d l, /e k, /f m, audit deny /** w, }" | ${APPARMOR_PARSER} -M features_files/features.extended-perms-no-policydb -QT -O minimize -O no-filter-deny -D dfa-states 2>&1 | grep -v '<==' | grep -c '^{.*}(.*)$')" -ne 7 ] ; then
++if [ "$(echo "/t { /a r, /b w, /c a, /d l, /e k, /f m, audit deny /** w, }" | ${APPARMOR_PARSER} -M features_files/features.extended-perms-no-policydb -QT -O minimize -O no-filter-deny -D dfa-states 2>&1 | grep -v '<==' | grep -c '^{.*}(.*)$')" -ne 6 ] ; then
echo "failed"
exit 1;
fi
---
-2.43.0
-
diff --git a/debian/patches/ubuntu/parser-fix-rule-priority-destroying-rule-permissions.patch b/debian/patches/ubuntu/parser-fix-rule-priority-destroying-rule-permissions.patch
deleted file mode 100644
index 0fb2569..0000000
--- a/debian/patches/ubuntu/parser-fix-rule-priority-destroying-rule-permissions.patch
+++ /dev/null
@@ -1,141 +0,0 @@
-From 204c0c5a3a34ac2eb47b863aae20bace48e0ad3c Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen at canonical.com>
-Date: Thu, 15 Aug 2024 03:51:20 -0700
-Subject: [PATCH] parser: fix rule priority destroying rule permissions for
- some classes
-
-io_uring and userns mediation are encoding permissions on the class
-byte. This is a mistake that should never have been allowed.
-
-With the addition of rule priorities the class byte mediates rule,
-that ensure the kernel can determine a class is being mediated is
-given the highest priority possible, to ensure class mediation can not
-be removed by a deny rule. See
- 61b7568e1 ("parser: bug fix mediates_X stub rules.")
-for details.
-
-Unfortunately this breaks rule classes that encode permissions on the
-class byte, because those rules will always have a lower priority and
-the class mediates rule will always be selected over them resulting in
-only the class mediates permission being on the rule class state.
-
-Fix this by adding the mediaties class rules for these rule classes
-with the lowest priority possible. This means that any rule mediating
-the class will wipe out the mediates class rule. So add a new mediates
-class rule at the same priority, as the rule being added.
-
-This is a naive implementation and does result in more mediates rules
-being added than necessary. The rule class could keep track of the
-highest priority rule that had been added, and use that to reduce the
-number of mediates rules it adds for the class.
-
-Technically we could also get away with not adding the rules for allow
-rules, as the kernel doesn't actually check the encoded permission but
-whether the class state is not the trap state. But it is required with
-deny rules to ensure the deny rule doesn't result in permissions being
-removed from the class, resulting in the kernel thinking it is
-unmediated. We also want to ensure that mediation is encoded for other
-rule types like prompt, and in the future the kernel could check the
-permission so we do want to guarantee that the class state has the
-MAY_READ permission on it.
-
-Note: there is another set of classes (file, mqueue, dbus, ...) which
-encodes a default rule permission as
-
- class .* <perm>
-
-this encoding is unfortunate in that it will also add the permission
-to the class byte, but also sets up following states with the permission.
-thankfully, this accespt anything, including nothing generally isn't
-valid in the nothing case (eg. a file without any absolute name). For
-this set of classes, the high priority mediates rule just ensures
-that the null match case does not have permission.
-
-Fixes: 61b7568e1 parser: bug fix mediates_X stub rules.
-Signed-off-by: John Johansen <john.johansen at canonical.com>
----
- parser/io_uring.cc | 7 +++++++
- parser/parser_regex.c | 15 +++++++++++++--
- parser/userns.cc | 8 ++++++++
- 3 files changed, 28 insertions(+), 2 deletions(-)
-
-diff --git a/parser/io_uring.cc b/parser/io_uring.cc
-index 17fa39614..60b8c2579 100644
---- a/parser/io_uring.cc
-+++ b/parser/io_uring.cc
-@@ -127,6 +127,13 @@ int io_uring_rule::gen_policy_re(Profile &prof)
- audit == AUDIT_FORCE ? perms : 0,
- parseopts))
- goto fail;
-+ /* add a mediates_io_uring rule for every rule added. It
-+ * needs to be the same priority
-+ */
-+ if (!prof.policy.rules->add_rule(buf.c_str(), priority,
-+ RULE_ALLOW, AA_MAY_READ, 0,
-+ parseopts))
-+ goto fail;
-
- if (perms & AA_IO_URING_OVERRIDE_CREDS) {
- buf = buffer.str(); /* update buf to have label */
-diff --git a/parser/parser_regex.c b/parser/parser_regex.c
-index 71126c5f9..7810458d5 100644
---- a/parser/parser_regex.c
-+++ b/parser/parser_regex.c
-@@ -1097,6 +1097,17 @@ static const char *deny_file = ".*";
- */
- static int mediates_priority = INT_MAX;
-
-+/* some rule types unfortunately encoded permissions on the class byte
-+ * to fix the above bug, they need a different solution. The generic
-+ * mediates rule will get encoded at the minimum priority, and then
-+ * for every rule of those classes a mediates rule of the same priority
-+ * will be added. This way the mediates rule never has higher priority,
-+ * which would wipe out the rule permissions encoded on the class state,
-+ * and it is guaranteed to have the same priority as the highest priority
-+ * rule.
-+ */
-+static int perms_onclass_mediates_priority = INT_MIN;
-+
- int process_profile_policydb(Profile *prof)
- {
- int error = -1;
-@@ -1112,7 +1123,7 @@ int process_profile_policydb(Profile *prof)
- * to be supported
- */
- if (features_supports_userns &&
-- !prof->policy.rules->add_rule(mediates_ns, mediates_priority, RULE_ALLOW, AA_MAY_READ, 0, parseopts))
-+ !prof->policy.rules->add_rule(mediates_ns, perms_onclass_mediates_priority, RULE_ALLOW, AA_MAY_READ, 0, parseopts))
- goto out;
-
- /* don't add mediated classes to unconfined profiles */
-@@ -1148,7 +1159,7 @@ int process_profile_policydb(Profile *prof)
- !prof->policy.rules->add_rule(mediates_sysv_mqueue, mediates_priority, RULE_ALLOW, AA_MAY_READ, 0, parseopts))
- goto out;
- if (features_supports_io_uring &&
-- !prof->policy.rules->add_rule(mediates_io_uring, mediates_priority, RULE_ALLOW, AA_MAY_READ, 0, parseopts))
-+ !prof->policy.rules->add_rule(mediates_io_uring, perms_onclass_mediates_priority, RULE_ALLOW, AA_MAY_READ, 0, parseopts))
- goto out;
- }
-
-diff --git a/parser/userns.cc b/parser/userns.cc
-index c66ce062e..a2cd9e8eb 100644
---- a/parser/userns.cc
-+++ b/parser/userns.cc
-@@ -99,6 +99,14 @@ int userns_rule::gen_policy_re(Profile &prof)
- rule_mode, perms,
- audit == AUDIT_FORCE ? perms : 0,
- parseopts))
-+
-+ goto fail;
-+ /* add a mediates_userns rule for every rule added. It
-+ * needs to be the same priority
-+ */
-+ if (!prof.policy.rules->add_rule(buf.c_str(), priority,
-+ RULE_ALLOW, AA_MAY_READ, 0,
-+ parseopts))
- goto fail;
- }
-
---
-2.43.0
-
diff --git a/debian/patches/ubuntu/parser-revert-removal-of-second-minimization-pass.patch b/debian/patches/ubuntu/parser-revert-removal-of-second-minimization-pass.patch
deleted file mode 100644
index d580d20..0000000
--- a/debian/patches/ubuntu/parser-revert-removal-of-second-minimization-pass.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From a7b1b48826f73a4586ac761f0499f6e9898d8d70 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen at canonical.com>
-Date: Thu, 15 Aug 2024 13:48:08 -0700
-Subject: [PATCH 2/2] parser: revert removal of second minimization pass
-
-extended perms code is not ready to carry explicit deny information
-revert the clearing of deny and second minimization pass from
-
- 2737cb2c2 ("parser: minimization - remove unnecessary second minimization pass")
-
-Signed-off-by: John Johansen <john.johansen at canonical.com>
----
- parser/libapparmor_re/aare_rules.cc | 31 +++++++++++++++--------------
- 1 file changed, 16 insertions(+), 15 deletions(-)
-
-diff --git a/parser/libapparmor_re/aare_rules.cc b/parser/libapparmor_re/aare_rules.cc
-index 6892b70a7..9b6478cf8 100644
---- a/parser/libapparmor_re/aare_rules.cc
-+++ b/parser/libapparmor_re/aare_rules.cc
-@@ -125,7 +125,6 @@ bool aare_rules::add_rule_vec(int priority, rule_mode_t mode, perm32_t perms,
- cerr << " -> ";
- tree->dump(cerr);
- // TODO: split out from prefixes class
-- cerr << " priority=" << priority;
- if (mode == RULE_DENY)
- cerr << " deny";
- else if (mode == RULE_PROMPT)
-@@ -258,20 +257,6 @@ CHFA *aare_rules::create_chfa(int *min_match_len,
- if (opts.dump & DUMP_DFA_UNIQ_PERMS)
- dfa.dump_uniq_perms("dfa");
-
-- /* since we are building a chfa, use the info about
-- * whether the chfa supports extended perms to help
-- * determine whether we clear the deny info.
-- * This will let us build the minimal dfa for the
-- * information supported by the backed
-- */
-- if (!extended_perms ||
-- // TODO: we should drop DFA_MINIMIZE check here but doing
-- // so changes behavior. Do as a separate patch and fixup
-- // tests, etc.
-- ((opts.control & CONTROL_DFA_FILTER_DENY) &&
-- (opts.control & CONTROL_DFA_MINIMIZE)))
-- dfa.apply_and_clear_deny();
--
- if (opts.control & CONTROL_DFA_MINIMIZE) {
- dfa.minimize(opts);
-
-@@ -279,6 +264,22 @@ CHFA *aare_rules::create_chfa(int *min_match_len,
- dfa.dump_uniq_perms("minimized dfa");
- }
-
-+ if (opts.control & CONTROL_DFA_FILTER_DENY &&
-+ opts.control & CONTROL_DFA_MINIMIZE &&
-+ dfa.apply_and_clear_deny()) {
-+ /* Do a second minimization pass as removal of deny
-+ * information has moved some states from accepting
-+ * to none accepting partitions
-+ *
-+ * TODO: add this as a tail pass to minimization
-+ * so we don't need to do a full second pass
-+ */
-+ dfa.minimize(opts);
-+
-+ if (opts.dump & DUMP_DFA_MIN_UNIQ_PERMS)
-+ dfa.dump_uniq_perms("minimized dfa");
-+ }
-+
- if (opts.control & CONTROL_DFA_REMOVE_UNREACHABLE)
- dfa.remove_unreachable(opts);
-
---
-2.43.0
-
diff --git a/debian/patches/ubuntu/parser-update-tsts-for-explicit-deny-and-filtering-c.patch b/debian/patches/ubuntu/parser-update-tsts-for-explicit-deny-and-filtering-c.patch
deleted file mode 100644
index 07dff37..0000000
--- a/debian/patches/ubuntu/parser-update-tsts-for-explicit-deny-and-filtering-c.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From 0195f3a1ab57e99404d996e29e80916441b12157 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen at canonical.com>
-Date: Thu, 15 Aug 2024 15:05:45 -0700
-Subject: [PATCH] parser: update tsts for explicit deny and filtering changes
-
-Update the equality and minimzation tests for changes made in how
-explicit denies can be carried.
-
-Signed-off-by: John Johansen <john.johansen at canonical.com>
----
- parser/tst/equality.sh | 4 ++--
- parser/tst/minimize.sh | 14 ++++++++------
- 2 files changed, 10 insertions(+), 8 deletions(-)
-
-diff --git a/parser/tst/equality.sh b/parser/tst/equality.sh
-index 8c68a2854..5cdd07a90 100755
---- a/parser/tst/equality.sh
-+++ b/parser/tst/equality.sh
-@@ -31,7 +31,7 @@ verbose="${VERBOSE:-}"
-
- hash_binary_policy()
- {
-- printf %s "$1" | ${APPARMOR_PARSER} --features-file "${_SCRIPTDIR}/features_files/features.all" -qS 2>/dev/null| md5sum | cut -d ' ' -f 1
-+ printf %s "$1" | ${APPARMOR_PARSER} --O filter-deny --features-file "${_SCRIPTDIR}/features_files/features.all" -qS 2>/dev/null| md5sum | cut -d ' ' -f 1
- return $?
- }
-
-@@ -504,7 +504,7 @@ verify_binary_equality "'$p1'x'$p2' Deny removes r perm" \
-
- #this one may not be true in the future depending on if the compiled profile
- #is explicitly including deny permissions for dynamic composition
--verify_binary_equality "'$p1'x'$p2' Deny of ungranted perm" \
-+verify_binary_inequality "'$p1'x'$p2' Deny of ungranted perm" \
- "/t { $p1 /foo/[abc] r, audit deny /foo/b w, }" \
- "/t { $p2 /foo/[abc] r, }"
-
-diff --git a/parser/tst/minimize.sh b/parser/tst/minimize.sh
-index 93bbd17a2..d7fb166f9 100755
---- a/parser/tst/minimize.sh
-+++ b/parser/tst/minimize.sh
-@@ -154,11 +154,12 @@ echo "ok"
-
- ## NOTE: change count from 6 to 7 when extend perms is not dependent on
- ## prompt rules being present
--echo -n "Minimize profiles extended no-filter audit deny perms "
--if [ "$(echo "/t { /a r, /b w, /c a, /d l, /e k, /f m, audit deny /** w, }" | ${APPARMOR_PARSER} -M features_files/features.extended-perms-no-policydb -QT -O minimize -O no-filter-deny -D dfa-states 2>&1 | grep -v '<==' | grep -c '^{.*} 0 (.*)$')" -ne 6 ] ; then
-- echo "failed"
-- exit 1;
--fi
-+## not doing this just yet
-+#echo -n "Minimize profiles extended no-filter audit deny perms "
-+#if [ "$(echo "/t { /a r, /b w, /c a, /d l, /e k, /f m, audit deny /** w, }" | ${APPARMOR_PARSER} -M features_files/features.extended-perms-no-policydb -QT -O minimize -O no-filter-deny -D dfa-states 2>&1 | grep -v '<==' | grep -c '^{.*} 0 (.*)$')" -ne 6 ] ; then
-+# echo "failed"
-+# exit 1;
-+#fi
- echo "ok"
-
- # same test as above except with filter-deny which should result in one less
-@@ -240,8 +241,9 @@ echo "ok"
- # {1} <== (allow/deny/audit/quiet)
- # {3} (0x 0/fe17f85/0/0)
-
-+# because we are still filtering deny this test is -ne 1 instead of -ne 0
- echo -n "Minimize profiles audit deny xtrans "
--if [ "$(echo "/t { /b px, audit deny /* xr, /a Cx -> foo, }" | ${APPARMOR_PARSER} -M features_files/features.nopolicydb -QT -O minimize -O no-filter-deny -D dfa-states 2>&1 | grep -v '<==' | grep -c '^{.*} 0 (.*)$')" -ne 0 ] ; then
-+if [ "$(echo "/t { /b px, audit deny /* xr, /a Cx -> foo, }" | ${APPARMOR_PARSER} -M features_files/features.nopolicydb -QT -O minimize -O no-filter-deny -D dfa-states 2>&1 | grep -v '<==' | grep -c '^{.*} 0 (.*)$')" -ne 1 ] ; then
- echo "failed"
- exit 1;
- fi
---
-2.43.0
-
diff --git a/debian/patches/ubuntu/profiles-grant-access-to-systemd-resolved.patch b/debian/patches/ubuntu/profiles-grant-access-to-systemd-resolved.patch
index f0dac7b..2e36bd2 100644
--- a/debian/patches/ubuntu/profiles-grant-access-to-systemd-resolved.patch
+++ b/debian/patches/ubuntu/profiles-grant-access-to-systemd-resolved.patch
@@ -27,9 +27,11 @@ Bug: https://launchpad.net/bugs/1598759
profiles/apparmor.d/abstractions/nameservice | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
---- apparmor-4.0.0-beta3.orig/profiles/apparmor.d/abstractions/nameservice
-+++ apparmor-4.0.0-beta3/profiles/apparmor.d/abstractions/nameservice
-@@ -105,6 +105,25 @@
+Index: b/profiles/apparmor.d/abstractions/nameservice
+===================================================================
+--- a/profiles/apparmor.d/abstractions/nameservice 2025-01-09 10:23:05.483520378 -0800
++++ b/profiles/apparmor.d/abstractions/nameservice 2025-01-09 10:23:05.479520377 -0800
+@@ -88,6 +88,25 @@
member="{GetDynamicUsers,LookupDynamicUserByName,LookupDynamicUserByUID}"
peer=(name="org.freedesktop.systemd1"),
diff --git a/debian/patches/ubuntu/remmina_mr_1348.patch b/debian/patches/ubuntu/remmina_mr_1348.patch
new file mode 100644
index 0000000..9d256db
--- /dev/null
+++ b/debian/patches/ubuntu/remmina_mr_1348.patch
@@ -0,0 +1,97 @@
+From 347ffd091abdbe733ad4d13ad72af839e22f3574 Mon Sep 17 00:00:00 2001
+From: Paulo Flabiano Smorigo <pfsmorigo at canonical.com>
+Date: Wed, 2 Oct 2024 18:21:30 -0300
+Subject: [PATCH] Add remmina profile
+
+Signed-off-by: Paulo Flabiano Smorigo <pfsmorigo at canonical.com>
+---
+ profiles/apparmor.d/remmina | 77 +++++++++++++++++++++++++++++++++++++
+ 1 file changed, 77 insertions(+)
+ create mode 100644 profiles/apparmor.d/remmina
+
+diff --git a/profiles/apparmor.d/remmina b/profiles/apparmor.d/remmina
+new file mode 100644
+index 000000000..943ebc2fa
+--- /dev/null
++++ b/profiles/apparmor.d/remmina
+@@ -0,0 +1,77 @@
++#------------------------------------------------------------------
++# Copyright (C) 2024 Canonical Ltd.
++#
++# Author: Paulo Flabiano Smorigo <pfsmorigo at canonical.com>
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#------------------------------------------------------------------
++# vim: ft=apparmor
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile remmina /usr/bin/remmina {
++ include <abstractions/base>
++ include <abstractions/fonts>
++ include <abstractions/freedesktop.org>
++ include <abstractions/gnome>
++ include <abstractions/dbus>
++ include <abstractions/dbus-session-strict>
++ include <abstractions/nameservice>
++ include <abstractions/openssl>
++ include <abstractions/ssl_certs>
++ include <abstractions/private-files-strict>
++ include <abstractions/dconf>
++
++ dbus (bind) bus=session name="org.remmina.Remmina",
++ dbus (send) bus=session path="/org/gtk/vfs/mounttracker" interface="org.gtk.vfs.MountTracker" member={ListMountableInfo,LookupMount} peer=(label=unconfined),
++ dbus (send) bus=session path="/org/freedesktop/secrets" interface="org.freedesktop.DBus.Properties" member=GetAll peer=(label=unconfined),
++ dbus (send) bus=session path="/org/freedesktop/DBus" interface="org.freedesktop.DBus" member={RequestName,ReleaseName} peer=(label=unconfined),
++ dbus (send) bus=session path="/org/freedesktop/secrets/collection/login" interface="org.freedesktop.DBus.Properties" member=GetAll peer=(label=unconfined),
++ dbus (send) bus=system path="/org/freedesktop/NetworkManager" interface="org.freedesktop.DBus.Properties" member=GetAll peer=(label=unconfined),
++
++ @{etc_ro}/fstab r,
++ /usr/bin/remmina mr,
++ /usr/share/remmina/{,**} r,
++ /var/lib/snapd/desktop/icons/{,**} r,
++
++ owner @{HOME}/.cache/org.remmina.Remmina/{,**} rw,
++ owner @{HOME}/.cache/remmina/{,**} rw,
++ owner @{HOME}/.cache/thumbnails/{,**} r,
++ owner @{HOME}/.config/autostart/remmina-applet.desktop r,
++ owner @{HOME}/.config/freerdp/known_hosts2 rwk,
++ owner @{HOME}/.config/glib-2.0/settings/keyfile rw,
++ owner @{HOME}/.config/remmina/{,**} rw,
++ owner @{HOME}/.ssh/{config,known_hosts} r,
++ owner @{HOME}/.local/share/remmina/{,**} rw,
++
++ ## In order to import and export profiles
++ owner @{HOME}/{,[^.]**} rw,
++
++ owner @{run}/user/@{uid}/gvfsd/socket-* rw,
++ owner @{PROC}/@{pid}/task/@{tid}/comm rw,
++ owner @{PROC}/@{pid}/mountinfo rw,
++
++ ## dconf abstraction is read-only, adding write access
++ owner @{run}/user/@{uid}/dconf/{,user} rw,
++
++ owner @{run}/user/@{uid}/at-spi/ rw,
++ owner @{run}/user/@{uid}/at-spi/bus{,_[0-9]*} rw,
++
++ /usr/bin/dash Px -> shell_browser,
++
++ include if exists <local/remmina>
++}
++
++profile shell_browser {
++ include <abstractions/base>
++ include <abstractions/consoles>
++ include <abstractions/ubuntu-helpers>
++ include <abstractions/ubuntu-browsers>
++ network tcp,
++
++ /usr/bin/dash r,
++}
+--
+2.43.0
+
diff --git a/debian/patches/ubuntu/rygel_mr_1311.patch b/debian/patches/ubuntu/rygel_mr_1311.patch
new file mode 100644
index 0000000..12201f2
--- /dev/null
+++ b/debian/patches/ubuntu/rygel_mr_1311.patch
@@ -0,0 +1,184 @@
+From b0f00d0a2acdeec9e3e7b81c77e507fa76941fde Mon Sep 17 00:00:00 2001
+From: Alex Murray <alex.murray at canonical.com>
+Date: Thu, 22 Aug 2024 12:12:53 +0930
+Subject: [PATCH] profiles/apparmor.d: add rygel profile
+
+Signed-off-by: Alex Murray <alex.murray at canonical.com>
+---
+ profiles/apparmor.d/rygel | 144 +++++++++++++++++++++++++++++
+ profiles/apparmor.d/tunables/rygel | 12 +++
+ 2 files changed, 156 insertions(+)
+ create mode 100644 profiles/apparmor.d/rygel
+ create mode 100644 profiles/apparmor.d/tunables/rygel
+
+diff --git a/profiles/apparmor.d/rygel b/profiles/apparmor.d/rygel
+new file mode 100644
+index 000000000..1016e483c
+--- /dev/null
++++ b/profiles/apparmor.d/rygel
+@@ -0,0 +1,144 @@
++# -*- mode: apparmor; -*-
++# ------------------------------------------------------------------
++#
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#
++# ------------------------------------------------------------------
++# vim: ft=apparmor
++
++abi <abi/4.0>,
++
++include <tunables/global>
++include <tunables/rygel>
++
++profile rygel /usr/bin/rygel {
++ include <abstractions/base>
++ include <abstractions/dbus-session-strict>
++ include <abstractions/dconf>
++ include <abstractions/freedesktop.org>
++ include <abstractions/nameservice>
++
++ # gst-plugin-scanner tries to probe various things including display devices
++ # etc so allow those that are harmless but deny the rest
++ file r /dev/{,urandom,null},
++ file r /sys/,
++ file r /sys/{bus,class}/,
++ file r /sys/class/drm/,
++ deny file r /dev/dri/{,**},
++
++ file r @{etc_ro}/rygel.conf,
++
++ file mr /usr/bin/rygel,
++
++ file Cx /usr/libexec/rygel/mx-extract -> mx-extract,
++
++ file mrix /usr/lib/@{multiarch}/gstreamer1.0/gstreamer-1.0/gst-plugin-scanner,
++
++ file r /usr/share/gupnp-dlna-2.0/dlna-profiles/{,*},
++ file r /usr/share/gupnp-av/{,*},
++ file r /usr/share/rygel/{,**},
++
++ owner file rw @{HOME}/.cache/gstreamer-1.0/{,*},
++
++ # config and cache
++ owner file rwk @{HOME}/.cache/rygel/{,*},
++ owner file rw @{HOME}/.config/rygel.conf,
++ owner file rw @{HOME}/.config/Rygel/{,*},
++
++ # thumbnails
++ owner file r @{HOME}/.cache/thumbnails/{,**},
++
++ # media files - see tunables/rygel
++ owner file r @{rygel_media_dirs}/{,**},
++
++ # dconf access
++ owner rw @{run}/user/*/dconf/user,
++
++ # liborc temporary files from gstreamer Orc Integration
++ owner file mrw @{HOME}/orcexec.*,
++ owner file mrw @{run}/user/*/orcexec.*,
++ owner file mrw /tmp/orcexec.*,
++
++ network netlink dgram,
++
++ # dbus access
++ # register on DBus
++ dbus (send)
++ bus=session
++ path=/org/freedesktop/DBus
++ interface=org.freedesktop.DBus
++ member="{Request,Release}Name"
++ peer=(name=org.freedesktop.DBus, label=unconfined),
++
++ # claim the org.gnome.Rygel[1] names
++ dbus bus=session
++ name="org.gnome.Rygel{,1}",
++
++ # Allow unconfined to introspect us
++ dbus (receive)
++ bus=session
++ interface=org.freedesktop.DBus.Introspectable
++ member=Introspect
++ peer=(label=unconfined),
++
++ # allow to respond to unconfined clients
++ dbus (receive)
++ bus=session
++ interface="org.gnome.Rygel1"
++ peer=(label=unconfined),
++
++ # allow us to respond to unconfined clients (eg, org.freedesktop.*,
++ # org.gtk.Application, etc)
++ dbus (receive)
++ bus=session
++ path="/org/gnome/Rygel{,1}"
++ peer=(label=unconfined),
++
++ # allow to enumerate mounts
++ dbus (send)
++ bus=session
++ path="/org/gtk/vfs/mounttracker"
++ interface="org.gtk.vfs.MountTracker"
++ member="ListMountableInfo"
++ peer=(label=unconfined),
++
++ profile mx-extract {
++ include <abstractions/base>
++ include <abstractions/dbus-session-strict>
++ include <abstractions/freedesktop.org>
++
++ # gst-plugin-scanner tries to probe various things including display devices
++ # etc so allow those that are harmless but deny the rest
++ file r /dev/{,urandom,null},
++ file r /sys/,
++ file r /sys/{bus,class}/,
++ file r /sys/class/drm/,
++ deny file r /dev/dri/{,**},
++
++ file mr /usr/libexec/rygel/mx-extract,
++
++ file r /usr/share/gupnp-dlna-2.0/dlna-profiles/{,*},
++
++ file mrix /usr/lib/@{multiarch}/gstreamer1.0/gstreamer-1.0/gst-plugin-scanner,
++
++ file r /usr/share/gvfs/mounts/,
++
++ owner file r @{HOME}/.cache/gstreamer-1.0/*,
++ owner file rw @{HOME}/.cache/media-art/{,*},
++
++ # media files - see tunables/rygel
++ owner file r @{rygel_media_dirs}/{,**},
++
++ # liborc temporary files from gstreamer Orc Integration
++ owner file mrw @{HOME}/orcexec.*,
++ owner file mrw @{run}/user/*/orcexec.*,
++ owner file mrw /tmp/orcexec.*,
++ }
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/rygel>
++}
+diff --git a/profiles/apparmor.d/tunables/rygel b/profiles/apparmor.d/tunables/rygel
+new file mode 100644
+index 000000000..72b793b0e
+--- /dev/null
++++ b/profiles/apparmor.d/tunables/rygel
+@@ -0,0 +1,12 @@
++# ------------------------------------------------------------------
++#
++# Copyright (C) 2024 Canonical Ltd.
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#
++# ------------------------------------------------------------------
++# allow standard XDG media paths by default
++@{rygel_media_dirs}=@{HOME}/@{XDG_MUSIC_DIR} @{HOME}/@{XDG_VIDEOS_DIR} @{HOME}/@{XDG_PICTURES_DIR}
++
++include if exists <tunables/rygel.d>
+--
+2.43.0
+
diff --git a/debian/patches/ubuntu/samba-systemd-interaction.patch b/debian/patches/ubuntu/samba-systemd-interaction.patch
index 36405b0..15b9b0c 100644
--- a/debian/patches/ubuntu/samba-systemd-interaction.patch
+++ b/debian/patches/ubuntu/samba-systemd-interaction.patch
@@ -18,9 +18,11 @@ Ubuntu notes:
profiles/apparmor.d/usr.sbin.smbd | 12 ++++++++++++
1 file changed, 12 insertions(+)
---- apparmor-4.0.0-beta4.orig/profiles/apparmor.d/usr.sbin.smbd
-+++ apparmor-4.0.0-beta4/profiles/apparmor.d/usr.sbin.smbd
-@@ -26,12 +26,22 @@
+Index: b/profiles/apparmor.d/usr.sbin.smbd
+===================================================================
+--- a/profiles/apparmor.d/usr.sbin.smbd 2025-01-09 10:23:17.326524283 -0800
++++ b/profiles/apparmor.d/usr.sbin.smbd 2025-01-09 10:23:17.322524282 -0800
+@@ -27,12 +27,22 @@
signal send set=term peer=samba-bgqd,
@@ -43,7 +45,7 @@ Ubuntu notes:
/usr/lib*/samba/vfs/*.so mr,
/usr/lib*/samba/auth/*.so mr,
/usr/lib*/samba/charset/*.so mr,
-@@ -56,6 +66,8 @@
+@@ -57,6 +67,8 @@
@{run}/samba/** rk,
@{run}/samba/ncalrpc/ rw,
@{run}/samba/ncalrpc/** rw,
diff --git a/debian/patches/ubuntu/sbuild_mr_1555.patch b/debian/patches/ubuntu/sbuild_mr_1555.patch
new file mode 100644
index 0000000..05319f2
--- /dev/null
+++ b/debian/patches/ubuntu/sbuild_mr_1555.patch
@@ -0,0 +1,300 @@
+From 7abfc1baf7b9200b52fadbf9c89d3d1b1fd854a7 Mon Sep 17 00:00:00 2001
+From: John Johansen <john.johansen at canonical.com>
+Date: Wed, 19 Feb 2025 16:05:57 -0800
+Subject: [PATCH] profiles: fix sbuild to work with the unprivileged_unshare
+ profile
+
+sbuild is an unconfined profile allowing it to by-pass the unprivlieged
+user namespace restritction.
+
+unconfined profiles us a pix transition which means when the
+unprivileged_unshare profile is enabled, the binaries in an unconfined
+profile calls unshare it will transition to the unprivileged_unshare
+profile.
+
+This will break sbuild because it needs capabilities within the
+user namespace.
+
+However we can not just add a x transition rule to unconfined profiles,
+the transitions won't be respected. Instead we have to make the profile
+a default allow profile, and add a transition that will override
+the default pix transition of allow all.
+
+We have to add the attached_disconnected and mediated_deleted flags
+because sbuild is manipulating mounts.
+
+Signed-off-by: John Johansen <john.johansen at canonical.com>
+---
+ profiles/apparmor.d/sbuild | 7 ++++++-
+ profiles/apparmor.d/sbuild-abort | 7 ++++++-
+ profiles/apparmor.d/sbuild-adduser | 7 ++++++-
+ profiles/apparmor.d/sbuild-apt | 7 ++++++-
+ profiles/apparmor.d/sbuild-checkpackages | 7 ++++++-
+ profiles/apparmor.d/sbuild-clean | 7 ++++++-
+ profiles/apparmor.d/sbuild-createchroot | 7 ++++++-
+ profiles/apparmor.d/sbuild-destroychroot | 7 ++++++-
+ profiles/apparmor.d/sbuild-distupgrade | 7 ++++++-
+ profiles/apparmor.d/sbuild-hold | 7 ++++++-
+ profiles/apparmor.d/sbuild-shell | 7 ++++++-
+ profiles/apparmor.d/sbuild-unhold | 7 ++++++-
+ profiles/apparmor.d/sbuild-update | 7 ++++++-
+ profiles/apparmor.d/sbuild-upgrade | 7 ++++++-
+ 14 files changed, 84 insertions(+), 14 deletions(-)
+
+diff --git a/profiles/apparmor.d/sbuild b/profiles/apparmor.d/sbuild
+index 1b9bae999..28f3e41d7 100644
+--- a/profiles/apparmor.d/sbuild
++++ b/profiles/apparmor.d/sbuild
+@@ -4,9 +4,14 @@
+ abi <abi/4.0>,
+ include <tunables/global>
+
+-profile sbuild /usr/bin/sbuild flags=(unconfined) {
++profile sbuild /usr/bin/sbuild flags=(attach_disconnected mediate_deleted) {
++ allow all,
++
+ userns,
+
++ # override default pix
++ /usr/bin/unshare ix,
++
+ # Site-specific additions and overrides. See local/README for details.
+ include if exists <local/sbuild>
+ }
+diff --git a/profiles/apparmor.d/sbuild-abort b/profiles/apparmor.d/sbuild-abort
+index b147d5b3b..77b60db3f 100644
+--- a/profiles/apparmor.d/sbuild-abort
++++ b/profiles/apparmor.d/sbuild-abort
+@@ -4,7 +4,12 @@
+ abi <abi/4.0>,
+ include <tunables/global>
+
+-profile sbuild-abort /usr/bin/sbuild-abort flags=(unconfined) {
++profile sbuild-abort /usr/bin/sbuild-abort flags=(attach_disconnected mediate_deleted) {
++ allow all,
++
++ # override default pix
++ /usr/bin/unshare ix,
++
+ userns,
+
+ # Site-specific additions and overrides. See local/README for details.
+diff --git a/profiles/apparmor.d/sbuild-adduser b/profiles/apparmor.d/sbuild-adduser
+index a7f1322ba..bb67c50e7 100644
+--- a/profiles/apparmor.d/sbuild-adduser
++++ b/profiles/apparmor.d/sbuild-adduser
+@@ -4,7 +4,12 @@
+ abi <abi/4.0>,
+ include <tunables/global>
+
+-profile sbuild-adduser /usr/sbin/sbuild-adduser flags=(unconfined) {
++profile sbuild-adduser /usr/sbin/sbuild-adduser flags=(attach_disconnected mediate_deleted) {
++ allow all,
++
++ # override default pix
++ /usr/bin/unshare ix,
++
+ userns,
+
+ # Site-specific additions and overrides. See local/README for details.
+diff --git a/profiles/apparmor.d/sbuild-apt b/profiles/apparmor.d/sbuild-apt
+index 0257e4574..f50fc4f3b 100644
+--- a/profiles/apparmor.d/sbuild-apt
++++ b/profiles/apparmor.d/sbuild-apt
+@@ -4,7 +4,12 @@
+ abi <abi/4.0>,
+ include <tunables/global>
+
+-profile sbuild-apt /usr/bin/sbuild-apt flags=(unconfined) {
++profile sbuild-apt /usr/bin/sbuild-apt flags=(attach_disconnected mediate_deleted) {
++ allow all,
++
++ # override default pix
++ /usr/bin/unshare ix,
++
+ userns,
+
+ # Site-specific additions and overrides. See local/README for details.
+diff --git a/profiles/apparmor.d/sbuild-checkpackages b/profiles/apparmor.d/sbuild-checkpackages
+index aa52207eb..c4f8812d1 100644
+--- a/profiles/apparmor.d/sbuild-checkpackages
++++ b/profiles/apparmor.d/sbuild-checkpackages
+@@ -4,7 +4,12 @@
+ abi <abi/4.0>,
+ include <tunables/global>
+
+-profile sbuild-checkpackages /usr/bin/sbuild-checkpackages flags=(unconfined) {
++profile sbuild-checkpackages /usr/bin/sbuild-checkpackages flags=(attach_disconnected mediate_deleted) {
++ allow all,
++
++ # override default pix
++ /usr/bin/unshare ix,
++
+ userns,
+
+ # Site-specific additions and overrides. See local/README for details.
+diff --git a/profiles/apparmor.d/sbuild-clean b/profiles/apparmor.d/sbuild-clean
+index c2ecc9cf7..eca646a51 100644
+--- a/profiles/apparmor.d/sbuild-clean
++++ b/profiles/apparmor.d/sbuild-clean
+@@ -4,7 +4,12 @@
+ abi <abi/4.0>,
+ include <tunables/global>
+
+-profile sbuild-clean /usr/bin/sbuild-clean flags=(unconfined) {
++profile sbuild-clean /usr/bin/sbuild-clean flags=(attach_disconnected mediate_deleted) {
++ allow all,
++
++ # override default pix
++ /usr/bin/unshare ix,
++
+ userns,
+
+ # Site-specific additions and overrides. See local/README for details.
+diff --git a/profiles/apparmor.d/sbuild-createchroot b/profiles/apparmor.d/sbuild-createchroot
+index e58b130c3..85ffa3ed6 100644
+--- a/profiles/apparmor.d/sbuild-createchroot
++++ b/profiles/apparmor.d/sbuild-createchroot
+@@ -4,7 +4,12 @@
+ abi <abi/4.0>,
+ include <tunables/global>
+
+-profile sbuild-createchroot /usr/bin/sbuild-createchroot flags=(unconfined) {
++profile sbuild-createchroot /usr/bin/sbuild-createchroot flags=(attach_disconnected mediate_deleted) {
++ allow all,
++
++ # override default pix
++ /usr/bin/unshare ix,
++
+ userns,
+
+ # Site-specific additions and overrides. See local/README for details.
+diff --git a/profiles/apparmor.d/sbuild-destroychroot b/profiles/apparmor.d/sbuild-destroychroot
+index 217809723..7232c2ce6 100644
+--- a/profiles/apparmor.d/sbuild-destroychroot
++++ b/profiles/apparmor.d/sbuild-destroychroot
+@@ -4,7 +4,12 @@
+ abi <abi/4.0>,
+ include <tunables/global>
+
+-profile sbuild-destroychroot /usr/sbin/sbuild-destroychroot flags=(unconfined) {
++profile sbuild-destroychroot /usr/sbin/sbuild-destroychroot flags=(attach_disconnected mediate_deleted) {
++ allow all,
++
++ # override default pix
++ /usr/bin/unshare ix,
++
+ userns,
+
+ # Site-specific additions and overrides. See local/README for details.
+diff --git a/profiles/apparmor.d/sbuild-distupgrade b/profiles/apparmor.d/sbuild-distupgrade
+index c5c6f7dfd..8df44146f 100644
+--- a/profiles/apparmor.d/sbuild-distupgrade
++++ b/profiles/apparmor.d/sbuild-distupgrade
+@@ -4,7 +4,12 @@
+ abi <abi/4.0>,
+ include <tunables/global>
+
+-profile sbuild-distupgrade /usr/bin/sbuild-distupgrade flags=(unconfined) {
++profile sbuild-distupgrade /usr/bin/sbuild-distupgrade flags=(attach_disconnected mediate_deleted) {
++ allow all,
++
++ # override default pix
++ /usr/bin/unshare ix,
++
+ userns,
+
+ # Site-specific additions and overrides. See local/README for details.
+diff --git a/profiles/apparmor.d/sbuild-hold b/profiles/apparmor.d/sbuild-hold
+index 7f592f1cc..0a07994ec 100644
+--- a/profiles/apparmor.d/sbuild-hold
++++ b/profiles/apparmor.d/sbuild-hold
+@@ -4,7 +4,12 @@
+ abi <abi/4.0>,
+ include <tunables/global>
+
+-profile sbuild-hold /usr/bin/sbuild-hold flags=(unconfined) {
++profile sbuild-hold /usr/bin/sbuild-hold flags=(attach_disconnected mediate_deleted) {
++ allow all,
++
++ # override default pix
++ /usr/bin/unshare ix,
++
+ userns,
+
+ # Site-specific additions and overrides. See local/README for details.
+diff --git a/profiles/apparmor.d/sbuild-shell b/profiles/apparmor.d/sbuild-shell
+index be97320fd..d93b70e6d 100644
+--- a/profiles/apparmor.d/sbuild-shell
++++ b/profiles/apparmor.d/sbuild-shell
+@@ -4,7 +4,12 @@
+ abi <abi/4.0>,
+ include <tunables/global>
+
+-profile sbuild-shell /usr/bin/sbuild-shell flags=(unconfined) {
++profile sbuild-shell /usr/bin/sbuild-shell flags=(attach_disconnected mediate_deleted) {
++ allow all,
++
++ # override default pix
++ /usr/bin/unshare ix,
++
+ userns,
+
+ # Site-specific additions and overrides. See local/README for details.
+diff --git a/profiles/apparmor.d/sbuild-unhold b/profiles/apparmor.d/sbuild-unhold
+index c06f56deb..13c009633 100644
+--- a/profiles/apparmor.d/sbuild-unhold
++++ b/profiles/apparmor.d/sbuild-unhold
+@@ -4,7 +4,12 @@
+ abi <abi/4.0>,
+ include <tunables/global>
+
+-profile sbuild-unhold /usr/bin/sbuild-unhold flags=(unconfined) {
++profile sbuild-unhold /usr/bin/sbuild-unhold flags=(attach_disconnected mediate_deleted) {
++ allow all,
++
++ # override default pix
++ /usr/bin/unshare ix,
++
+ userns,
+
+ # Site-specific additions and overrides. See local/README for details.
+diff --git a/profiles/apparmor.d/sbuild-update b/profiles/apparmor.d/sbuild-update
+index dcca130df..764c11e26 100644
+--- a/profiles/apparmor.d/sbuild-update
++++ b/profiles/apparmor.d/sbuild-update
+@@ -4,7 +4,12 @@
+ abi <abi/4.0>,
+ include <tunables/global>
+
+-profile sbuild-update /usr/bin/sbuild-update flags=(unconfined) {
++profile sbuild-update /usr/bin/sbuild-update flags=(attach_disconnected mediate_deleted) {
++ allow all,
++
++ # override default pix
++ /usr/bin/unshare ix,
++
+ userns,
+
+ # Site-specific additions and overrides. See local/README for details.
+diff --git a/profiles/apparmor.d/sbuild-upgrade b/profiles/apparmor.d/sbuild-upgrade
+index be154b03e..3ee9d328a 100644
+--- a/profiles/apparmor.d/sbuild-upgrade
++++ b/profiles/apparmor.d/sbuild-upgrade
+@@ -4,7 +4,12 @@
+ abi <abi/4.0>,
+ include <tunables/global>
+
+-profile sbuild-upgrade /usr/bin/sbuild-upgrade flags=(unconfined) {
++profile sbuild-upgrade /usr/bin/sbuild-upgrade flags=(attach_disconnected mediate_deleted) {
++ allow all,
++
++ # override default pix
++ /usr/bin/unshare ix,
++
+ userns,
+
+ # Site-specific additions and overrides. See local/README for details.
+--
+GitLab
+
diff --git a/debian/patches/ubuntu/socat_mr_1319.patch b/debian/patches/ubuntu/socat_mr_1319.patch
new file mode 100644
index 0000000..8bffdd1
--- /dev/null
+++ b/debian/patches/ubuntu/socat_mr_1319.patch
@@ -0,0 +1,75 @@
+From a0bb3e01325b92aa755a5db2ea5e4d42c7af6bc4 Mon Sep 17 00:00:00 2001
+From: Nishit Majithia <nishit.nm at gmail.com>
+Date: Sun, 1 Sep 2024 09:42:50 +0530
+Subject: [PATCH] socat: add profile
+
+Signed-off-by: Nishit Majithia <nishit.nm at gmail.com>
+---
+ profiles/apparmor/profiles/extras/socat | 55 +++++++++++++++++++++++++
+ 1 file changed, 55 insertions(+)
+ create mode 100644 profiles/apparmor/profiles/extras/socat
+
+diff --git a/profiles/apparmor/profiles/extras/socat b/profiles/apparmor/profiles/extras/socat
+new file mode 100644
+index 000000000..85c579dad
+--- /dev/null
++++ b/profiles/apparmor/profiles/extras/socat
+@@ -0,0 +1,55 @@
++#------------------------------------------------------------------
++# Copyright (C) 2024 Canonical Ltd.
++#
++# Author: Nishit Majithia (0xnishit)
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#------------------------------------------------------------------
++# vim: ft=apparmor
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile socat /usr/bin/socat {
++ include <abstractions/base>
++ include <abstractions/nameservice-strict>
++ include <abstractions/ssl_certs>
++ include <abstractions/consoles>
++
++ capability dac_read_search,
++ capability dac_override,
++ capability net_raw,
++ capability net_admin,
++ capability sys_module,
++ capability sys_admin,
++ capability fsetid,
++ capability chown,
++ capability net_bind_service,
++ capability sys_resource,
++
++ # Allow creation of network sockets and `socat` uses dccp for some
++ # fuctionalities that is why it is necessary to allow whole `network`
++ network,
++
++ # Allow executable mapping and read for the binary
++ file mr /usr/bin/socat,
++
++ # Enable /dev/ptmx access for testsuite
++ # file rw /dev/ptmx,
++
++ # TUN/TAP device
++ file rw /dev/net/tun,
++
++ # Process-specific access
++ file rw @{PROC}/@{pid}/fdinfo/[0-9]*,
++ file r @{PROC}/@{pid}/stat,
++
++ # For bi-directional communication between vms and host/hypervisor
++ file r /dev/vsock,
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/socat>
++}
+--
+2.43.0
+
diff --git a/debian/patches/ubuntu/tar_cap_fowner_fix_mr_1553.patch b/debian/patches/ubuntu/tar_cap_fowner_fix_mr_1553.patch
new file mode 100644
index 0000000..c6d75cb
--- /dev/null
+++ b/debian/patches/ubuntu/tar_cap_fowner_fix_mr_1553.patch
@@ -0,0 +1,28 @@
+From 09573220d2edad856b3f46712bbbb401877c6a9a Mon Sep 17 00:00:00 2001
+From: Ryan Lee <ryan.lee at canonical.com>
+Date: Tue, 18 Feb 2025 17:11:55 -0800
+Subject: [PATCH] profiles: add missing fowner capability to the tar profile
+
+This manifested with chmod calls failing in autopkgtests of dbus and snapd
+
+Reported-by: Alex Murray <alex.murray at canonical.com>
+Signed-off-by: Ryan Lee <ryan.lee at canonical.com>
+---
+ profiles/apparmor.d/tar | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/profiles/apparmor.d/tar b/profiles/apparmor.d/tar
+index 444fea7d5..e244879d9 100644
+--- a/profiles/apparmor.d/tar
++++ b/profiles/apparmor.d/tar
+@@ -16,6 +16,7 @@ profile tar /usr/bin/tar {
+
+ # used to extract user files as root
+ capability chown,
++ capability fowner,
+
+ # used to compress user files as root
+ capability dac_override,
+--
+GitLab
+
diff --git a/debian/patches/ubuntu/tar_mr_1453.patch b/debian/patches/ubuntu/tar_mr_1453.patch
new file mode 100644
index 0000000..c5ebb81
--- /dev/null
+++ b/debian/patches/ubuntu/tar_mr_1453.patch
@@ -0,0 +1,77 @@
+From 193299280ec84104a6458d9c1cd6e62c12edd628 Mon Sep 17 00:00:00 2001
+From: Octavio Galland <octavio.galland at canonical.com>
+Date: Mon, 9 Dec 2024 14:00:52 -0300
+Subject: [PATCH] Initial profile for tar binary
+
+---
+ profiles/apparmor.d/tar | 37 ++++++++++++++++++++++++++++++++++++
+ tests/profiles/tar/task.yaml | 13 +++++++++++++
+ 2 files changed, 50 insertions(+)
+ create mode 100644 profiles/apparmor.d/tar
+ create mode 100644 tests/profiles/tar/task.yaml
+
+diff --git a/profiles/apparmor.d/tar b/profiles/apparmor.d/tar
+new file mode 100644
+index 000000000..444fea7d5
+--- /dev/null
++++ b/profiles/apparmor.d/tar
+@@ -0,0 +1,37 @@
++#------------------------------------------------------------------
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#------------------------------------------------------------------
++# vim: ft=apparmor
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile tar /usr/bin/tar {
++ include <abstractions/base>
++
++ # used to extract user files as root
++ capability chown,
++
++ # used to compress user files as root
++ capability dac_override,
++ capability dac_read_search,
++
++ file rwl /**,
++
++ # tar can be made to filter archives through an arbitrary program
++ /{usr{/local,},}/{bin,sbin}/* ix,
++ /opt/** ix,
++
++ # tar can compress/extract files over rsh/ssh
++ network stream ip=127.0.0.1,
++ network stream ip=::1,
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/tar>
++}
++
+diff --git a/tests/profiles/tar/task.yaml b/tests/profiles/tar/task.yaml
+new file mode 100644
+index 000000000..ebfd13295
+--- /dev/null
++++ b/tests/profiles/tar/task.yaml
+@@ -0,0 +1,13 @@
++summary: smoke test for the tar profile
++execute: |
++ # tar works (this is a very basic test).
++ # create a text file, archive it and delete the original file
++ echo "test" > file.txt
++ tar -czf archive.tar file.txt
++ rm file.txt
++ # extract archive, assert content is correct
++ tar -xzf archive.tar
++ test "$(cat file.txt)" = "test"
++
++ # The profile is attached based on the program path.
++ "$SPREAD_PATH"/tests/bin/actual-profile-of tar | MATCH 'tar \(enforce\)'
+--
+2.43.0
+
diff --git a/debian/patches/ubuntu/tinyproxy_mr_1477.patch b/debian/patches/ubuntu/tinyproxy_mr_1477.patch
new file mode 100644
index 0000000..78f32d6
--- /dev/null
+++ b/debian/patches/ubuntu/tinyproxy_mr_1477.patch
@@ -0,0 +1,112 @@
+From 088def41760f171fbe1e90b4f052e4f65cf17b50 Mon Sep 17 00:00:00 2001
+From: Alex Murray <alex.murray at canonical.com>
+Date: Thu, 9 Jan 2025 14:49:40 +1030
+Subject: [PATCH] profiles/apparmor.d: add profile for tinyproxy
+
+This was tested using the test-tinyproxy.py script from qa-regression-testing as
+well as by running the upstream test suite with a brief hack to ensure it
+invokes tinyproxy with aa-exec -p tinyproxy first.
+
+Signed-off-by: Alex Murray <alex.murray at canonical.com>
+---
+ .image-garden.mk | 1 +
+ profiles/apparmor.d/tinyproxy | 58 ++++++++++++++++++++++++++++++
+ tests/profiles/tinyproxy/task.yaml | 14 ++++++++
+ 3 files changed, 73 insertions(+)
+ create mode 100644 profiles/apparmor.d/tinyproxy
+ create mode 100644 tests/profiles/tinyproxy/task.yaml
+
+Index: b/.image-garden.mk
+===================================================================
+--- a/.image-garden.mk 2025-02-11 17:06:05.746603278 -0800
++++ b/.image-garden.mk 2025-02-11 17:06:05.743603292 -0800
+@@ -78,6 +78,7 @@
+ - python311
+ - python311-devel
+ - swig
++- tinyproxy
+ endef
+
+ define FEDORA_CLOUD_INIT_USER_DATA_TEMPLATE
+Index: b/profiles/apparmor.d/tinyproxy
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ b/profiles/apparmor.d/tinyproxy 2025-02-11 17:06:05.743603292 -0800
+@@ -0,0 +1,58 @@
++# -*- mode: apparmor; -*-
++# ------------------------------------------------------------------
++#
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#
++# ------------------------------------------------------------------
++# vim: ft=apparmor
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile tinyproxy /usr/bin/tinyproxy {
++ include <abstractions/base>
++ include <abstractions/nameservice-strict>
++
++ # allow to drop privileges
++ capability setuid,
++ capability setgid,
++
++ # to provide flexibility, when run as root tinyproxy may need to read files
++ # owned by other users
++ capability dac_override,
++ capability dac_read_search,
++ # also tinyproxy may be configured to bind to a privileged port so ensure we
++ # allow this as well
++ capability net_bind_service,
++
++ file mr /usr/bin/tinyproxy,
++
++ file r @{etc_ro}/tinyproxy/tinyproxy.conf,
++ # tinyproxy.conf allows to configure the locations of various files that will
++ # be written to by tinyproxy including ErrorFile, DefaultErrorFile, LogFile,
++ # and StatFile as well as PidFile. This profile allows tinyproxy to write to
++ # the default locations but if these are changed in the configuration file,
++ # additional rules should be added to the /etc/apparmor.d/local/tinyproxy file
++ # to allow this access
++ file rw /run/tinyproxy/tinyproxy.pid, # PidFile
++ file rw /var/log/tinyproxy/tinyproxy.log, # LogFile
++
++ file r /usr/share/tinyproxy/*, #ErrorFile, DefaultErrorFile, StatFile etc
++
++ # for network access
++ network inet stream,
++ network inet dgram,
++ network inet6 stream,
++ network inet6 dgram,
++
++ # for DNS resolution
++ network netlink raw,
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/tinyproxy>
++}
+Index: b/tests/profiles/tinyproxy/task.yaml
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ b/tests/profiles/tinyproxy/task.yaml 2025-02-11 17:06:05.743603292 -0800
+@@ -0,0 +1,14 @@
++summary: smoke test for the tinyproxy profile
++execute: |
++ # restart tinyproxy service as it may already be running
++ systemctl restart tinyproxy
++
++ # wait for it to be running
++ sleep 1
++
++ # check is running
++ systemctl is-active tinyproxy
++
++ # check tinyproxy system service is confined
++ cat /proc/$(pidof tinyproxy)/attr/apparmor/current | MATCH 'tinyproxy \(enforce\)'
++
diff --git a/debian/patches/ubuntu/tnftp_mr_1363.patch b/debian/patches/ubuntu/tnftp_mr_1363.patch
new file mode 100644
index 0000000..f7ec3a3
--- /dev/null
+++ b/debian/patches/ubuntu/tnftp_mr_1363.patch
@@ -0,0 +1,107 @@
+From f311164a28e5a4dedbf51a89d520a89e065f29b1 Mon Sep 17 00:00:00 2001
+From: Giampaolo Fresi Roglia <giampaolo.fresi.roglia at canonical.com>
+Date: Fri, 4 Oct 2024 16:23:48 +0200
+Subject: [PATCH] apparmor.d: add tnftp profile
+
+---
+ profiles/apparmor.d/tnftp | 88 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 88 insertions(+)
+ create mode 100644 profiles/apparmor.d/tnftp
+
+diff --git a/profiles/apparmor.d/tnftp b/profiles/apparmor.d/tnftp
+new file mode 100644
+index 000000000..73a938de2
+--- /dev/null
++++ b/profiles/apparmor.d/tnftp
+@@ -0,0 +1,88 @@
++
++#------------------------------------------------------------------
++# Copyright (C) 2024 Canonical Ltd.
++#
++# Author: Giampaolo Fresi Roglia (gianz)
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#------------------------------------------------------------------
++# vim: ft=apparmor
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++@{tnftp_rx}=/bin/ /sbin/ /usr/bin/ /usr/sbin/ /usr/local/bin/ /usr/local/sbin/ /usr/games/ /usr/local/games/ /snap/bin/ @{HOME}/bin/ @{HOME}/.local/bin/
++
++profile tnftp /usr/bin/tnftp {
++ include <abstractions/authentication>
++ include <abstractions/base>
++ include <abstractions/consoles>
++ include <abstractions/nameservice>
++ include <abstractions/user-tmp>
++ include <abstractions/user-download>
++ include <abstractions/private-files-strict>
++
++ network inet stream,
++ network inet6 stream,
++
++ # readline wants to know terminal capabilities
++ file r /usr/share/terminfo/**,
++
++ # required for the pager (less, more) to work
++ file Cx /usr/bin/dash,
++
++ # allow read on anything on @{HOME} not explicitly denied
++ owner file r @{HOME},
++ owner file r @{HOME}/**,
++
++ # Sub-profile for the pager to work
++ profile dash /usr/bin/dash {
++ include <abstractions/base>
++ network (send, receive) inet stream,
++ network (send, receive) inet6 stream,
++
++ file Px /usr/bin/more -> tnftp//dash//more,
++ file mr /usr/bin/dash,
++ }
++
++ # Ideally this would be a subprofile of "dash".
++ # Defined as sub profile of tnftp for backwards compatibility.
++ profile dash//more {
++ include <abstractions/base>
++ network (send, receive) inet stream,
++ network (send, receive) inet6 stream,
++
++ # readline wants to know terminal capabilities
++ file r /usr/share/terminfo/**,
++ file mr /usr/bin/more,
++ }
++
++ # required for the ! command to work.
++ # here we are restricting execution to files in a limited set of
++ # directories, for which we also deny write access.
++ file Cx @{tnftp_rx}/* -> cmds,
++ audit deny file w @{tnftp_rx}/*,
++
++ profile cmds {
++ include <abstractions/base>
++ include <abstractions/consoles>
++ include <abstractions/user-tmp>
++ include <abstractions/user-download>
++ include <abstractions/private-files-strict>
++
++ # prevent network access
++ deny network,
++
++ file ixmr @{tnftp_rx}/*,
++ audit deny file w @{tnftp_rx}/*,
++
++ # allow read on anything on @{HOME} not explicitly denied
++ owner file r @{HOME},
++ owner file r @{HOME}/**,
++ }
++
++ include if exists <local/tnftp>
++}
+--
+2.43.0
+
diff --git a/debian/patches/ubuntu/tshark_mr_1384.patch b/debian/patches/ubuntu/tshark_mr_1384.patch
new file mode 100644
index 0000000..e71646e
--- /dev/null
+++ b/debian/patches/ubuntu/tshark_mr_1384.patch
@@ -0,0 +1,87 @@
+From 57d1cce195a8a06e537d7a9ca3429ddd97a40a85 Mon Sep 17 00:00:00 2001
+From: Shishir Subedi <shishir.subedi at canonical.com>
+Date: Thu, 17 Oct 2024 15:15:08 +0545
+Subject: [PATCH] add tshark profile
+
+---
+ profiles/apparmor.d/tshark | 68 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 68 insertions(+)
+ create mode 100644 profiles/apparmor.d/tshark
+
+diff --git a/profiles/apparmor.d/tshark b/profiles/apparmor.d/tshark
+new file mode 100644
+index 000000000..0f54b3970
+--- /dev/null
++++ b/profiles/apparmor.d/tshark
+@@ -0,0 +1,68 @@
++#------------------------------------------------------------------
++# Copyright (C) 2024 Canonical Ltd.
++#
++# Author: Shishir Subedi (shishir.subedi at canonical.com)
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#------------------------------------------------------------------
++# vim: ft=apparmor
++#
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile tshark /usr/bin/tshark {
++ include <abstractions/base>
++ include <abstractions/nameservice>
++ include <abstractions/user-tmp>
++
++ capability dac_read_search,
++
++ signal send peer=tshark//dumpcap,
++
++ file Cx /usr/bin/dumpcap -> dumpcap,
++ file mr /usr/bin/tshark,
++ file mrix /usr/lib/@{multiarch}/wireshark/extcap/{,*},
++ file r /usr/share/wireshark/{,**},
++ file r @{PROC}/@{pid}/fd/,
++
++ # for -i sdjournal
++ file r /{var,run}/log/journal/{,**},
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/tshark>
++
++ profile dumpcap {
++ include <abstractions/base>
++ include <abstractions/nameservice>
++ include <abstractions/private-files-strict>
++ include <abstractions/user-tmp>
++ include <abstractions/user-write>
++
++ capability net_admin,
++ capability net_raw,
++
++ network packet,
++ network raw,
++ network stream,
++
++ dbus (eavesdrop receive) bus=system,
++
++ signal receive peer=tshark,
++
++ file r /dev/,
++ file r @{PROC}/@{pid}/net/dev,
++ file r @{sys}/devices/{,**},
++ file rw @{sys}/devices/**/statistics/rx_*,
++
++ file r /**.pcap{,ng}{,.gz},
++ owner rw /**.pcap{,ng}{,.gz},
++
++ owner rw @{run}/dbus/system_bus_socket,
++ file mr /usr/bin/dumpcap,
++
++ }
++}
+--
+2.43.0
+
diff --git a/debian/patches/ubuntu/utils-change-os.mkdir-to-self.mkpath-to-create-inter.patch b/debian/patches/ubuntu/utils-change-os.mkdir-to-self.mkpath-to-create-inter.patch
deleted file mode 100644
index 6f756e0..0000000
--- a/debian/patches/ubuntu/utils-change-os.mkdir-to-self.mkpath-to-create-inter.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From a3eca67f380a900327400dcfd0753ad955f3cac3 Mon Sep 17 00:00:00 2001
-From: Georgia Garcia <georgia.garcia at canonical.com>
-Date: Thu, 15 Aug 2024 00:44:55 -0300
-Subject: [PATCH] utils: change os.mkdir to self.mkpath to create intermediary
- dirs
-
-Signed-off-by: Georgia Garcia <georgia.garcia at canonical.com>
----
- utils/python-tools-setup.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/utils/python-tools-setup.py b/utils/python-tools-setup.py
-index e84375898..363762ce6 100644
---- a/utils/python-tools-setup.py
-+++ b/utils/python-tools-setup.py
-@@ -68,7 +68,7 @@ class Install(_install):
- polkit = polkit_template.format(LIB_PATH=self.install_lib)
-
- if not os.path.exists(prefix + '/usr/share/polkit-1/actions/'):
-- os.mkdir(prefix + '/usr/share/polkit-1/actions/')
-+ self.mkpath(prefix + '/usr/share/polkit-1/actions/')
- with open(prefix + '/usr/share/polkit-1/actions/' + pkexec_action_name, 'w') as f:
- f.write(polkit)
- os.chmod(prefix + '/usr/share/polkit-1/actions/' + pkexec_action_name, 0o644)
---
-2.34.1
-
diff --git a/debian/patches/ubuntu/wireguard_mr_1323.patch b/debian/patches/ubuntu/wireguard_mr_1323.patch
new file mode 100644
index 0000000..04650a8
--- /dev/null
+++ b/debian/patches/ubuntu/wireguard_mr_1323.patch
@@ -0,0 +1,178 @@
+From cb7e58bbb5ec5bcd64b0b8ed0169dee1d2f2d270 Mon Sep 17 00:00:00 2001
+From: Evan Caville <evan.caville at canonical.com>
+Date: Tue, 3 Sep 2024 14:21:04 +1000
+Subject: [PATCH] profiles/apparmor.d: add wireguard profile
+
+Signed-off-by: Evan Caville <evan.caville at canonical.com>
+---
+ profiles/apparmor.d/wg | 35 +++++++++++
+ profiles/apparmor.d/wg-quick | 115 +++++++++++++++++++++++++++++++++++
+ 2 files changed, 150 insertions(+)
+ create mode 100644 profiles/apparmor.d/wg
+ create mode 100644 profiles/apparmor.d/wg-quick
+
+diff --git a/profiles/apparmor.d/wg b/profiles/apparmor.d/wg
+new file mode 100644
+index 000000000..9698a7ac4
+--- /dev/null
++++ b/profiles/apparmor.d/wg
+@@ -0,0 +1,35 @@
++#------------------------------------------------------------------
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#------------------------------------------------------------------
++# vim: ft=apparmor
++#
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile wg /usr/bin/wg flags=(attach_disconnected){
++ include <abstractions/base>
++ include <abstractions/nameservice-strict>
++
++ capability net_admin,
++ capability net_bind_service,
++
++ # Network access rules
++ network netlink raw,
++ network inet dgram,
++ network inet6 dgram,
++ network inet stream,
++ network inet6 stream,
++
++ # wireguard configuration and key files
++ file rw @{etc_rw}/wireguard/{,**},
++
++ file mr /usr/bin/wg,
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/wg>
++}
+diff --git a/profiles/apparmor.d/wg-quick b/profiles/apparmor.d/wg-quick
+new file mode 100644
+index 000000000..68b191c86
+--- /dev/null
++++ b/profiles/apparmor.d/wg-quick
+@@ -0,0 +1,115 @@
++#------------------------------------------------------------------
++# Copyright (C) 2024 Canonical Ltd.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#------------------------------------------------------------------
++# vim: ft=apparmor
++#
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile wg-quick /usr/bin/wg-quick flags=(attach_disconnected) {
++ include <abstractions/base>
++ include <abstractions/consoles>
++
++ capability dac_read_search,
++ capability net_admin,
++
++ # Network access rules
++ network netlink raw,
++ network unix stream,
++
++ # use wg aa profile
++ file mrpx /usr/bin/wg -> wg,
++
++ # binaries called from within wg-quick
++ file mrix /usr/bin/readlink,
++ file mrix /usr/bin/stat,
++ file mrix /usr/bin/cat,
++ file mrix /usr/bin/rm,
++ file mrix /usr/bin/mv,
++ file mrix /usr/bin/sync,
++ file mrix /usr/bin/sort,
++ file mrix /usr/sbin/xtables-nft-multi,
++ file mrix /usr/bin/resolvectl,
++ file mrix /usr/sbin/resolvconf,
++
++ # dbus access
++ file rw @{run}/dbus/system_bus_socket,
++
++ dbus (send)
++ bus=system
++ path=/org/freedesktop/resolve1
++ interface=org.freedesktop.resolve1.Manager
++ member="SetLink{DNSEx,Domains}"
++ peer=(name=org.freedesktop.resolve1, label=unconfined),
++
++ dbus (send)
++ bus=system
++ path=/org/freedesktop/DBus
++ interface=org.freedesktop.DBus
++ member="Hello"
++ peer=(name=org.freedesktop.DBus, label=unconfined),
++
++ # Sub-profile for nft tool restrictions
++ file mrCx /usr/sbin/nft,
++ profile nft /usr/sbin/nft {
++ include <abstractions/base>
++
++ capability net_admin,
++
++ # Allow executable mapping and read for the binary
++ file mr /usr/sbin/nft,
++
++ # Network access rules
++ network netlink raw,
++
++ file r /usr/share/iproute2/rt_realms,
++ file r /usr/share/iproute2/group,
++ }
++
++ # Sub-profile for IP tool restrictions
++ file mrCx /usr/bin/ip,
++ profile ip /usr/bin/ip {
++ include <abstractions/base>
++
++ capability net_admin,
++ capability sys_module,
++
++ # Allow executable mapping and read for the binary
++ file mr /usr/bin/ip,
++
++ # Network access rules
++ network netlink raw,
++
++ file r /usr/share/iproute2/group,
++ file r /usr/share/iproute2/rt_tables,
++ file r @{run}/netns/{,**},
++ }
++
++ # Sub-profile for sysctl tool restrictions
++ file mrCx /usr/sbin/sysctl,
++ profile sysctl /usr/sbin/sysctl {
++ include <abstractions/base>
++
++ # Allow executable mapping and read for the binary
++ file mr /usr/sbin/sysctl,
++
++ file w @{PROC}/sys/net/ipv4/conf/all/src_valid_mark,
++ }
++
++ # wireguard configuration and key files
++ file rw @{etc_rw}/wireguard/{,**},
++
++ # Allow executable mapping and read for the binary
++ file mr /usr/bin/wg-quick,
++
++ # Process-specific access
++ file r @{PROC}/@{pid}/net/ip_tables_names,
++
++ # Site-specific additions and overrides. See local/README for details.
++ include if exists <local/wg-quick>
++}
+--
+2.43.0
+
diff --git a/debian/patches/ubuntu/wpa_supplicant_mr_1385.patch b/debian/patches/ubuntu/wpa_supplicant_mr_1385.patch
new file mode 100644
index 0000000..2b4dd8a
--- /dev/null
+++ b/debian/patches/ubuntu/wpa_supplicant_mr_1385.patch
@@ -0,0 +1,75 @@
+Author: Sudhakar Verma <sudhakar.verma at canonical.com>
+MR link: https://gitlab.com/apparmor/apparmor/-/merge_requests/1385
+Subject: profiles: add wpa_supplicant
+
+diff --git a/profiles/apparmor.d/wpa_supplicant b/profiles/apparmor.d/wpa_supplicant
+new file mode 100644
+index 0000000000000000000000000000000000000000..b87bfeee838d9dd60c1bc53310f2deb81d6457c2
+--- /dev/null
++++ b/profiles/apparmor.d/wpa_supplicant
+@@ -0,0 +1,65 @@
++# Copyright (C) 2024 Canonical Ltd.
++#
++# Author: sudhackar <sudhakar.verma at canonical.com>
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of version 2 of the GNU General Public
++# License published by the Free Software Foundation.
++#------------------------------------------------------------------
++# vim: ft=apparmor
++
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile wpa_supplicant /usr/sbin/wpa_supplicant {
++ include <abstractions/base>
++ include <abstractions/dbus-strict>
++
++ capability chown,
++ capability net_admin,
++ capability net_raw,
++
++ dbus (bind) bus=system name=fi.w1.wpa_supplicant1,
++ dbus (receive)
++ bus=system
++ path=/fi/w1/wpa_supplicant1
++ interface=fi.w1.wpa_supplicant1
++ member={CreateInterface,ExpectDisconnect,GetInterface,InterfaceRemoved,RemoveInterface},
++
++
++ dbus (receive)
++ bus=system
++ path=/fi/w1/wpa_supplicant1/**
++ interface=org.freedesktop.DBus.Properties
++ member={GetAll,Set},
++
++ dbus (receive)
++ bus=system
++ path=/fi/w1/wpa_supplicant1/Interfaces/**
++ interface=fi.w1.wpa_supplicant1.Interface
++ member={AbortScan,AddBlob,AddCred,AddNetwork,AddPersistentGroup,AddService,AutoScan,Cancel,Connect,DeleteService,Disconnect,EAPLogoff,EAPLogon,ExtendedListen,Find,Flush,FlushBSS,FlushService,GetBlob,GroupAdd,InterworkingSelect,Invite,Listen,NetworkReply,PresenceRequest,ProvisionDiscoveryRequest,Reassociate,Reattach,Reconnect,RejectPeer,RemoveAllCreds,RemoveAllNetworks,RemoveAllPersistentGroups,RemoveBlob,RemoveClient,RemoveCred,RemoveNetwork,RemovePersistentGroup,Roam,SaveConfig,Scan,SelectNetwork,ServiceDiscoveryCancelRequest,ServiceDiscoveryExternal,ServiceDiscoveryRequest,ServiceDiscoveryResponse,ServiceUpdate,SetPKCS11EngineAndModulePath,SignalPoll,Start,StopFind,SubscribeProbeReq,TDLSCancelChannelSwitch,TDLSChannelSwitch,TDLSDiscover,TDLSSetup,TDLSStatus,TDLSTeardown,UnsubscribeProbeReq,VendorElemAdd,VendorElemGet,VendorElemRem},
++
++ dbus (send)
++ bus=system
++ path=/fi/w1/wpa_supplicant1/Interfaces/**
++ interface=fi.w1.wpa_supplicant1.Interface
++ member={BSSAdded,BSSRemoved,BlobAdded,BlobRemoved,Certification,Credentials,DeviceFound,DeviceFoundProperties,DeviceLost,EAP,Event,FindStopped,GONegotiationFailure,GONegotiationRequest,GONegotiationSuccess,GroupFinished,GroupFormationFailure,GroupStarted,InterworkingAPAdded,InterworkingSelectDone,(receiveInvitationResult,MeshGroupRemoved,MeshGroupStarted,MeshPeerConnected,MeshPeerDisconnected,NetworkAdded,NetworkRemoved,NetworkRequest,NetworkSelected,PersistentGroupAdded,PersistentGroupRemoved,ProbeRequest,PropertiesChanged,ProvisionDiscoveryFailure,ProvisionDiscoveryPBCRequest,ProvisionDiscoveryPBCResponse,ProvisionDiscoveryRequestDisplayPin,ProvisionDiscoveryRequestEnterPin,ProvisionDiscoveryResponseDisplayPin,ProvisionDiscoveryResponseEnterPin,ScanDone,ServiceDiscoveryRequest,ServiceDiscoveryResponse,StaAuthorized,StaDeauthorized,StationAdded,StationRemoved,WpsFailed,PropertiesChanged},
++
++ dbus (send)
++ bus=system
++ path=/org/freedesktop/DBus
++ interface=org.freedesktop.DBus
++ member={AddMatch,GetNameOwner,Hello,ReleaseName,RemoveMatch,RequestName,StartServiceByName},
++
++ owner /dev/rfkill r,
++ owner /etc/group r,
++ owner /etc/nsswitch.conf r,
++
++ owner @{PROC}/sys/net/ipv{4,6}/conf/** rw,
++
++ owner @{run}/wpa_supplicant/ w,
++ owner @{run}/wpa_supplicant/** rw,
++
++ include if exists <local/wpa_supplicant>
++}
diff --git a/debian/patches/ubuntu/wpa_supplicant_profile_fixup.patch b/debian/patches/ubuntu/wpa_supplicant_profile_fixup.patch
new file mode 100644
index 0000000..ad6d6ff
--- /dev/null
+++ b/debian/patches/ubuntu/wpa_supplicant_profile_fixup.patch
@@ -0,0 +1,31 @@
+From 16118337e21c9e9416284978bac930abb93c9173 Mon Sep 17 00:00:00 2001
+From: Ryan Lee <ryan.lee at canonical.com>
+Date: Wed, 19 Feb 2025 14:21:46 -0800
+Subject: [PATCH] Fixes for wpa_supplicant profile based on LP: #2098838
+
+Signed-off-by: Ryan Lee <ryan.lee at canonical.com>
+---
+ profiles/apparmor.d/wpa_supplicant | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/profiles/apparmor.d/wpa_supplicant b/profiles/apparmor.d/wpa_supplicant
+index b87bfeee8..fd5cd32a5 100644
+--- a/profiles/apparmor.d/wpa_supplicant
++++ b/profiles/apparmor.d/wpa_supplicant
+@@ -61,5 +61,13 @@ profile wpa_supplicant /usr/sbin/wpa_supplicant {
+ owner @{run}/wpa_supplicant/ w,
+ owner @{run}/wpa_supplicant/** rw,
+
++ network dgram,
++ network netlink raw,
++
++ @{sys}/devices/pci[0-9]*:[0-9]*/**/ieee80211/phy[0-9]*/** r,
++ # Might also need @{sys}/class/ieee80211/ r,
++ # phy* files inside are symlinks to the pci directory but directory
++ # listing might be needed to enumerate and resolve symlinks
++
+ include if exists <local/wpa_supplicant>
+ }
+--
+GitLab
+
diff --git a/debian/patches/ubuntu/znc_mr_1376.patch b/debian/patches/ubuntu/znc_mr_1376.patch
new file mode 100644
index 0000000..1ac0f2c
--- /dev/null
+++ b/debian/patches/ubuntu/znc_mr_1376.patch
@@ -0,0 +1,62 @@
+From f7c9932c1149e857e2d5b5eafe9fbc5f0ffa9d74 Mon Sep 17 00:00:00 2001
+From: Ryan Lee <ryan.lee at canonical.com>
+Date: Tue, 15 Oct 2024 15:14:10 -0700
+Subject: [PATCH] Add a profile for ZNC
+
+Signed-off-by: Ryan Lee <ryan.lee at canonical.com>
+---
+ profiles/apparmor.d/znc | 42 +++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 42 insertions(+)
+ create mode 100644 profiles/apparmor.d/znc
+
+diff --git a/profiles/apparmor.d/znc b/profiles/apparmor.d/znc
+new file mode 100644
+index 000000000..04b478add
+--- /dev/null
++++ b/profiles/apparmor.d/znc
+@@ -0,0 +1,42 @@
++abi <abi/4.0>,
++
++include <tunables/global>
++
++profile znc /usr/bin/znc {
++ include <abstractions/base>
++ include <abstractions/nameservice>
++ include <abstractions/ssl_certs>
++
++ include <abstractions/perl>
++ include <abstractions/python>
++ # It seems that znc embeds a tcl interpreter and that there are no tcl-related abstractions
++
++ network tcp,
++
++ @{system_share_dirs}/znc/** r,
++
++ owner @{HOME}/.znc/ rw,
++ owner @{HOME}/.znc/** r,
++
++ owner @{HOME}/.znc/znc.pid rw,
++
++ owner @{HOME}/.znc/configs/ rw,
++ owner @{HOME}/.znc/configs/znc.conf rwk,
++ # Tilde version is used when the config is updated by ZNC
++ owner @{HOME}/.znc/configs/znc.conf~ rw,
++ owner @{HOME}/.znc/modules/ rw,
++ owner @{HOME}/.znc/modules/* mrw,
++ owner @{HOME}/.znc/moddata/ rw,
++ owner @{HOME}/.znc/moddata/** rw,
++ owner @{HOME}/.znc/users/ rw,
++ owner @{HOME}/.znc/users/** rw,
++
++ # Write perms on znc.pem only needed with --makeconf
++ owner @{HOME}/.znc/znc.pem rw,
++
++ # Python extensions will need to be run through a Python interpreter
++ # The Perl interpreter is already included in the abstractions file
++ /{usr/,}bin/python{3,3.[0-9],3.[1-9][0-9]} rix,
++
++ include if exists <local/znc>
++}
+--
+GitLab
+
diff --git a/debian/rules b/debian/rules
index 37ee3da..3124784 100755
--- a/debian/rules
+++ b/debian/rules
@@ -21,17 +21,6 @@ override_dh_auto_configure:
override_dh_auto_build:
- # Create the empty file that was meant to be created by
- # ubuntu/add-mqueue-support.patch.
- # Quilt does not support creating new empty files.
- touch libraries/libapparmor/testsuite/test_multi/testcase_mqueue_01.err
- touch libraries/libapparmor/testsuite/test_multi/testcase_mqueue_02.err
- touch libraries/libapparmor/testsuite/test_multi/testcase_mqueue_03.err
- touch libraries/libapparmor/testsuite/test_multi/testcase_mqueue_04.err
- touch libraries/libapparmor/testsuite/test_multi/testcase_mqueue_05.err
- touch libraries/libapparmor/testsuite/test_multi/testcase_mqueue_06.err
- touch libraries/libapparmor/testsuite/test_multi/testcase_mqueue_07.err
- touch libraries/libapparmor/testsuite/test_multi/testcase_mqueue_08.err
# Replace #VERSION# placeholder in dh_apparmor
sed -i --regexp-extended \
-e "s,^#VERSION#,our \$$VERSION = \"$(DEB_VERSION)\";," \
@@ -47,8 +36,6 @@ override_dh_auto_build:
-D libraries/libapparmor.$$py; \
done
- # Don't run '$(MAKE) check' because of too many perl dependencies
- # and various apparmor files installed on the system
# Build pythons
cd utils && $(MAKE)
for py in $(shell py3versions -s) ; do \
@@ -68,15 +55,27 @@ endif
override_dh_auto_test:
ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
-ifeq (,$(filter $(DEB_HOST_ARCH_OS), kfreebsd knetbsd hurd ))
- dh_auto_test -Dbinutils -- V=1
- dh_auto_test -Dparser -- V=1
-endif
dh_auto_test -Dlibraries/libapparmor -- V=1
+ # Doesn't make sense to run utils tests without Python version
+ #dh_auto_test -Dutils -- V=1
+
+ # Utils test needs to set PYTHON_VERSIONS and PYTHON
+ # Hacky workaround since utils make check uses a version of pyalldo
+ # and we need to specify a different libapparmor CPython module for each
+ # Also set APPARMOR_NOTIFY to use our Python version
set -e; for py in $(shell py3versions -s) ; do \
PYTHON=/usr/bin/$$py dh_auto_test \
-D libraries/libapparmor.$$py -- PYTHON=/usr/bin/$$py; \
+ LIBAPPARMOR_BASEDIR=../../libraries/libapparmor.$$py\
+ PYTHON_VERSIONS=$$py PYTHON=/usr/bin/$$py\
+ dh_auto_test \
+ -D utils.$$py/ -- LIBAPPARMOR_BASEDIR=../../libraries/libapparmor.$$py\
+ PYTHON_VERSIONS=$$py PYTHON=/usr/bin/$$py;\
done
+ifeq (,$(filter $(DEB_HOST_ARCH_OS), kfreebsd knetbsd hurd ))
+ dh_auto_test -Dbinutils -- V=1
+ dh_auto_test -Dparser -- V=1
+endif
endif
@@ -203,4 +202,4 @@ override_dh_install-arch:
done
dh_install
# Fix permissions so that aa-teardown can execute this file
- chmod 0755 $(CURDIR)/debian/apparmor/lib/apparmor/apparmor.systemd
+ chmod 0755 $(CURDIR)/debian/apparmor/usr/lib/apparmor/apparmor.systemd
diff --git a/debian/usr/lib/sysctl.d/10-apparmor.conf b/debian/usr/lib/sysctl.d/10-apparmor.conf
index 8b2624d..660b923 100644
--- a/debian/usr/lib/sysctl.d/10-apparmor.conf
+++ b/debian/usr/lib/sysctl.d/10-apparmor.conf
@@ -7,8 +7,10 @@
#
# See
# https://gitlab.com/apparmor/apparmor/-/wikis/unprivileged_userns_restriction
+# https://gitlab.com/apparmor/apparmor/-/wikis/unprivileged_unconfined
#
# If it is desired to disable this restriction, it is preferable to create an
# additional file named /etc/sysctl.d/20-apparmor.conf which will override this
# current file and sets this value to 0 rather than editing this current file
kernel.apparmor_restrict_unprivileged_userns = 1
+kernel.apparmor_restrict_unprivileged_unconfined = 1
More information about the Neon-commits
mailing list