Version in base suite: 0.27-2 Base version: foomuuri_0.27-2 Target version: foomuuri_0.27-2+deb13u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/f/foomuuri/foomuuri_0.27-2.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/f/foomuuri/foomuuri_0.27-2+deb13u1.dsc changelog | 7 + control | 2 foomuuri.install | 1 patches/01.CVE-2025-67858.patch | 63 +++++++++ patches/02.CVE-2025-67603.patch | 278 ++++++++++++++++++++++++++++++++++++++++ patches/series | 2 6 files changed, 352 insertions(+), 1 deletion(-) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpzg6lujr_/foomuuri_0.27-2.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpzg6lujr_/foomuuri_0.27-2+deb13u1.dsc: no acceptable signature found diff -Nru foomuuri-0.27/debian/changelog foomuuri-0.27/debian/changelog --- foomuuri-0.27/debian/changelog 2025-02-08 10:37:36.000000000 +0000 +++ foomuuri-0.27/debian/changelog 2025-12-31 11:39:39.000000000 +0000 @@ -1,3 +1,10 @@ +foomuuri (0.27-2+deb13u1) trixie-security; urgency=high + + * Fix CVE-2025-67858 and CVE-2025-67603. + * Update maintainer. + + -- Kim B. Heino Wed, 31 Dec 2025 13:39:39 +0200 + foomuuri (0.27-2) unstable; urgency=medium * Orphaning package. diff -Nru foomuuri-0.27/debian/control foomuuri-0.27/debian/control --- foomuuri-0.27/debian/control 2025-02-08 10:34:52.000000000 +0000 +++ foomuuri-0.27/debian/control 2025-12-31 11:38:02.000000000 +0000 @@ -1,7 +1,7 @@ Source: foomuuri Section: net Priority: optional -Maintainer: Debian QA Group +Maintainer: Kim B. Heino Build-Depends: debhelper-compat (= 13), dh-python, dh-sequence-movetousr, diff -Nru foomuuri-0.27/debian/foomuuri.install foomuuri-0.27/debian/foomuuri.install --- foomuuri-0.27/debian/foomuuri.install 2025-01-28 19:58:52.000000000 +0000 +++ foomuuri-0.27/debian/foomuuri.install 2025-12-31 11:39:14.000000000 +0000 @@ -5,6 +5,7 @@ usr/lib/tmpfiles.d/foomuuri.conf usr/sbin/foomuuri usr/share/dbus-1/system.d/fi.foobar.Foomuuri1.conf +usr/share/polkit-1/actions/fi.foobar.Foomuuri1.policy usr/share/foomuuri/block.fw usr/share/foomuuri/default.services.conf usr/share/foomuuri/static.nft diff -Nru foomuuri-0.27/debian/patches/01.CVE-2025-67858.patch foomuuri-0.27/debian/patches/01.CVE-2025-67858.patch --- foomuuri-0.27/debian/patches/01.CVE-2025-67858.patch 1970-01-01 00:00:00.000000000 +0000 +++ foomuuri-0.27/debian/patches/01.CVE-2025-67858.patch 2025-12-31 11:38:35.000000000 +0000 @@ -0,0 +1,63 @@ +commit 5031645e8ec5f06ffa7b8a03aa44cedc011f2bf2 (HEAD -> v0.27-cve) +Author: Kim B. Heino +Date: Tue Dec 30 11:52:58 2025 +0200 + + CVE-2025-67858: Verify `interface` input parameter on D-Bus methods + + CVE-2025-67858: "a crafted 'interface' input parameter to D-Bus methods + can lead to integrity loss of the firewall configuration or further + unspecified impact by manipulating the JSON configuration passed to + `nft`." + +diff --git a/src/foomuuri b/src/foomuuri +index f5d40a4..ddc159c 100755 +--- a/src/foomuuri ++++ b/src/foomuuri +@@ -2488,6 +2488,21 @@ class DbusCommon: + save_final(CONFIG['dbus_file']) + run_program_rc(CONFIG['nft_bin'] + ['--file', CONFIG['dbus_file']]) + ++ @staticmethod ++ def verify_interface_name(interface): ++ """Check that interface name is valid. ++ ++ Linux accepts also \\ and " characters. Reject them here as they ++ would break JSONs without quoting. ++ """ ++ if any(letter <= ' ' for letter in interface): ++ return False # Reject whitespace and control chars as Linux does ++ if '/' in interface: ++ return False # Linux rejects this ++ if '\\' in interface or '"' in interface: ++ return False # Linux accepts these ++ return 1 <= len(interface) <= 15 # IFNAMSIZ = 16 including NUL, so 15 ++ + @staticmethod + def remove_interface(interface_zone, interface): + """Remove interface from all zones.""" +@@ -2581,6 +2596,8 @@ class DbusCommon: + + This is currently always handled as "from all". + """ ++ if not self.verify_interface_name(interface): ++ raise FoomuuriDbusException(f'Invalid interface name: {interface}') + print(f'Interface "{interface}" remove from zone "{zone}"', flush=True) + return self.change_interface_zone(interface, '')[0] + +@@ -2590,12 +2607,16 @@ class DbusCommon: + There can be only one zone per interface so it will be removed + from previous zone if needed. + """ ++ if not self.verify_interface_name(interface): ++ raise FoomuuriDbusException(f'Invalid interface name: {interface}') + zone = self.parse_default_zone(interface, zone) + print(f'Interface "{interface}" add to zone "{zone}"', flush=True) + return self.change_interface_zone(interface, zone)[1] + + def method_change_zone_of_interface(self, zone, interface): + """Change interface to zone.""" ++ if not self.verify_interface_name(interface): ++ raise FoomuuriDbusException(f'Invalid interface name: {interface}') + zone = self.parse_default_zone(interface, zone) + print(f'Interface "{interface}" change to zone "{zone}"', flush=True) + return self.change_interface_zone(interface, zone)[0] diff -Nru foomuuri-0.27/debian/patches/02.CVE-2025-67603.patch foomuuri-0.27/debian/patches/02.CVE-2025-67603.patch --- foomuuri-0.27/debian/patches/02.CVE-2025-67603.patch 1970-01-01 00:00:00.000000000 +0000 +++ foomuuri-0.27/debian/patches/02.CVE-2025-67603.patch 2025-12-31 11:38:35.000000000 +0000 @@ -0,0 +1,278 @@ +commit eff7dbb474adc7d4553a1951af74464f175cce7a (HEAD -> v0.27-cve) +Author: Kim B. Heino +Date: Tue Dec 30 12:02:40 2025 +0200 + + CVE-2025-67603: Add PolicyKit authorization to D-Bus methods + + PolicyKit is optional. Foomuuri fallbacks to "UID = 0" check if PolicyKit + is not available. + + CVE-2025-67603: "lack of client authorization allows arbitrary users to + influence the firewall configuration." + +diff --git a/Makefile b/Makefile +index 290aeef..d20c26e 100644 +--- a/Makefile ++++ b/Makefile +@@ -53,7 +53,9 @@ install: + mkdir -p $(DESTDIR)/run/foomuuri/ + mkdir -p $(DESTDIR)/var/lib/foomuuri/ + mkdir -p $(DESTDIR)/usr/share/dbus-1/system.d/ ++ mkdir -p $(DESTDIR)/usr/share/polkit-1/actions/ + cp systemd/fi.foobar.Foomuuri1.conf $(DESTDIR)/usr/share/dbus-1/system.d/ ++ cp systemd/fi.foobar.Foomuuri1.policy $(DESTDIR)/usr/share/polkit-1/actions/ + cp firewalld/fi.foobar.Foomuuri-FirewallD.conf $(DESTDIR)/usr/share/dbus-1/system.d/ + cp firewalld/dbus-firewalld.conf $(DESTDIR)/usr/share/foomuuri/ + mkdir -p $(DESTDIR)/usr/share/man/man8 +diff --git a/firewalld/fi.foobar.Foomuuri-FirewallD.conf b/firewalld/fi.foobar.Foomuuri-FirewallD.conf +index 97aeb5e..66051e1 100644 +--- a/firewalld/fi.foobar.Foomuuri-FirewallD.conf ++++ b/firewalld/fi.foobar.Foomuuri-FirewallD.conf +@@ -1,10 +1,13 @@ +- ++ + + + + ++ ++ + + + +@@ -13,10 +16,6 @@ + + + +- +- + + +diff --git a/src/foomuuri b/src/foomuuri +index ddc159c..18467d6 100755 +--- a/src/foomuuri ++++ b/src/foomuuri +@@ -2471,6 +2471,7 @@ class DbusCommon: + """D-Bus server - Common Functions.""" + + zones = None ++ polkit = None + + def set_data(self, zones): + """Save config data: zone list is static.""" +@@ -2503,6 +2504,40 @@ class DbusCommon: + return False # Linux accepts these + return 1 <= len(interface) <= 15 # IFNAMSIZ = 16 including NUL, so 15 + ++ def verify_polkit_privilege(self, sender, privilege): ++ """Verify authorization from PolicyKit.""" ++ # Initialize polkit connections ++ if not self.polkit: ++ try: ++ self.polkit = dbus.Interface( ++ dbus.SystemBus().get_object( ++ 'org.freedesktop.PolicyKit1', ++ '/org/freedesktop/PolicyKit1/Authority'), ++ 'org.freedesktop.PolicyKit1.Authority') ++ except dbus.DBusException: ++ # No polkit, fallback to check that UID == 0 ++ iface = dbus.Interface( ++ dbus.SystemBus().get_object('org.freedesktop.DBus', ++ '/org/freedesktop/DBus'), ++ 'org.freedesktop.DBus') ++ try: ++ if int(iface.GetConnectionUnixUser(sender)) == 0: ++ return ++ except ValueError: ++ pass ++ raise FoomuuriDbusException('Authorization failed') from None ++ ++ # Verify authorization from polkit ++ try: ++ if self.polkit.CheckAuthorization( ++ ('system-bus-name', {'name': sender}), ++ privilege, {}, 1, '', timeout=60)[0]: ++ return ++ except dbus.DBusException as error: ++ warning(error) ++ self.polkit = None # Reconnect on next call ++ raise FoomuuriDbusException('Authorization failed') from None ++ + @staticmethod + def remove_interface(interface_zone, interface): + """Remove interface from all zones.""" +@@ -2628,36 +2663,44 @@ class DbusFoomuuri(dbus.service.Object, DbusCommon): + # pylint: disable=invalid-name # dbus method names + + @dbus.service.method('fi.foobar.Foomuuri1.zone', +- in_signature='', out_signature='as') +- def getZones(self): ++ in_signature='', out_signature='as', ++ sender_keyword='sender') ++ def getZones(self, sender=None): + """Get list of available zones.""" ++ self.verify_polkit_privilege(sender, 'fi.foobar.Foomuuri1.info') + return self.method_get_zones() + + @dbus.service.method('fi.foobar.Foomuuri1.zone', +- in_signature='ss', out_signature='s') +- def removeInterface(self, zone, interface): ++ in_signature='ss', out_signature='s', ++ sender_keyword='sender') ++ def removeInterface(self, zone, interface, sender=None): + """Remove interface from zone, or from all if zone is empty. + + Return: previous zone + """ ++ self.verify_polkit_privilege(sender, 'fi.foobar.Foomuuri1.config') + return self.method_remove_interface(zone, interface) + + @dbus.service.method('fi.foobar.Foomuuri1.zone', +- in_signature='ss', out_signature='s') +- def addInterface(self, zone, interface): ++ in_signature='ss', out_signature='s', ++ sender_keyword='sender') ++ def addInterface(self, zone, interface, sender=None): + """Add interface to zone. + + Return: new zone + """ ++ self.verify_polkit_privilege(sender, 'fi.foobar.Foomuuri1.config') + return self.method_add_interface(zone, interface) + + @dbus.service.method('fi.foobar.Foomuuri1.zone', +- in_signature='ss', out_signature='s') +- def changeZoneOfInterface(self, zone, interface): ++ in_signature='ss', out_signature='s', ++ sender_keyword='sender') ++ def changeZoneOfInterface(self, zone, interface, sender=None): + """Change interface to zone. + + Return: previous zone + """ ++ self.verify_polkit_privilege(sender, 'fi.foobar.Foomuuri1.config') + return self.method_change_zone_of_interface(zone, interface) + + +@@ -2667,36 +2710,44 @@ class DbusFirewallD(dbus.service.Object, DbusCommon): + # pylint: disable=invalid-name # dbus method names + + @dbus.service.method('org.fedoraproject.FirewallD1.zone', +- in_signature='', out_signature='as') +- def getZones(self): ++ in_signature='', out_signature='as', ++ sender_keyword='sender') ++ def getZones(self, sender=None): + """Get list of available zones.""" ++ self.verify_polkit_privilege(sender, 'fi.foobar.Foomuuri1.info') + return self.method_get_zones() + + @dbus.service.method('org.fedoraproject.FirewallD1.zone', +- in_signature='ss', out_signature='s') +- def removeInterface(self, zone, interface): ++ in_signature='ss', out_signature='s', ++ sender_keyword='sender') ++ def removeInterface(self, zone, interface, sender=None): + """Remove interface from zone, or from all if zone is empty. + + Return: previous zone + """ ++ self.verify_polkit_privilege(sender, 'fi.foobar.Foomuuri1.config') + return self.method_remove_interface(zone, interface) + + @dbus.service.method('org.fedoraproject.FirewallD1.zone', +- in_signature='ss', out_signature='s') +- def addInterface(self, zone, interface): ++ in_signature='ss', out_signature='s', ++ sender_keyword='sender') ++ def addInterface(self, zone, interface, sender=None): + """Add interface to zone. + + Return: new zone + """ ++ self.verify_polkit_privilege(sender, 'fi.foobar.Foomuuri1.config') + return self.method_add_interface(zone, interface) + + @dbus.service.method('org.fedoraproject.FirewallD1.zone', +- in_signature='ss', out_signature='s') +- def changeZoneOfInterface(self, zone, interface): ++ in_signature='ss', out_signature='s', ++ sender_keyword='sender') ++ def changeZoneOfInterface(self, zone, interface, sender=None): + """Change interface to zone. + + Return: previous zone + """ ++ self.verify_polkit_privilege(sender, 'fi.foobar.Foomuuri1.config') + return self.method_change_zone_of_interface(zone, interface) + + +diff --git a/systemd/fi.foobar.Foomuuri1.conf b/systemd/fi.foobar.Foomuuri1.conf +index be98c2f..ecb8abe 100644 +--- a/systemd/fi.foobar.Foomuuri1.conf ++++ b/systemd/fi.foobar.Foomuuri1.conf +@@ -1,11 +1,21 @@ +- +- ++ + + ++ + + + + ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/systemd/fi.foobar.Foomuuri1.policy b/systemd/fi.foobar.Foomuuri1.policy +new file mode 100644 +index 0000000..43d2bf2 +--- /dev/null ++++ b/systemd/fi.foobar.Foomuuri1.policy +@@ -0,0 +1,29 @@ ++ ++ ++ ++ Foomuuri ++ https://github.com/FoobarOy/foomuuri ++ ++ ++ Foomuuri information ++ System policy prevents getting Foomuuri information ++ ++ yes ++ yes ++ yes ++ ++ ++ ++ ++ Foomuuri configuration ++ System policy prevents changing Foomuuri configuration ++ ++ auth_admin_keep ++ auth_admin_keep ++ auth_admin_keep ++ ++ ++ ++ diff -Nru foomuuri-0.27/debian/patches/series foomuuri-0.27/debian/patches/series --- foomuuri-0.27/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 +++ foomuuri-0.27/debian/patches/series 2025-12-31 11:38:29.000000000 +0000 @@ -0,0 +1,2 @@ +01.CVE-2025-67858.patch +02.CVE-2025-67603.patch