[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