diff -pruN 2:4.0.4-8/debian/changelog 2:4.0.4-8ubuntu3/debian/changelog
--- 2:4.0.4-8/debian/changelog	2025-04-14 08:06:27.000000000 +0000
+++ 2:4.0.4-8ubuntu3/debian/changelog	2025-08-29 10:58:29.000000000 +0000
@@ -1,3 +1,66 @@
+procps (2:4.0.4-8ubuntu3) questing; urgency=medium
+
+  * debian/patches/lp2120904-openat.patch: utilize file descriptors
+    and openat. (LP: #2120904)
+  * debian/patches/lp2120904-nullpointer.patch: Fix a race
+    when 'status' is unavailable in /proc/<pid> resulting in
+    a NULL pointer. (LP: #2120904)
+
+ -- John Chittum <john.chittum@canonical.com>  Fri, 29 Aug 2025 06:58:29 -0400
+
+procps (2:4.0.4-8ubuntu2) questing; urgency=medium
+
+  * Fixes for new sysctl-defaults test:
+    - d/t/test_sysctl_defaults.py: skip test if sysctl key invalid
+    - d/t/control: show all sysctl.d configs before test
+    - d/t/control: make sysctl-defaults test Restrictions: isolation-machine
+      (LP: #2115346)
+
+ -- Nick Rosbrook <enr0n@ubuntu.com>  Wed, 25 Jun 2025 10:25:56 -0400
+
+procps (2:4.0.4-8ubuntu1) questing; urgency=medium
+
+  * Merge from Debian unstable (LP: #2112060). Remaining changes:
+    - d/p/0010-testsuite-ps-etime-ELAPSED-doesn-t-match-full-format.patch:
+      Fix test failure (FTBFS) in testsuite/ps.test/ps_output.exp due to
+      invalid regex match inside LXD containers.
+    - debian/sysctl.d (Ubuntu-specific):
+      + 10-console-messages.conf: stop low-level kernel messages on console.
+      + 10-kernel-hardening.conf: add the kptr_restrict setting
+      + 10-ipv6-privacy.conf: add a file to sysctl.d to apply the defaults
+        for IPv6 privacy extensions for interfaces. (LP#176125, LP#841353)
+      + 10-magic-sysrq.conf: Disable most magic sysrq by default, allowing
+      critical sync, remount, reboot functions. (LP#194676, LP#1025467)
+      + 10-network-security.conf: enable rp_filter.
+      + 10-ptrace.conf: describe new PTRACE setting.
+      + 10-zeropage.conf: safe mmap_min_addr value for graceful fall-back.
+        for armhf, and arm64.
+      + 10-qemu.conf.s390x for qemu.
+      + 10-bufferbloat.conf: set default qdisc to fq_codel
+      + 10-map-count.conf: Increase vm.max_map_count to 1048576
+    - ignore_erofs.patch: Same as ignore_eaccess but for the case
+      where part of /proc is read/only.
+      - Adjust logic due to rc no longer being propagated (LP#1903351)
+    - ignore_eaccess.patch: If we get eaccess when opening a sysctl
+      file for writing, don't error out. Otherwise package upgrades
+      can fail, especially in containers.
+      - Adjust logic due to rc no longer being propagated (LP#1903351)
+    - Add basic autopkgtest to validate sysctl-defaults (LP#1962038)
+    - d/t/stack-limit: add basic autopkgtest to validate limits
+  * Dropped, included in Debian:
+    - d/p/ps-Don-t-crash-when-using-short-option.patch:
+      Fix ps crash issue when using short option
+  * New changes:
+    - debian/sysctl.d: ship configs in /usr, with higher priority
+      This ensures that Ubuntu's defaults take precedence over
+      50-default.conf from linux-sysctl-defaults. (LP: #2108979)
+    - d/t/stack-limit: call 'pgrep systemd' instead of 'pgrep bash'
+      The autopkgtest currently fails because there is no bash session, and
+      pgrep returns non-zero. Use systemd because that will match for pid1.
+    - d/tests: make sysctl-defaults test comprehensive
+
+ -- Nick Rosbrook <enr0n@ubuntu.com>  Tue, 10 Jun 2025 13:26:18 -0400
+
 procps (2:4.0.4-8) unstable; urgency=medium
 
   * Port 4.0.5 patches:
@@ -19,6 +82,38 @@ procps (2:4.0.4-8) unstable; urgency=med
 
  -- Craig Small <csmall@debian.org>  Mon, 14 Apr 2025 18:06:27 +1000
 
+procps (2:4.0.4-7ubuntu1) plucky; urgency=medium
+
+  * Merge with Debian unstable (LP: #2098925). Remaining changes:
+    - d/t/stack-limit: add basic autopkgtest to validate limits
+    - Add basic autopkgtest to validate sysctl-defaults (LP: 1962038)
+    - ignore_eaccess.patch: If we get eaccess when opening a sysctl file for
+      writing, don't error out.  Otherwise package upgrades can fail,
+      especially in containers.
+      - Adjust logic due to rc no longer being propagated (LP: 1903351)
+    - ignore_erofs.patch: Same as ignore_eaccess but for the case where
+      part of /proc is read/only.
+      - Adjust logic due to rc no longer being propagated (LP: 1903351)
+    - debian/sysctl.d (Ubuntu-specific):
+       + 10-console-messages.conf: stop low-level kernel messages on console.
+       + 10-kernel-hardening.conf: add the kptr_restrict setting
+       + 10-ipv6-privacy.conf: add a file to sysctl.d to apply the defaults
+         for IPv6 privacy extensions for interfaces. (LP: 176125, LP: 841353)
+       + 10-magic-sysrq.conf: Disable most magic sysrq by default, allowing
+         critical sync, remount, reboot functions. (LP: 194676, LP: 1025467)
+       + 10-network-security.conf: enable rp_filter.
+       + 10-ptrace.conf: describe new PTRACE setting.
+       + 10-zeropage.conf: safe mmap_min_addr value for graceful fall-back.
+         for armhf, and arm64.
+       + 10-qemu.conf.s390x for qemu.
+    - d/p/0010-testsuite-ps-etime-ELAPSED-doesn-t-match-full-format.patch:
+      Fix test failure (FTBFS) in testsuite/ps.test/ps_output.exp due to
+      invalid regex match inside LXD containers.
+    - d/p/ps-Don-t-crash-when-using-short-option.patch:
+      Fix ps crash issue when using short option
+
+ -- Anshul Singh <anshul.singh@canonical.com>  Wed, 05 Mar 2025 12:08:11 +0530
+
 procps (2:4.0.4-7) unstable; urgency=medium
 
   [ Ben Hutchings ]
@@ -53,6 +148,60 @@ procps (2:4.0.4-5) unstable; urgency=med
 
  -- Craig Small <csmall@debian.org>  Thu, 11 Jul 2024 18:41:23 +1000
 
+procps (2:4.0.4-4ubuntu5) oracular; urgency=medium
+
+  * ps: Don't crash when using short option (LP: #2080518)
+
+ -- Benjamin Drung <bdrung@ubuntu.com>  Thu, 12 Sep 2024 14:34:29 +0200
+
+procps (2:4.0.4-4ubuntu4) oracular; urgency=medium
+
+  * d/sysctl.d/10-bufferbloat.conf: set default qdisc to fq_codel (LP: #2003027)
+
+ -- Heitor Alves de Siqueira <halves@canonical.com>  Wed, 17 Jul 2024 14:59:18 +0000
+
+procps (2:4.0.4-4ubuntu3) noble; urgency=medium
+
+  * No-change rebuild for CVE-2024-3094
+
+ -- Steve Langasek <steve.langasek@ubuntu.com>  Sun, 31 Mar 2024 08:16:00 +0000
+
+procps (2:4.0.4-4ubuntu2) noble; urgency=medium
+
+  * d/sysctl.d/10-map-count.conf: Set vm.max_map_count=1048576 (LP: #2057792)
+
+ -- Julian Andres Klode <juliank@ubuntu.com>  Sun, 24 Mar 2024 16:39:47 +0100
+
+procps (2:4.0.4-4ubuntu1) noble; urgency=medium
+
+  * Merge with Debian unstable. Remaining changes:
+    - d/t/stack-limit: add basic autopkgtest to validate limits
+    - Add basic autopkgtest to validate sysctl-defaults (LP#1962038)
+    - ignore_eaccess.patch: If we get eaccess when opening a sysctl file for
+      writing, don't error out.  Otherwise package upgrades can fail,
+      especially in containers.
+      - Adjust logic due to rc no longer being propagated (LP#1903351)
+    - ignore_erofs.patch: Same as ignore_eaccess but for the case where
+      part of /proc is read/only.
+      - Adjust logic due to rc no longer being propagated (LP#1903351)
+    - debian/sysctl.d (Ubuntu-specific):
+       + 10-console-messages.conf: stop low-level kernel messages on console.
+       + 10-kernel-hardening.conf: add the kptr_restrict setting
+       + 10-ipv6-privacy.conf: add a file to sysctl.d to apply the defaults
+         for IPv6 privacy extensions for interfaces. (LP#176125, LP#841353)
+       + 10-magic-sysrq.conf: Disable most magic sysrq by default, allowing
+         critical sync, remount, reboot functions. (LP#194676, LP#1025467)
+       + 10-network-security.conf: enable rp_filter.
+       + 10-ptrace.conf: describe new PTRACE setting.
+       + 10-zeropage.conf: safe mmap_min_addr value for graceful fall-back.
+         for armhf, and arm64.
+       + 10-qemu.conf.s390x for qemu.
+    - d/p/0010-testsuite-ps-etime-ELAPSED-doesn-t-match-full-format.patch:
+      Fix test failure (FTBFS) in testsuite/ps.test/ps_output.exp due to
+      invalid regex match inside LXD containers.
+
+ -- Lukas Märdian <slyon@ubuntu.com>  Tue, 27 Feb 2024 12:07:21 +0100
+
 procps (2:4.0.4-4) unstable; urgency=medium
 
   * Moved into unstable
@@ -66,6 +215,36 @@ procps (2:4.0.4-3) experimental; urgency
 
  -- Craig Small <csmall@debian.org>  Tue, 02 Jan 2024 19:33:53 +1100
 
+procps (2:4.0.4-2ubuntu1) noble; urgency=medium
+
+  * Merge with Debian unstable. Remaining changes:
+    - d/t/stack-limit: add basic autopkgtest to validate limits
+    - Add basic autopkgtest to validate sysctl-defaults (LP#1962038)
+    - ignore_eaccess.patch: If we get eaccess when opening a sysctl file for
+      writing, don't error out.  Otherwise package upgrades can fail,
+      especially in containers.
+      - Adjust logic due to rc no longer being propagated (LP#1903351)
+    - ignore_erofs.patch: Same as ignore_eaccess but for the case where
+      part of /proc is read/only.
+      - Adjust logic due to rc no longer being propagated (LP#1903351)
+    - debian/sysctl.d (Ubuntu-specific):
+       + 10-console-messages.conf: stop low-level kernel messages on console.
+       + 10-kernel-hardening.conf: add the kptr_restrict setting
+       + 10-ipv6-privacy.conf: add a file to sysctl.d to apply the defaults
+         for IPv6 privacy extensions for interfaces. (LP#176125, LP#841353)
+       + 10-magic-sysrq.conf: Disable most magic sysrq by default, allowing
+         critical sync, remount, reboot functions. (LP#194676, LP#1025467)
+       + 10-network-security.conf: enable rp_filter.
+       + 10-ptrace.conf: describe new PTRACE setting.
+       + 10-zeropage.conf: safe mmap_min_addr value for graceful fall-back.
+         for armhf, and arm64.
+       + 10-qemu.conf.s390x for qemu.
+  * d/p/0010-testsuite-ps-etime-ELAPSED-doesn-t-match-full-format.patch:
+    Fix test failure (FTBFS) in testsuite/ps.test/ps_output.exp due to invalid
+    regex match inside LXD containers.
+
+ -- Lukas Märdian <slyon@ubuntu.com>  Tue, 21 Nov 2023 11:54:36 +0100
+
 procps (2:4.0.4-2) unstable; urgency=medium
 
   * Loosen regex and check file perms in pmap test Closes: #1052034
@@ -89,6 +268,40 @@ procps (2:4.0.4-1) unstable; urgency=med
 
  -- Craig Small <csmall@debian.org>  Thu, 07 Sep 2023 21:31:09 +1000
 
+procps (2:4.0.3-1ubuntu1) lunar; urgency=medium
+
+  * Merge from Debian unstable.  Remaining changes:
+    -  debian/sysctl.d (Ubuntu-specific):
+       + 10-console-messages.conf: stop low-level kernel messages on console.
+       + 10-kernel-hardening.conf: add the kptr_restrict setting
+       + 10-ipv6-privacy.conf: add a file to sysctl.d to apply the defaults
+         for IPv6 privacy extensions for interfaces. (LP: #176125, #841353)
+       + 10-magic-sysrq.conf: Disable most magic sysrq by default, allowing
+         critical sync, remount, reboot functions. (LP: #194676, LP: #1025467)
+       + 10-network-security.conf: enable rp_filter.
+       + 10-ptrace.conf: describe new PTRACE setting.
+       + 10-zeropage.conf: safe mmap_min_addr value for graceful fall-back.
+         for armhf, and arm64.
+       + 10-qemu.conf.s390x for qemu.
+    - ignore_eaccess.patch: If we get eaccess when opening a sysctl file for
+      writing, don't error out.  Otherwise package upgrades can fail,
+      especially in containers.
+      - Adjust logic due to rc no longer being propagated (LP: #1903351)
+    - ignore_erofs.patch: Same as ignore_eaccess but for the case where
+      part of /proc is read/only.
+      - Adjust logic due to rc no longer being propagated (LP: #1903351)
+    - d/t/stack-limit: add basic autopkgtest to validate limits
+    - Add basic autopkgtest to validate sysctl-defaults (LP: #1962038)
+  * Refresh patches
+  * Dropped changes (applied upstream or in Debian):
+    - debian/procps.maintscript: handle migration of link-protect.conf from
+      /etc to /usr.
+      - Added in Focal, should be clean as of Jammy.
+    - debian/rules: Fix cross build (Closes: #1031343)
+    - negative_committed_mem.patch: fix new 'free commited' test
+
+ -- Lukas Märdian <slyon@ubuntu.com>  Mon, 20 Feb 2023 09:32:53 +0100
+
 procps (2:4.0.3-1) unstable; urgency=medium
 
   * New upstream release
@@ -103,6 +316,40 @@ procps (2:4.0.3-1) unstable; urgency=med
 
  -- Craig Small <csmall@debian.org>  Sat, 18 Feb 2023 10:17:15 +1100
 
+procps (2:4.0.2-3ubuntu1) lunar; urgency=medium
+
+  * Merge from Debian unstable.  Remaining changes:
+    -  debian/sysctl.d (Ubuntu-specific):
+       + 10-console-messages.conf: stop low-level kernel messages on console.
+       + 10-kernel-hardening.conf: add the kptr_restrict setting
+       + 10-ipv6-privacy.conf: add a file to sysctl.d to apply the defaults
+         for IPv6 privacy extensions for interfaces. (LP: #176125, #841353)
+       + 10-magic-sysrq.conf: Disable most magic sysrq by default, allowing
+         critical sync, remount, reboot functions. (LP: #194676, LP: #1025467)
+       + 10-network-security.conf: enable rp_filter.
+       + 10-ptrace.conf: describe new PTRACE setting.
+       + 10-zeropage.conf: safe mmap_min_addr value for graceful fall-back.
+         for armhf, and arm64.
+       + 10-qemu.conf.s390x for qemu.
+    - debian/rules: Fix cross build
+    - ignore_eaccess.patch: If we get eaccess when opening a sysctl file for
+      writing, don't error out.  Otherwise package upgrades can fail,
+      especially in containers.
+      - Adjust logic due to rc no longer being propagated (LP: #1903351)
+    - ignore_erofs.patch: Same as ignore_eaccess but for the case where
+      part of /proc is read/only.
+      - Adjust logic due to rc no longer being propagated (LP: #1903351)
+    - negative_committed_mem.patch: fix new 'free commited' test
+    - d/t/stack-limit: add basic autopkgtest to validate limits
+    - Add basic autopkgtest to validate sysctl-defaults (LP: #1962038)
+  * Refresh patches
+  * Dropped changes:
+    - debian/procps.maintscript: handle migration of link-protect.conf from
+      /etc to /usr.
+      - Added in Focal, should be clean as of Jammy.
+
+ -- Lukas Märdian <slyon@ubuntu.com>  Wed, 15 Feb 2023 12:39:13 +0100
+
 procps (2:4.0.2-3) unstable; urgency=medium
 
   [ Pino Toscano ]
@@ -179,6 +426,35 @@ procps (2:3.3.17-7.1) unstable; urgency=
 
  -- Johannes Schauer Marin Rodrigues <josch@debian.org>  Thu, 20 Oct 2022 10:38:33 +0200
 
+procps (2:3.3.17-7ubuntu1) kinetic; urgency=medium
+
+  * Merge from Debian unstable.  Remaining changes:
+    - debian/sysctl.d (Ubuntu-specific):
+      + 10-console-messages.conf: stop low-level kernel messages on console.
+      + 10-kernel-hardening.conf: add the kptr_restrict setting
+      + 10-ipv6-privacy.conf: add a file to sysctl.d to apply the defaults
+        for IPv6 privacy extensions for interfaces. (LP: #176125, #841353)
+      + 10-magic-sysrq.conf: Disable most magic sysrq by default, allowing
+        critical sync, remount, reboot functions. (LP: #194676, LP: #1025467)
+      + 10-network-security.conf: enable rp_filter.
+      + 10-ptrace.conf: describe new PTRACE setting.
+      + 10-zeropage.conf: safe mmap_min_addr value for graceful fall-back.
+        for armhf, and arm64.
+      + 10-qemu.conf.s390x for qemu.
+    - debian/rules: Fix cross build
+    - ignore_eaccess.patch: If we get eaccess when opening a sysctl file for
+      writing, don't error out.  Otherwise package upgrades can fail,
+      especially in containers.
+      - Adjust logic due to rc no longer being propagated (LP: #1903351)
+    - ignore_erofs.patch: Same as ignore_eaccess but for the case where
+      part of /proc is read/only.
+      - Adjust logic due to rc no longer being propagated (LP: #1903351)
+    - debian/procps.maintscript: handle migration of link-protect.conf from
+      /etc to /usr.
+    - Add basic autopkgtest to validate sysctl-defaults (LP: #1962038)
+
+ -- Lukas Märdian <slyon@ubuntu.com>  Mon, 22 Aug 2022 10:50:36 +0200
+
 procps (2:3.3.17-7) unstable; urgency=medium
 
   * Update to Debian standards 4.6.0
@@ -190,6 +466,46 @@ procps (2:3.3.17-7) unstable; urgency=me
 
  -- Craig Small <csmall@debian.org>  Mon, 07 Mar 2022 22:05:15 +1100
 
+procps (2:3.3.17-6ubuntu2) jammy; urgency=medium
+
+  * Add basic autopkgtest to validate sysctl-defaults (LP: #1962038)
+
+ -- Lukas Märdian <slyon@ubuntu.com>  Fri, 25 Feb 2022 12:57:56 +0100
+
+procps (2:3.3.17-6ubuntu1) jammy; urgency=low
+
+  * Merge from Debian unstable (LP: #1961805).
+    Remaining changes:
+      - debian/sysctl.d (Ubuntu-specific):
+        + 10-console-messages.conf: stop low-level kernel messages on console.
+        + 10-kernel-hardening.conf: add the kptr_restrict setting
+        + 10-ipv6-privacy.conf: add a file to sysctl.d to apply the defaults
+          for IPv6 privacy extensions for interfaces. (LP: #176125, #841353)
+        + 10-magic-sysrq.conf: Disable most magic sysrq by default, allowing
+          critical sync, remount, reboot functions. (LP: #194676, LP: #1025467)
+        + 10-network-security.conf: enable rp_filter.
+        + 10-ptrace.conf: describe new PTRACE setting.
+        + 10-zeropage.conf: safe mmap_min_addr value for graceful fall-back.
+          for armhf, and arm64.
+        + 10-qemu.conf.s390x for qemu.
+      - debian/rules: Fix cross build
+      - ignore_eaccess.patch: If we get eaccess when opening a sysctl file for
+        writing, don't error out.  Otherwise package upgrades can fail,
+        especially in containers.
+        - Adjust logic due to rc no longer being propagated (LP: #1903351)
+      - ignore_erofs.patch: Same as ignore_eaccess but for the case where
+        part of /proc is read/only.
+        - Adjust logic due to rc no longer being propagated (LP: #1903351)
+      - debian/procps.maintscript: handle migration of link-protect.conf from
+        /etc to /usr.
+    Dropped changes:
+      - debian/README.sysctl: Debian has added this information.
+      - debian/procps.install: debian/protect-links.conf has been re-named to
+        debian/99-protect-links.conf, so it can be safely installed again
+        (see LP: #1938585 for background).
+
+ -- Nick Rosbrook <nick.rosbrook@canonical.com>  Fri, 18 Feb 2022 16:49:15 -0500
+
 procps (2:3.3.17-6) unstable; urgency=medium
 
   * Add reload option for init script Closes: #991151
@@ -199,6 +515,61 @@ procps (2:3.3.17-6) unstable; urgency=me
 
  -- Craig Small <csmall@debian.org>  Thu, 13 Jan 2022 19:46:59 +1100
 
+procps (2:3.3.17-5ubuntu3) impish; urgency=medium
+
+  * Remove /usr/lib/sysctl.d/protect-links.conf (LP: #1938585)
+
+ -- Dan Streetman <ddstreet@canonical.com>  Fri, 30 Jul 2021 12:17:48 -0400
+
+procps (2:3.3.17-5ubuntu2) impish; urgency=medium
+
+  * Clean up switch statement for ignore_erofs case (LP: #1903351)
+
+ -- William 'jawn-smith' Wilson <william.wilson@canonical.com>  Tue, 01 Jun 2021 14:10:29 -0500
+
+procps (2:3.3.17-5ubuntu1) impish; urgency=low
+
+  * Merge from Debian unstable.
+    Remaining changes:
+      - autopkgtest for LP: #1874824. Submitted to debian as bug 988792
+      - debian/sysctl.d (Ubuntu-specific):
+        + 10-console-messages.conf: stop low-level kernel messages on console.
+        + 10-kernel-hardening.conf: add the kptr_restrict setting
+        + 10-ipv6-privacy.conf: add a file to sysctl.d to apply the defaults
+          for IPv6 privacy extensions for interfaces. (LP: #176125, #841353)
+        + 10-magic-sysrq.conf: Disable most magic sysrq by default, allowing
+          critical sync, remount, reboot functions. (LP: #194676, LP: #1025467)
+        + 10-network-security.conf: enable rp_filter.
+        + 10-ptrace.conf: describe new PTRACE setting.
+        + 10-zeropage.conf: safe mmap_min_addr value for graceful fall-back.
+          for armhf, and arm64.
+        + 10-qemu.conf.s390x for qemu.
+        + README: describe how this directory is supposed to work.
+      - debian/rules: Fix cross build
+      - ignore_eaccess.patch: If we get eaccess when opening a sysctl file for
+        writing, don't error out.  Otherwise package upgrades can fail,
+        especially in containers.
+        - Adjust logic due to rc no longer being propagated (LP: #1903351)
+      - ignore_erofs.patch: Same as ignore_eaccess but for the case where
+        part of /proc is read/only.
+        - Adjust logic due to rc no longer being propagated (LP: #1903351)
+      - debian/procps.maintscript: handle migration of link-protect.conf from
+        /etc to /usr.
+    Justification of dropped patches
+      - missing_potfiles_in: Debian has now added this code in POTFILES.in
+        so the patch is no longer needed
+      - pmap_test: This patch disables some tests that are not causing
+        any problems. These tests are run in Debian so should be run
+        in Ubuntu as well
+      - top_config_file_bwcompat: Debian has applied this code upstream so
+        the patch is no longer needed
+      - tar-version: Debian has applied this code upstream so the patch is
+        no longer needed
+      - stack_limit: Debian has applied this code upstream so the patch is
+        no longer needed
+
+ -- William 'jawn-smith' Wilson <william.wilson@canonical.com>  Wed, 19 May 2021 09:24:31 +0000
+
 procps (2:3.3.17-5) unstable; urgency=medium
 
   * Add break/replace for conflicting manpages-fr-extra Closes: #986276
@@ -239,6 +610,48 @@ procps (2:3.3.17-1) unstable; urgency=me
 
  -- Craig Small <csmall@debian.org>  Tue, 09 Feb 2021 21:50:10 +1100
 
+procps (2:3.3.16-5ubuntu3) hirsute; urgency=medium
+
+  * Address slowness and crashes with large or unlimited stack limits
+    (LP: #1874824)
+
+ -- William 'jawn-smith' Wilson <william.wilson@canonical.com>  Wed, 24 Mar 2021 10:09:08 -0500
+
+procps (2:3.3.16-5ubuntu2) groovy; urgency=medium
+
+  * debian/sysctl.d/10-kernel-hardening.conf:
+    - Add documentation for DMESG_RESTRICT feature, and allow users to
+      disable by uncommenting kernel.dmesg_restrict=0. (LP: #1886112)
+
+ -- Matthew Ruffell <matthew.ruffell@canonical.com>  Thu, 23 Jul 2020 16:59:38 +1200
+
+procps (2:3.3.16-5ubuntu1) groovy; urgency=low
+
+  * Merge from Debian unstable.  Remaining changes:
+    - debian/sysctl.d (Ubuntu-specific):
+      + 10-console-messages.conf: stop low-level kernel messages on console.
+      + 10-kernel-hardening.conf: add the kptr_restrict setting
+      + 10-ipv6-privacy.conf: add a file to sysctl.d to apply the defaults
+        for IPv6 privacy extensions for interfaces. (LP: #176125, #841353)
+      + 10-magic-sysrq.conf: Disable most magic sysrq by default, allowing
+        critical sync, remount, reboot functions. (LP: #194676, LP: #1025467)
+      + 10-network-security.conf: enable rp_filter.
+      + 10-ptrace.conf: describe new PTRACE setting.
+      + 10-zeropage.conf: safe mmap_min_addr value for graceful fall-back.
+        for armhf, and arm64.
+      + 10-qemu.conf.s390x for qemu.
+      + README: describe how this directory is supposed to work.
+    - debian/rules: Fix cross build
+    - ignore_eaccess.patch: If we get eaccess when opening a sysctl file for
+      writing, don't error out.  Otherwise package upgrades can fail,
+      especially in containers.
+    - ignore_erofs.patch: Same as ignore_eaccess but for the case where
+      part of /proc is read/only.
+    - debian/procps.maintscript: handle migration of link-protect.conf from
+      /etc to /usr.
+
+ -- Steve Langasek <steve.langasek@ubuntu.com>  Tue, 09 Jun 2020 13:18:24 -0700
+
 procps (2:3.3.16-5) unstable; urgency=medium
 
   * programs report version correctly Closes: #960810
@@ -246,6 +659,35 @@ procps (2:3.3.16-5) unstable; urgency=me
 
  -- Craig Small <csmall@debian.org>  Sun, 17 May 2020 09:45:41 +1000
 
+procps (2:3.3.16-4ubuntu1) groovy; urgency=low
+
+  * Merge from Debian unstable.  Remaining changes:
+    - debian/sysctl.d (Ubuntu-specific):
+      + 10-console-messages.conf: stop low-level kernel messages on console.
+      + 10-kernel-hardening.conf: add the kptr_restrict setting
+      + 10-ipv6-privacy.conf: add a file to sysctl.d to apply the defaults
+        for IPv6 privacy extensions for interfaces. (LP: #176125, #841353)
+      + 10-magic-sysrq.conf: Disable most magic sysrq by default, allowing
+        critical sync, remount, reboot functions. (LP: #194676, LP: #1025467)
+      + 10-network-security.conf: enable rp_filter.
+      + 10-ptrace.conf: describe new PTRACE setting.
+      + 10-zeropage.conf: safe mmap_min_addr value for graceful fall-back.
+        for armhf, and arm64.
+      + 10-qemu.conf.s390x for qemu.
+      + README: describe how this directory is supposed to work.
+    - debian/rules: Fix cross build
+    - ignore_eaccess.patch: If we get eaccess when opening a sysctl file for
+      writing, don't error out.  Otherwise package upgrades can fail,
+      especially in containers.
+    - ignore_erofs.patch: Same as ignore_eaccess but for the case where
+      part of /proc is read/only.
+    - debian/procps.maintscript: handle migration of link-protect.conf from
+      /etc to /usr.
+  * 10-link-restrictions.conf: was not correctly dropped in focal, drop it
+    fully now.
+
+ -- Steve Langasek <steve.langasek@ubuntu.com>  Fri, 01 May 2020 05:54:27 -0700
+
 procps (2:3.3.16-4) unstable; urgency=medium
 
   * Use correct package version on removing conffile Closes: #951293
@@ -269,6 +711,49 @@ procps (2:3.3.16-2) unstable; urgency=me
 
  -- Craig Small <csmall@debian.org>  Tue, 25 Feb 2020 08:08:40 +1100
 
+procps (2:3.3.16-1ubuntu2) focal; urgency=medium
+
+  * Fix libprocps.so link target to point to the library we actually ship.
+
+ -- Steve Langasek <steve.langasek@ubuntu.com>  Wed, 26 Feb 2020 21:52:07 -0800
+
+procps (2:3.3.16-1ubuntu1) focal; urgency=low
+
+  * Merge from Debian unstable.  Remaining changes:
+    - debian/sysctl.d (Ubuntu-specific):
+      + 10-console-messages.conf: stop low-level kernel messages on console.
+      + 10-kernel-hardening.conf: add the kptr_restrict setting
+      + 10-ipv6-privacy.conf: add a file to sysctl.d to apply the defaults
+        for IPv6 privacy extensions for interfaces. (LP: #176125, #841353)
+      + 10-magic-sysrq.conf: Disable most magic sysrq by default, allowing
+        critical sync, remount, reboot functions. (LP: #194676, LP: #1025467)
+      + 10-network-security.conf: enable rp_filter.
+      + 10-ptrace.conf: describe new PTRACE setting.
+      + 10-zeropage.conf: safe mmap_min_addr value for graceful fall-back.
+        for armhf, and arm64.
+      + 10-qemu.conf.s390x for qemu.
+      + README: describe how this directory is supposed to work.
+    - debian/rules: Fix cross build
+    - ignore_eaccess.patch: If we get eaccess when opening a sysctl file for
+      writing, don't error out.  Otherwise package upgrades can fail,
+      especially in containers.
+    - ignore_erofs.patch: Same as ignore_eaccess but for the case where
+      part of /proc is read/only.
+    - 10-network-security.conf: change the rp_filter default from 1 to 2,
+      the strict mode isn't compatible with the n-m handling of
+      captive portals
+  * Dropped changes, superseded upstream:
+    - d/p/pgrep-increase-CMDSTRSIZE.patch: Allow long command lines to be
+      searched.
+  * Dropped changes, no longer needed:
+    - 10-keyboard.conf.powerpc: mouse button emulation on PowerPC.
+    - 10-link-restrictions.conf: this is redundant with link-protect.conf
+      from Debian.
+  * debian/procps.maintscript: handle migration of link-protect.conf from
+    /etc to /usr.
+
+ -- Steve Langasek <steve.langasek@ubuntu.com>  Thu, 13 Feb 2020 22:53:02 -0800
+
 procps (2:3.3.16-1) unstable; urgency=medium
 
   [ Ondřej Nový ]
@@ -285,6 +770,51 @@ procps (2:3.3.16-1) unstable; urgency=me
 
  -- Craig Small <csmall@debian.org>  Fri, 07 Feb 2020 19:05:09 +1100
 
+procps (2:3.3.15-2ubuntu3) eoan; urgency=medium
+
+  * d/p/pgrep-increase-CMDSTRSIZE.patch:
+    - Allows long command lines to be searched.
+    eg: Java process with a long classpath. (LP: #1839329)
+
+ -- Eric Desrochers <eric.desrochers@canonical.com>  Thu, 08 Aug 2019 16:46:48 +0000
+
+procps (2:3.3.15-2ubuntu2) disco; urgency=medium
+
+  * 10-network-security.conf: change the rp_filter default from 1 to 2,
+    the strict mode isn't compatible with the n-m handling of
+    captive portals (lp: #1814262)
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Thu, 07 Feb 2019 23:46:43 +0100
+
+procps (2:3.3.15-2ubuntu1) cosmic; urgency=medium
+
+  * Merge from Debian unstable.  Remaining changes:
+    - debian/sysctl.d (Ubuntu-specific):
+      + 10-console-messages.conf: stop low-level kernel messages on console.
+      + 10-kernel-hardening.conf: add the kptr_restrict setting
+      + 10-keyboard.conf.powerpc: mouse button emulation on PowerPC.
+      + 10-ipv6-privacy.conf: add a file to sysctl.d to apply the defaults
+        for IPv6 privacy extensions for interfaces. (LP: #176125, #841353)
+      + 10-link-restrictions.conf: even though the Ubuntu
+        kernel is built with these defaults in place, we want to make sure
+        that people running stock kernels don't miss out.
+      + 10-magic-sysrq.conf: Disable most magic sysrq by default, allowing
+        critical sync, remount, reboot functions. (LP: #194676, LP: #1025467)
+      + 10-network-security.conf: enable rp_filter.
+      + 10-ptrace.conf: describe new PTRACE setting.
+      + 10-zeropage.conf: safe mmap_min_addr value for graceful fall-back.
+        for armhf, and arm64.
+      + 10-qemu.conf.s390x for qemu.
+      + README: describe how this directory is supposed to work.
+    - debian/rules: Fix cross build
+    - ignore_eaccess.patch: If we get eaccess when opening a sysctl file for
+      writing, don't error out.  Otherwise package upgrades can fail,
+      especially in containers.
+    - ignore_erofs.patch: Same as ignore_eaccess but for the case where
+      part of /proc is read/only.
+
+ -- Balint Reczey <rbalint@ubuntu.com>  Tue, 05 Jun 2018 11:20:00 -0700
+
 procps (2:3.3.15-2) unstable; urgency=medium
 
   * Fix link in libprocps-dev Closes: 900239
@@ -292,6 +822,38 @@ procps (2:3.3.15-2) unstable; urgency=me
 
  -- Craig Small <csmall@debian.org>  Thu, 31 May 2018 19:42:46 +1000
 
+procps (2:3.3.15-1ubuntu1) cosmic; urgency=medium
+
+  * Merge from Debian unstable.  Remaining changes:
+    - debian/sysctl.d (Ubuntu-specific):
+      + 10-console-messages.conf: stop low-level kernel messages on console.
+      + 10-kernel-hardening.conf: add the kptr_restrict setting
+      + 10-keyboard.conf.powerpc: mouse button emulation on PowerPC.
+      + 10-ipv6-privacy.conf: add a file to sysctl.d to apply the defaults
+        for IPv6 privacy extensions for interfaces. (LP: #176125, #841353)
+      + 10-link-restrictions.conf: even though the Ubuntu
+        kernel is built with these defaults in place, we want to make sure
+        that people running stock kernels don't miss out.
+      + 10-magic-sysrq.conf: Disable most magic sysrq by default, allowing
+        critical sync, remount, reboot functions. (LP: #194676, LP: #1025467)
+      + 10-network-security.conf: enable rp_filter.
+      + 10-ptrace.conf: describe new PTRACE setting.
+      + 10-zeropage.conf: safe mmap_min_addr value for graceful fall-back.
+        for armhf, and arm64.
+      + 10-qemu.conf.s390x for qemu.
+      + README: describe how this directory is supposed to work.
+    - debian/rules: Fix cross build
+    - ignore_eaccess.patch: If we get eaccess when opening a sysctl file for
+      writing, don't error out.  Otherwise package upgrades can fail,
+      especially in containers.
+    - ignore_erofs.patch: Same as ignore_eaccess but for the case where
+      part of /proc is read/only.
+  * Drop redundant setting of net.ipv4.tcp_syncookies=1, it is now the kernel's default
+    (LP: #1773157)
+  * Update README about new commands for reloading configuration (LP: #1719159)
+
+ -- Balint Reczey <rbalint@ubuntu.com>  Fri, 25 May 2018 12:09:30 +0200
+
 procps (2:3.3.15-1) unstable; urgency=medium
 
   * New upstream release Closes: #899170
@@ -337,6 +899,35 @@ procps (2:3.3.12-4) unstable; urgency=me
 
  -- Craig Small <csmall@debian.org>  Sat, 10 Feb 2018 10:59:11 +1100
 
+procps (2:3.3.12-3ubuntu1) bionic; urgency=medium
+
+  * Merge from Debian unstable.  Remaining changes:
+    - debian/sysctl.d (Ubuntu-specific):
+      + 10-console-messages.conf: stop low-level kernel messages on console.
+      + 10-kernel-hardening.conf: add the kptr_restrict setting
+      + 10-keyboard.conf.powerpc: mouse button emulation on PowerPC.
+      + 10-ipv6-privacy.conf: add a file to sysctl.d to apply the defaults
+        for IPv6 privacy extensions for interfaces. (LP: #176125, #841353)
+      + 10-link-restrictions.conf: even though the Ubuntu
+        kernel is built with these defaults in place, we want to make sure
+        that people running stock kernels don't miss out.
+      + 10-magic-sysrq.conf: Disable most magic sysrq by default, allowing
+        critical sync, remount, reboot functions. (LP: #194676, LP: #1025467)
+      + 10-network-security.conf: enable rp_filter and SYN-flood protection.
+      + 10-ptrace.conf: describe new PTRACE setting.
+      + 10-zeropage.conf: safe mmap_min_addr value for graceful fall-back.
+        for armhf, and arm64.
+      + 10-qemu.conf.s390x for qemu.
+      + README: describe how this directory is supposed to work.
+    - debian/rules: Fix cross build
+    - ignore_eaccess.patch: If we get eaccess when opening a sysctl file for
+      writing, don't error out.  Otherwise package upgrades can fail,
+      especially in containers.
+    - ignore_erofs.patch: Same as ignore_eaccess but for the case where
+      part of /proc is read/only.
+
+ -- Balint Reczey <rbalint@ubuntu.com>  Wed, 17 Jan 2018 23:35:48 +0100
+
 procps (2:3.3.12-3) unstable; urgency=medium
 
   [ Sven Joachim <svenjoac@gmx.de> ]
@@ -359,6 +950,44 @@ procps (2:3.3.12-2) unstable; urgency=me
 
  -- Craig Small <csmall@debian.org>  Wed, 13 Jul 2016 21:20:48 +1000
 
+procps (2:3.3.12-1ubuntu2) yakkety; urgency=medium
+
+  * Remove strtod_nol tests Closes: #830733
+    (Cherry-picked from Debian packaging git).
+  * Only have one installinit override, thanks Sven! Closes: #827423
+    (Cherry-picked from Debian packaging git).
+
+ -- Martin Pitt <martin.pitt@ubuntu.com>  Tue, 12 Jul 2016 08:07:11 +0200
+
+procps (2:3.3.12-1ubuntu1) yakkety; urgency=medium
+
+  * Merge from Debian unstable.  Remaining changes:
+    - debian/sysctl.d (Ubuntu-specific):
+      + 10-console-messages.conf: stop low-level kernel messages on console.
+      + 10-kernel-hardening.conf: add the kptr_restrict setting
+      + 10-keyboard.conf.powerpc: mouse button emulation on PowerPC.
+      + 10-ipv6-privacy.conf: add a file to sysctl.d to apply the defaults
+        for IPv6 privacy extensions for interfaces. (LP: #176125, #841353)
+      + 10-link-restrictions.conf: even though the Ubuntu
+        kernel is built with these defaults in place, we want to make sure
+        that people running stock kernels don't miss out.
+      + 10-magic-sysrq.conf: Disable most magic sysrq by default, allowing
+        critical sync, remount, reboot functions. (LP: #194676, LP: #1025467)
+      + 10-network-security.conf: enable rp_filter and SYN-flood protection.
+      + 10-ptrace.conf: describe new PTRACE setting.
+      + 10-zeropage.conf: safe mmap_min_addr value for graceful fall-back.
+        for armhf, and arm64.
+      + 10-qemu.conf.s390x for qemu.
+      + README: describe how this directory is supposed to work.
+    - debian/rules: Fix cross build
+    - ignore_eaccess.patch: If we get eaccess when opening a sysctl file for
+      writing, don't error out.  Otherwise package upgrades can fail,
+      especially in containers.
+    - ignore_erofs.patch: Same as ignore_eaccess but for the case where
+      part of /proc is read/only.
+
+ -- Martin Pitt <martin.pitt@ubuntu.com>  Mon, 11 Jul 2016 22:30:18 +0200
+
 procps (2:3.3.12-1) unstable; urgency=medium
 
   [ Helmut Grohne <helmut@subdivi.de> ]
@@ -384,6 +1013,42 @@ procps (2:3.3.12-1) unstable; urgency=me
 
  -- Craig Small <csmall@debian.org>  Sun, 10 Jul 2016 17:39:28 +1000
 
+procps (2:3.3.11-3ubuntu1) yakkety; urgency=medium
+
+  [ Martin Pitt ]
+  * Merge from Debian unstable.  Remaining changes:
+    - debian/sysctl.d (Ubuntu-specific):
+      + 10-console-messages.conf: stop low-level kernel messages on console.
+      + 10-kernel-hardening.conf: add the kptr_restrict setting
+      + 10-keyboard.conf.powerpc: mouse button emulation on PowerPC.
+      + 10-ipv6-privacy.conf: add a file to sysctl.d to apply the defaults
+        for IPv6 privacy extensions for interfaces. (LP: #176125, #841353)
+      + 10-link-restrictions.conf: even though the Ubuntu
+        kernel is built with these defaults in place, we want to make sure
+        that people running stock kernels don't miss out.
+      + 10-magic-sysrq.conf: Disable most magic sysrq by default, allowing
+        critical sync, remount, reboot functions. (LP: #194676, LP: #1025467)
+      + 10-network-security.conf: enable rp_filter and SYN-flood protection.
+      + 10-ptrace.conf: describe new PTRACE setting.
+      + 10-zeropage.conf: safe mmap_min_addr value for graceful fall-back.
+        for armhf, and arm64.
+      + 10-qemu.conf.s390x for qemu.
+      + README: describe how this directory is supposed to work.
+    - debian/upstart (Ubuntu-specific): upstart configuration to replace old
+      style sysv init script
+    - debian/rules: Fix cross build
+    - ignore_eaccess.patch: If we get eaccess when opening a sysctl file for
+      writing, don't error out.  Otherwise package upgrades can fail,
+      especially in containers.
+    - ignore_erofs.patch: Same as ignore_eaccess but for the case where
+      part of /proc is read/only.
+
+   [ Craig Small ]
+   * Dropped initscript dependency Closes: #804966
+     [Taken from Debian packaging git]
+
+ -- Martin Pitt <martin.pitt@ubuntu.com>  Fri, 20 May 2016 18:09:37 +0200
+
 procps (2:3.3.11-3) unstable; urgency=medium
 
   * New upstream source (from experimental)
diff -pruN 2:4.0.4-8/debian/control 2:4.0.4-8ubuntu3/debian/control
--- 2:4.0.4-8/debian/control	2025-04-14 08:06:27.000000000 +0000
+++ 2:4.0.4-8ubuntu3/debian/control	2025-08-29 10:58:29.000000000 +0000
@@ -1,7 +1,8 @@
 Source: procps
 Section: admin
 Priority: optional
-Maintainer: Craig Small <csmall@debian.org>
+Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
+XSBC-Original-Maintainer: Craig Small <csmall@debian.org>
 Build-Depends: debhelper-compat (= 13),
     dh-exec (>= 0.3),
     libncurses-dev,
diff -pruN 2:4.0.4-8/debian/patches/0010-testsuite-ps-etime-ELAPSED-doesn-t-match-full-format.patch 2:4.0.4-8ubuntu3/debian/patches/0010-testsuite-ps-etime-ELAPSED-doesn-t-match-full-format.patch
--- 2:4.0.4-8/debian/patches/0010-testsuite-ps-etime-ELAPSED-doesn-t-match-full-format.patch	1970-01-01 00:00:00.000000000 +0000
+++ 2:4.0.4-8ubuntu3/debian/patches/0010-testsuite-ps-etime-ELAPSED-doesn-t-match-full-format.patch	2025-08-29 10:58:29.000000000 +0000
@@ -0,0 +1,41 @@
+From: =?utf-8?q?Lukas_M=C3=A4rdian?= <slyon@ubuntu.com>
+Date: Tue, 21 Nov 2023 12:30:57 +0100
+Subject: testsuite:ps: etime/ELAPSED doesn't match full format
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+According to the manpage on Ubuntu 23.10 the etime/ELAPSED output can take
+the following format:
+"elapsed time since the process was started, in the form [[DD-]hh:]mm:ss."
+
+We're not currently accouting for the [DD-] part, which makes this test
+fail inside an Ubuntu 24.04 LXD container running on a Ubuntu 23.10 host.
+
+$ lxc shell nn
+root@nn:~# ps -o bsdtime,cputime,etime,etimes
+  TIME     TIME     ELAPSED ELAPSED
+  0:00 00:00:00 441077220-02:35:44 4121967232
+  0:00 00:00:00 441077220-02:35:44 4121967232
+  0:00 00:00:00 441077220-02:35:12 4121967200
+
+Origin: vendor, Ubuntu
+Author: Lukas Märdian <slyon@ubuntu.com>
+Forwarded: https://gitlab.com/procps-ng/procps/-/merge_requests/208
+---
+ testsuite/ps.test/ps_output.exp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/testsuite/ps.test/ps_output.exp b/testsuite/ps.test/ps_output.exp
+index ff2a233..1f32513 100644
+--- a/testsuite/ps.test/ps_output.exp
++++ b/testsuite/ps.test/ps_output.exp
+@@ -25,7 +25,7 @@ set flag_match {
+     "%cpu,pcpu,%mem,pmem"   "%CPU\\s+%CPU\\s+%MEM\\s+%MEM\\s+\(\(\\d+\.\\d+\\s*\){4}\)+$"
+     "blocked,sig_block,sigmask,caught,sigcatch,sig_catch" "\(BLOCKED\\s+\){3}\(CAUGHT\\s+\){2}CATCHED\\s+\(<?\[0-9a-f\]+\\s*\)+$"
+     "bsdstart,start,lstart" "\\s*START\\s+STARTED\\s+STARTED\\s+\(\\s*\(\[A-Z\]\[a-z\]{2} \\d+|\\d+:\\d{2}\)\\s+\(\[A-Z\]\[a-z\]{2} \\d+|\\d+:\\d{2}:\\d{2}\)\\s+\[A-Z\]\[a-z\]{2} \[A-Z\]\[a-z\]{2}\\s+\\d+ \\d{2}:\\d{2}:\\d{2} \\d{4}\\s*\)+$"
+-    "bsdtime,cputime,etime,etimes" "\\s*TIME\\s+TIME\\s+ELAPSED\\s+ELAPSED\\s*\(\\s*\\d+:\\d{2}\\s+\\d{2}:\\d{2}:\\d{2}\\s+\(\\d{2}:\)?\\d{2}:\\d{2}\\s+\\d+\\s*\)+$"
++    "bsdtime,cputime,etime,etimes" "\\s*TIME\\s+TIME\\s+ELAPSED\\s+ELAPSED\\s*\(\\s*\\d+:\\d{2}\\s+\\d{2}:\\d{2}:\\d{2}\\s+\(\\d+-\)?\(\\d{2}:\)?\\d{2}:\\d{2}\\s+\\d+\\s*\)+$"
+     "user,ruser,group,rgroup,uid,ruid,gid,rgid" "\\s*USER\\s+RUSER\\s+GROUP\\s+RGROUP\\s+UID\\s+RUID\\s+GID\\s+RGID\\s+\(\(\\s*\[A-Za-z0-9_+-\]+\\s+\){4}\(\\d+\\s+\){4}\\s*\)+$"
+     "cputimes,times" "\\s*TIME\\s+TIME\\s+\\d+\\s+\\d+\\s*"
+ }
diff -pruN 2:4.0.4-8/debian/patches/ignore_eaccess.patch 2:4.0.4-8ubuntu3/debian/patches/ignore_eaccess.patch
--- 2:4.0.4-8/debian/patches/ignore_eaccess.patch	1970-01-01 00:00:00.000000000 +0000
+++ 2:4.0.4-8ubuntu3/debian/patches/ignore_eaccess.patch	2025-08-29 10:58:29.000000000 +0000
@@ -0,0 +1,31 @@
+Description: Ignore EACCESS when writing a new setting
+ If we are running in a container, we're not allowed to write to any
+ non-namespaced sysctls.
+Author: Vincent Fazio <vfazio@xes-inc.com>
+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/procps/+bug/1157643
+
+--- a/src/sysctl.c
++++ b/src/sysctl.c
+@@ -530,12 +530,13 @@ static int WriteSetting(
+     const char *key,
+     const char *path,
+     const char *value,
+-    const bool ignore_failure)
++    const bool ign_failure)
+ {
+     int rc = EXIT_SUCCESS;
+     FILE *fp;
+     struct stat ts;
+     char *dotted_key;
++    bool ignore_failure = ign_failure;
+ 
+     if (!key || !path)
+         return rc;
+@@ -585,6 +586,7 @@ static int WriteSetting(
+             case EPERM:
+             case EROFS:
+             case EACCES:
++                ignore_failure = true;
+                 xwarnx(_("permission denied on key \"%s\"%s"),
+                        dotted_key, (ignore_failure?_(", ignoring"):""));
+                 break;
diff -pruN 2:4.0.4-8/debian/patches/ignore_erofs.patch 2:4.0.4-8ubuntu3/debian/patches/ignore_erofs.patch
--- 2:4.0.4-8/debian/patches/ignore_erofs.patch	1970-01-01 00:00:00.000000000 +0000
+++ 2:4.0.4-8ubuntu3/debian/patches/ignore_erofs.patch	2025-08-29 10:58:29.000000000 +0000
@@ -0,0 +1,25 @@
+Description: Ignore EROFS when writing a new setting
+ If we are running in a container, we're not allowed to write to any
+ non-namespaced sysctls.
+Author: Vincent Fazio <vfazio@xes-inc.com>
+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/procps/+bug/1419554
+Last-Update: 2020-11-06
+---
+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
+--- a/src/sysctl.c
++++ b/src/sysctl.c
+@@ -583,12 +583,13 @@ static int WriteSetting(
+                 }
+                 break;
+             case EPERM:
+-            case EROFS:
+             case EACCES:
+                 ignore_failure = true;
+                 xwarnx(_("permission denied on key \"%s\"%s"),
+                        dotted_key, (ignore_failure?_(", ignoring"):""));
+                 break;
++            case EROFS:
++                ignore_failure = true;
+             default:
+                 xwarn(_("setting key \"%s\"%s"),
+                       dotted_key, (ignore_failure?_(", ignoring"):""));
diff -pruN 2:4.0.4-8/debian/patches/lp2120904-nullpointer.patch 2:4.0.4-8ubuntu3/debian/patches/lp2120904-nullpointer.patch
--- 2:4.0.4-8/debian/patches/lp2120904-nullpointer.patch	1970-01-01 00:00:00.000000000 +0000
+++ 2:4.0.4-8ubuntu3/debian/patches/lp2120904-nullpointer.patch	2025-08-29 10:58:29.000000000 +0000
@@ -0,0 +1,197 @@
+Description: The library position was to never subject callers to a
+NULL string pointer. Rather, a literal "-" was usually
+substituted to mean such information is not available.
+
+But, as revealed in the issue cited below, there was a
+huge unknown gap in our goal. Under the original code,
+if the 'status' file was not available in /proc/<pid>,
+fields like supgrp, ruser, rgroup, etc. would be NULL.
+
+The same was true with lxc and docker container fields
+which depend on the 'cgroup' file. Should that file be
+missing it means more unexpected NULL string pointers.
+
+Under what conditions might such files be unavailable?
+If a process exited but has not yet been fully reaped,
+it could be encountered by a repeatedly run ps or by a
+continuously running program like top. In such a case,
+there's a possibility some files under /proc/<pid> are
+missing. A NULL string address could then be a result.
+Author: Jim Warner <james.warner@comcast.net>
+Author: John Chittum <john.chittum@canonical.com>
+Origin: https://gitlab.com/procps-ng/procps/-/commit/a5708118a4f3184cb5a3e2faa219807e73f007d3
+Bug: https://gitlab.com/procps-ng/procps/-/issues/390
+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/procps/+bug/2120904
+Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1111830
+Last-Update: 2025-08-29
+---
+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
+--- a/library/pids.c
++++ b/library/pids.c
+@@ -104,10 +104,12 @@
+ 
+ // ___ Free Storage Support |||||||||||||||||||||||||||||||||||||||||||||||||||
+ 
++extern char *str_none;
++
+ #define freNAME(t) free_pids_ ## t
+ 
+ static void freNAME(str) (struct pids_result *R) {
+-    if (R->result.str) free(R->result.str);
++    if (R->result.str && R->result.str != str_none) free(R->result.str);
+ }
+ 
+ static void freNAME(strv) (struct pids_result *R) {
+@@ -1001,10 +1003,12 @@
+         info->oldflags |= Item_table[e].oldflags;
+         info->history_yes |= Item_table[e].needhist;
+     }
+-    if (info->oldflags & f_either) {
+-        if (!(info->oldflags & (f_stat | f_status)))
+-            info->oldflags |= f_stat;
+-    }
++//  note: the read of f_stat has been made unconditional in readproc.c
++//        so this logic is no longer useful ...
++//  if (info->oldflags & f_either) {
++//      if (!(info->oldflags & (f_stat | f_status)))
++//          info->oldflags |= f_stat;
++//  }
+     return;
+ } // end: pids_libflags_set
+ 
+--- a/library/readproc.c
++++ b/library/readproc.c
+@@ -79,6 +79,7 @@
+ 
+ static int task_dir_missing;
+ 
++char *str_none = "-";
+ 
+ // free any additional dynamically acquired storage associated with a proc_t
+ static inline void free_acquired (proc_t *p) {
+@@ -96,9 +97,15 @@
+     if (p->sd_slice) free(p->sd_slice);
+     if (p->sd_unit)  free(p->sd_unit);
+     if (p->sd_uunit) free(p->sd_uunit);
+-    if (p->supgid)   free(p->supgid);
++     if (p->supgid && p->supgid != str_none)  free(p->supgid);
+ 
+     memset(p, '\0', sizeof(proc_t));
++    // if /proc/<pid>/status wasn't available we won't be calling the pwcache guys,
++    // so we'll follow the convention used elsewhere in this module ...
++    p->ruser = p->suser = p->fuser
++        = p->rgroup = p->sgroup = p->fgroup
++        = p->supgid = p->supgrp
++        = str_none;
+ }
+ 
+ static void close_dirfd(int *fd)
+@@ -463,11 +470,8 @@
+ #ifdef FALSE_THREADS
+     if (!IS_THREAD(P)) {
+ #endif
+-    if (!P->supgid) {
+-        P->supgid = strdup("-");
+-        if (!P->supgid)
+-            return 1;
+-    }
++    if (!P->supgid)
++        P->supgid = str_none;
+ #ifdef FALSE_THREADS
+     }
+ #endif
+@@ -484,8 +488,10 @@
+ #ifdef FALSE_THREADS
+     if (IS_THREAD(p)) return 0;
+ #endif
+-    if (!p->supgid || '-' == *p->supgid)
++    if (!p->supgid || p->supgid == str_none)
+         goto wrap_up;
++    // ensure we're not pointing to str_none ...
++    p->supgrp = NULL;
+ 
+     s = p->supgid;
+     t = 0;
+@@ -512,9 +518,8 @@
+     } while (*s);
+ 
+ wrap_up:
+-    if (!p->supgrp
+-    && !(p->supgrp = strdup("-")))
+-        return 1;
++    if (!p->supgrp)
++        p->supgrp = str_none;
+     return 0;
+ }
+ 
+@@ -974,7 +979,7 @@
+         escape_str(dst_buffer, src_buffer, MAX_BUFSZ);
+     else
+         escape_command(dst_buffer, p, MAX_BUFSZ, uFLG);
+-    p->cmdline = strdup(dst_buffer[0] ? dst_buffer : "?");
++    p->cmdline = strdup(dst_buffer[0] ? dst_buffer : str_none);
+     if (!p->cmdline)
+         return 1;
+     return 0;
+@@ -1164,11 +1169,14 @@
+     p->euid = sb.st_uid;                        /* need a way to get real uid */
+     p->egid = sb.st_gid;                        /* need a way to get real gid */
+ 
+-    if (flags & PROC_FILLSTAT) {                // read /proc/#/stat
++    /* this attempted read of 'stat' is now unconditional to ensure a 'cmd' name
++       as a minimum. this prevents a NULL 'cmdline' pointer for kernel threads
++       in case the 'status' file is missing or not otherwise read ... */
++//    if (flags & PROC_FILLSTAT) {                // read /proc/#/stat
+         if (file2str(PT->pidfd, "stat", &ub) == -1)
+             goto next_proc;
+         rc += stat2proc(ub.buf, p);
+-    }
++//    }
+ 
+     if (flags & PROC_FILLIO) {                  // read /proc/#/io
+         if (file2str(PT->pidfd, "io", &ub) != -1)
+@@ -1246,9 +1254,11 @@
+     if (flags & PROC_FILLSYSTEMD)               // get sd-login.h stuff
+         rc += sd2proc(p);
+ 
+-    if (flags & PROC_FILL_LXC)                  // value the lxc name
++    if (flags & PROC_FILL_LXC){                  // value the lxc name
++        // ok if nothing is read, an empty buffer will do just fine ...
++        file2str(PT->pidfd, "cgroup", &ub);
+         p->lxcname = lxc_containers(&ub);
+-
++}
+     if (flags & PROC_FILL_LUID)                 // value the login user id
+         p->luid = login_uid(PT->pidfd);
+ 
+@@ -1293,11 +1303,14 @@
+     t->euid = sb.st_uid;                        /* need a way to get real uid */
+     t->egid = sb.st_gid;                        /* need a way to get real gid */
+ 
+-    if (flags & PROC_FILLSTAT) {                // read /proc/#/task/#/stat
++    /* this attempted read of 'stat' is now unconditional to ensure a 'cmd' name
++       as a minimum. this prevents a NULL 'cmdline' pointer for kernel threads
++       in case the 'status' file is missing or not otherwise read ... */
++//  if (flags & PROC_FILLSTAT) {                // read /proc/#/task/#/stat
+         if (file2str(PT->taskfd, "stat", &ub) == -1)
+             goto next_task;
+         rc += stat2proc(ub.buf, t);
+-    }
++//    }
+ 
+     if (flags & PROC_FILLIO) {                  // read /proc/#/task/#/io
+         if (file2str(PT->taskfd, "io", &ub) != -1)
+@@ -1380,9 +1393,11 @@
+     if (flags & PROC_FILLNS)                    // read /proc/#/task/#/ns/*
+         procps_ns_read_pid(t->tid, &(t->ns));
+ 
+-    if (flags & PROC_FILL_LXC)
++    if (flags & PROC_FILL_LXC){
++        // ok if nothing is read, an empty buffer will do just fine ...
++        file2str(PT->taskfd, "cgroup", &ub);
+         t->lxcname = lxc_containers(&ub);
+-
++}
+     if (flags & PROC_FILL_LUID)
+         t->luid = login_uid(PT->taskfd);
+ 
diff -pruN 2:4.0.4-8/debian/patches/lp2120904-openat.patch 2:4.0.4-8ubuntu3/debian/patches/lp2120904-openat.patch
--- 2:4.0.4-8/debian/patches/lp2120904-openat.patch	1970-01-01 00:00:00.000000000 +0000
+++ 2:4.0.4-8ubuntu3/debian/patches/lp2120904-openat.patch	2025-08-29 10:58:29.000000000 +0000
@@ -0,0 +1,683 @@
+Description: The internals in the library within readproc had an "interesting" way
+of using the path variable. Sometimes global, sometimes from proctab
+and sometimes local to the function, or passed through from one other
+way.
+
+Besides the issue of the path variable scope, using standard open()
+means we cannot be sure that /proc/12345/stat and /proc/12345/cmdline
+are from the same process, because the first may have died and we are
+in a PID reuse situation. By opening the /proc/<PID> directory and
+consistently using this, we remove the ambiguity. There are some
+vague promises that open()ing /proc/<PID> turns it into a pidfd,
+like pidfd_open(2) with all the guarantees that provides, but I'm
+not convinced.
+
+Why not use pidfd_open(2) then? Because what it returns a file
+descriptor of type... nothing (st_mode=0). Some functions are fine
+using the fd, but openat() fails. statx() works if the pathname is
+null, but not if it has a value. A lot of functions expect the
+fd to be a type directory, and pidfd_open isn't (quite) that.
+
+Trying to use openat() with a mode O_PATH for directories gives
+a different set of problems. While subsequent openat()s on
+subdirectories work, fstat() fails; hence the strictly not-required
+O_RDONLY mode is used instead.
+
+After multiple runs with strace, the only direct opens are for
+the directories /proc, /proc/self and /proc/<PID> however there
+is a possibility there is a code path that doesn't reset/establish
+the dirfds correctly.
+
+Patch deviates from upstream as commit in Gitlab was on top of various features.
+Craig Small authoredoriginal commit, John Chittum made patch alterations
+Author: Craig Small <csmall@dropbear.xyz>
+Author: John Chittum <john.chittum@canonical.com
+Origin: https://gitlab.com/procps-ng/procps/-/commit/5e4886ae9231d332edd591334c210e8ba5ed9e84
+Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1111830
+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/procps/+bug/2120904
+Last-Update: 2025-08-28
+---
+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
+--- a/library/include/readproc.h
++++ b/library/include/readproc.h
+@@ -205,6 +205,8 @@
+ #define PROCPATHLEN 64  // must hold /proc/2000222000/task/2000222000/cmdline
+ 
+ typedef struct PROCTAB {
++    int         pidfd;          // FD for the /proc/<pid> directory
++    int         taskfd;         // FD for the /proc/<pid>/tasks/<tid> directory
+     DIR        *procfs;
+ //    char deBug0[64];
+     DIR        *taskdir;  // for threads
+@@ -212,18 +214,14 @@
+     pid_t       taskdir_user;  // for threads
+     int(*finder)(struct PROCTAB *__restrict const, proc_t *__restrict const);
+     proc_t*(*reader)(struct PROCTAB *__restrict const, proc_t *__restrict const);
+-    int(*taskfinder)(struct PROCTAB *__restrict const, const proc_t *__restrict const, proc_t *__restrict const, char *__restrict const);
+-    proc_t*(*taskreader)(struct PROCTAB *__restrict const, proc_t *__restrict const, char *__restrict const);
++    int(*taskfinder)(struct PROCTAB *__restrict const, const proc_t *__restrict const, proc_t *__restrict const);
++    proc_t*(*taskreader)(struct PROCTAB *__restrict const, proc_t *__restrict const);
+     pid_t      *pids;   // pids of the procs
+     uid_t      *uids;   // uids of procs
+     int         nuid;   // cannot really sentinel-terminate unsigned short[]
+     int         i;  // generic
+     int         hide_kernel;  // getenv LIBPROC_HIDE_KERNEL was set
+     unsigned    flags;
+-    unsigned    u;  // generic
+-    void *      vp; // generic
+-    char        path[PROCPATHLEN];  // must hold /proc/2000222000/task/2000222000/cmdline
+-    unsigned pathlen;        // length of string in the above (w/o '\0')
+ } PROCTAB;
+ 
+ 
+--- a/library/readproc.c
++++ b/library/readproc.c
+@@ -35,6 +35,7 @@
+ #include <dirent.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
++#include <sys/syscall.h>
+ #include <limits.h>
+ #include <stdint.h>
+ #ifdef WITH_SYSTEMD
+@@ -100,6 +101,37 @@
+     memset(p, '\0', sizeof(proc_t));
+ }
+ 
++static void close_dirfd(int *fd)
++{
++    if (*fd >= 0) {
++        close(*fd);
++        *fd = -1;
++    }
++}
++
++/*
++ * Open a directory stream using the pathname relative what dirfd points to.
++ * If successful, fdopendir() takes control of the fd, so we it gets closed
++ * in the subsequent closedir(3)
++ * fdopendir() needs O_RDONLY not O_PATH, despite it being possible to use
++ * in other openat() calls, the fcntl() fails.
++ */
++static DIR* opendirat(
++        int dirfd,
++        const char *pathname)
++{
++    int fd;
++    DIR *dirp;
++
++   if ((fd = openat(dirfd, pathname, O_DIRECTORY | O_RDONLY)) < 0)
++       return NULL;
++   if ((dirp = fdopendir(fd)) == NULL) {
++       int tmperrno = errno;
++       close(fd);
++       errno = tmperrno;
++   }
++   return dirp;
++}
+ 
+ ///////////////////////////////////////////////////////////////////////////
+ 
+@@ -719,9 +751,8 @@
+   #undef mkOBJ
+ }
+ 
+-static int file2str(const char *directory, const char *what, struct utlbuf_s *ub) {
++static int file2str(int dirfd, const char *what, struct utlbuf_s *ub) {
+  #define buffGRW 1024
+-    char path[PROCPATHLEN];
+     int fd, num, tot_read = 0, len;
+ 
+     /* on first use we preallocate a buffer of minimum size to emulate
+@@ -733,9 +764,7 @@
+         ub->buf = calloc(1, (ub->siz = buffGRW));
+         if (!ub->buf) return -1;
+     }
+-    len = snprintf(path, sizeof path, "%s/%s", directory, what);
+-    if (len <= 0 || (size_t)len >= sizeof path) return -1;
+-    if (-1 == (fd = open(path, O_RDONLY, 0))) return -1;
++    if (-1 == (fd = openat(dirfd, what, O_RDONLY, 0))) return -1;
+     while (0 < (num = read(fd, ub->buf + tot_read, ub->siz - tot_read))) {
+         tot_read += num;
+         if (tot_read < ub->siz) break;
+@@ -756,15 +785,13 @@
+ }
+ 
+ 
+-static char **file2strvec(const char *directory, const char *what) {
++static char **file2strvec(int dirfd, const char *what) {
+     char buf[2048];     /* read buf bytes at a time */
+     char *p, *rbuf = 0, *endbuf, **q, **ret, *strp;
+     int fd, tot = 0, n, c, end_of_file = 0;
+     int align;
+ 
+-    const int len = snprintf(buf, sizeof buf, "%s/%s", directory, what);
+-    if(len <= 0 || (size_t)len >= sizeof buf) return NULL;
+-    fd = open(buf, O_RDONLY, 0);
++    fd = openat(dirfd, what, O_RDONLY, 0);
+     if(fd==-1) return NULL;
+ 
+     /* read whole file into a memory buffer, allocating as we go */
+@@ -838,7 +865,7 @@
+     // this is the former under utilized 'read_cmdline', which has been
+     // generalized in support of these new libproc flags:
+     //     PROC_EDITCGRPCVT, PROC_EDITCMDLCVT and PROC_EDITENVRCVT
+-static int read_unvectored(char *restrict const dst, unsigned sz, const char *whom, const char *what, char sep) {
++static int read_unvectored(char *restrict const dst, unsigned sz, int dirfd, const char *what, char sep) {
+     char path[PROCPATHLEN];
+     int fd, len;
+     unsigned n = 0;
+@@ -847,10 +874,8 @@
+     if(sz >= INT_MAX) sz = INT_MAX-1;
+     dst[0] = '\0';
+ 
+-    len = snprintf(path, sizeof(path), "%s/%s", whom, what);
+-    if(len <= 0 || (size_t)len >= sizeof(path)) return 0;
+-    fd = open(path, O_RDONLY);
+-    if(fd==-1) return 0;
++    if ((fd = openat(dirfd, what, O_RDONLY)) == -1)
++        return 0;
+ 
+     for(;;){
+         ssize_t r = read(fd,dst+n,sz-n);
+@@ -908,13 +933,13 @@
+ 
+     // This routine reads a 'cgroup' for the designated proc_t and
+     // guarantees the caller a valid proc_t.cgroup pointer.
+-static int fill_cgroup_cvt (const char *directory, proc_t *restrict p) {
++static int fill_cgroup_cvt (int dirfd, proc_t *restrict p) {
+  #define vMAX ( MAX_BUFSZ - (int)(dst - dst_buffer) )
+     char *src, *dst, *grp, *eob, *name;
+     int tot, x, len;
+ 
+     *(dst = dst_buffer) = '\0';                  // empty destination
+-    tot = read_unvectored(src_buffer, MAX_BUFSZ, directory, "cgroup", '\0');
++    tot = read_unvectored(src_buffer, MAX_BUFSZ, dirfd, "cgroup", '\0');
+     for (src = src_buffer, eob = src_buffer + tot; src < eob; src += x) {
+         x = 1;                                   // loop assist
+         if (!*src) continue;
+@@ -943,9 +968,9 @@
+     // This routine reads a 'cmdline' for the designated proc_t, "escapes"
+     // the result into a single string while guaranteeing the caller a
+     // valid proc_t.cmdline pointer.
+-static int fill_cmdline_cvt (const char *directory, proc_t *restrict p) {
++static int fill_cmdline_cvt (int dirfd, proc_t *restrict p) {
+  #define uFLG ( ESC_BRACKETS | ESC_DEFUNCT )
+-    if (read_unvectored(src_buffer, MAX_BUFSZ, directory, "cmdline", ' '))
++    if (read_unvectored(src_buffer, MAX_BUFSZ, dirfd, "cmdline", ' '))
+         escape_str(dst_buffer, src_buffer, MAX_BUFSZ);
+     else
+         escape_command(dst_buffer, p, MAX_BUFSZ, uFLG);
+@@ -959,9 +984,9 @@
+ 
+     // This routine reads an 'environ' for the designated proc_t and
+     // guarantees the caller a valid proc_t.environ pointer.
+-static int fill_environ_cvt (const char *directory, proc_t *restrict p) {
++static int fill_environ_cvt (int dirfd, proc_t *restrict p) {
+     dst_buffer[0] = '\0';
+-    if (read_unvectored(src_buffer, MAX_BUFSZ, directory, "environ", ' '))
++    if (read_unvectored(src_buffer, MAX_BUFSZ, dirfd, "environ", ' '))
+         escape_str(dst_buffer, src_buffer, MAX_BUFSZ);
+     p->environ = strdup(dst_buffer[0] ? dst_buffer : "-");
+     if (!p->environ)
+@@ -973,10 +998,14 @@
+     // Provide the means to value proc_t.lxcname (perhaps only with "-") while
+     // tracking all names already seen thus avoiding the overhead of repeating
+     // malloc() and free() calls.
+-static char *lxc_containers (const char *path) {
+-    static __thread struct utlbuf_s ub = { NULL, 0 };   // util buffer for whole cgroup
++static char *lxc_containers (struct utlbuf_s *ub) {
+     static char lxc_none[] = "-";
+     static char lxc_oops[] = "?";              // used when memory alloc fails
++    static __thread struct lxc_ele {
++        struct lxc_ele *next;
++        char *name;
++    } *anchor = NULL;
++    struct lxc_ele *ele = anchor;
+     /*
+        try to locate the lxc delimiter eyecatcher somewhere in a task's cgroup
+        directory -- the following are from nested privileged plus unprivileged
+@@ -992,7 +1021,16 @@
+            2:name=systemd:/
+            1:cpuset,cpu,cpuacct,devices,freezer,net_cls,blkio,perf_event,net_prio:/lxc/lxc-P
+     */
+-    if (file2str(path, "cgroup", &ub) > 0) {
++    if (ub == NULL) {                               // looks like time for cleanup
++        while (anchor) {
++            ele = anchor->next;
++            free(anchor->name);
++            free(anchor);
++            anchor = ele;
++        }
++        return NULL;
++    }
++    if (ub->buf[0]) {
+         /* ouch, the next defaults could be changed at lxc ./configure time
+            ( and a changed 'lxc.cgroup.pattern' is only available to root ) */
+         static const char *lxc_delm1 = "lxc.payload.";    // with lxc-4.0.0
+@@ -1001,14 +1039,9 @@
+         const char *delim;
+         char *p1;
+ 
+-        if ((p1 = strstr(ub.buf, (delim = lxc_delm1)))
+-        || ((p1 = strstr(ub.buf, (delim = lxc_delm2)))
+-        || ((p1 = strstr(ub.buf, (delim = lxc_delm3)))))) {
+-            static __thread struct lxc_ele {
+-                struct lxc_ele *next;
+-                char *name;
+-            } *anchor = NULL;
+-            struct lxc_ele *ele = anchor;
++        if ((p1 = strstr(ub->buf, (delim = lxc_delm1)))
++        || ((p1 = strstr(ub->buf, (delim = lxc_delm2)))
++        || ((p1 = strstr(ub->buf, (delim = lxc_delm3)))))) {
+             int delim_len = strlen(delim);
+             char *p2;
+ 
+@@ -1041,13 +1074,12 @@
+ 
+ 
+     // Provide the user id at login (or -1 if not available)
+-static int login_uid (const char *path) {
+-    char buf[PROCPATHLEN];
++static int login_uid (const int dirfd) {
++    char buf[P_G_SZ];
+     int fd, id, in;
+ 
+     id = -1;
+-    snprintf(buf, sizeof(buf), "%s/loginuid", path);
+-    if ((fd = open(buf, O_RDONLY, 0)) != -1) {
++    if ((fd = openat(dirfd,"loginuid", O_RDONLY)) != -1) {
+         in = read(fd, buf, sizeof(buf) - 1);
+         close(fd);
+         if (in > 0) {
+@@ -1059,12 +1091,10 @@
+ }
+ 
+ 
+-static char *readlink_exe (const char *path){
+-    char buf[PROCPATHLEN];
++static char *readlink_exe (const int dirfd){
+     int in;
+ 
+-    snprintf(buf, sizeof(buf), "%s/exe", path);
+-    in = (int)readlink(buf, src_buffer, MAX_BUFSZ-1);
++    in = (int)readlinkat(dirfd, "exe", src_buffer, MAX_BUFSZ);
+     if (in > 0) {
+         src_buffer[in] = '\0';
+         escape_str(dst_buffer, src_buffer, MAX_BUFSZ);
+@@ -1075,13 +1105,12 @@
+ 
+ 
+     // Provide the autogroup fields (or -1 if not available)
+-static void autogroup_fill (const char *path, proc_t *p) {
+-    char buf[PROCPATHLEN];
++static void autogroup_fill (int dirfd, proc_t *p) {
++    char buf[100]; // 22 chars so 100 is plenty
+     int fd, in;
+ 
+     p->autogrp_id = -1;
+-    snprintf(buf, sizeof(buf), "%s/autogroup", path);
+-    if ((fd = open(buf, O_RDONLY, 0)) != -1) {
++    if ((fd = openat(dirfd, "autogroup", O_RDONLY, 0)) != -1) {
+         in = read(fd, buf, sizeof(buf) - 1);
+         close(fd);
+         if (in > 0) {
+@@ -1123,11 +1152,10 @@
+ static proc_t *simple_readproc(PROCTAB *restrict const PT, proc_t *restrict const p) {
+     static __thread struct utlbuf_s ub = { NULL, 0 };    // buf for stat,statm,status
+     static __thread struct stat sb;     // stat() buffer
+-    char *restrict const path = PT->path;
+     unsigned flags = PT->flags;
+     int rc = 0;
+ 
+-    if (stat(path, &sb) == -1)                  /* no such dirent (anymore) */
++    if (fstat(PT->pidfd, &sb) == -1)                  /* no such dirent (anymore) */
+         goto next_proc;
+ 
+     if ((flags & PROC_UID) && !XinLN(uid_t, sb.st_uid, PT->uids, PT->nuid))
+@@ -1137,28 +1165,28 @@
+     p->egid = sb.st_gid;                        /* need a way to get real gid */
+ 
+     if (flags & PROC_FILLSTAT) {                // read /proc/#/stat
+-        if (file2str(path, "stat", &ub) == -1)
++        if (file2str(PT->pidfd, "stat", &ub) == -1)
+             goto next_proc;
+         rc += stat2proc(ub.buf, p);
+     }
+ 
+     if (flags & PROC_FILLIO) {                  // read /proc/#/io
+-        if (file2str(path, "io", &ub) != -1)
++        if (file2str(PT->pidfd, "io", &ub) != -1)
+             io2proc(ub.buf, p);
+     }
+ 
+     if (flags & PROC_FILLSMAPS) {               // read /proc/#/smaps_rollup
+-        if (file2str(path, "smaps_rollup", &ub) != -1)
++        if (file2str(PT->pidfd, "smaps_rollup", &ub) != -1)
+             smaps2proc(ub.buf, p);
+     }
+ 
+     if (flags & PROC_FILLMEM) {                 // read /proc/#/statm
+-        if (file2str(path, "statm", &ub) != -1)
++        if (file2str(PT->pidfd, "statm", &ub) != -1)
+             statm2proc(ub.buf, p);
+     }
+ 
+     if (flags & PROC_FILLSTATUS) {              // read /proc/#/status
+-        if (file2str(path, "status", &ub) != -1){
++        if (file2str(PT->pidfd, "status", &ub) != -1){
+             rc += status2proc(ub.buf, p, 1);
+             if (flags & (PROC_FILL_SUPGRP & ~PROC_FILLSTATUS))
+                 rc += supgrps_from_supgids(p);
+@@ -1187,27 +1215,27 @@
+         p->egroup = pwcache_get_group(p->egid);
+ 
+     if (flags & PROC_FILLENV)                   // read /proc/#/environ
+-        if (!(p->environ_v = file2strvec(path, "environ")))
++        if (!(p->environ_v = file2strvec(PT->pidfd, "environ")))
+             rc += vectorize_dash_rc(&p->environ_v);
+     if (flags & PROC_EDITENVRCVT)
+-        rc += fill_environ_cvt(path, p);
++        rc += fill_environ_cvt(PT->pidfd, p);
+ 
+     if (flags & PROC_FILLARG)                   // read /proc/#/cmdline
+-        if (!(p->cmdline_v = file2strvec(path, "cmdline")))
++        if (!(p->cmdline_v = file2strvec(PT->pidfd, "cmdline")))
+             rc += vectorize_dash_rc(&p->cmdline_v);
+     if (flags & PROC_EDITCMDLCVT)
+-        rc += fill_cmdline_cvt(path, p);
++        rc += fill_cmdline_cvt(PT->pidfd, p);
+ 
+     if ((flags & PROC_FILLCGROUP))              // read /proc/#/cgroup
+-        if (!(p->cgroup_v = file2strvec(path, "cgroup")))
++        if (!(p->cgroup_v = file2strvec(PT->pidfd, "cgroup")))
+             rc += vectorize_dash_rc(&p->cgroup_v);
+     if (flags & PROC_EDITCGRPCVT)
+-        rc += fill_cgroup_cvt(path, p);
++        rc += fill_cgroup_cvt(PT->pidfd, p);
+ 
+     if (flags & PROC_FILLOOM) {
+-        if (file2str(path, "oom_score", &ub) != -1)
++        if (file2str(PT->pidfd, "oom_score", &ub) != -1)
+             oomscore2proc(ub.buf, p);
+-        if (file2str(path, "oom_score_adj", &ub) != -1)
++        if (file2str(PT->pidfd, "oom_score_adj", &ub) != -1)
+             oomadj2proc(ub.buf, p);
+     }
+ 
+@@ -1219,18 +1247,18 @@
+         rc += sd2proc(p);
+ 
+     if (flags & PROC_FILL_LXC)                  // value the lxc name
+-        p->lxcname = lxc_containers(path);
++        p->lxcname = lxc_containers(&ub);
+ 
+     if (flags & PROC_FILL_LUID)                 // value the login user id
+-        p->luid = login_uid(path);
++        p->luid = login_uid(PT->pidfd);
+ 
+     if (flags & PROC_FILL_EXE) {
+-        if (!(p->exe = readlink_exe(path)))
++        if (!(p->exe = readlink_exe(PT->pidfd)))
+             rc += 1;
+     }
+ 
+     if (flags & PROC_FILLAUTOGRP)               // value the 2 autogroup fields
+-        autogroup_fill(path, p);
++        autogroup_fill(PT->pidfd, p);
+ 
+     // openproc() ensured that a ppid will be present when needed ...
+     if (rc == 0) {
+@@ -1250,13 +1278,13 @@
+ // This reads /proc/*/task/* data, for one task.
+ // t is the POSIX thread  (task group member, generally not the leader)
+ // path is a path to the task, with some room to spare.
+-static proc_t *simple_readtask(PROCTAB *restrict const PT, proc_t *restrict const t, char *restrict const path) {
++static proc_t *simple_readtask(PROCTAB *restrict const PT, proc_t *restrict const t) {
+     static __thread struct utlbuf_s ub = { NULL, 0 };    // buf for stat,statm,status
+     static __thread struct stat sb;     // stat() buffer
+     unsigned flags = PT->flags;
+     int rc = 0;
+ 
+-    if (stat(path, &sb) == -1)                  /* no such dirent (anymore) */
++    if (fstat(PT->taskfd, &sb) == -1)                  /* no such dirent (anymore) */
+         goto next_task;
+ 
+ //  if ((flags & PROC_UID) && !XinLN(uid_t, sb.st_uid, PT->uids, PT->nuid))
+@@ -1266,28 +1294,28 @@
+     t->egid = sb.st_gid;                        /* need a way to get real gid */
+ 
+     if (flags & PROC_FILLSTAT) {                // read /proc/#/task/#/stat
+-        if (file2str(path, "stat", &ub) == -1)
++        if (file2str(PT->taskfd, "stat", &ub) == -1)
+             goto next_task;
+         rc += stat2proc(ub.buf, t);
+     }
+ 
+     if (flags & PROC_FILLIO) {                  // read /proc/#/task/#/io
+-        if (file2str(path, "io", &ub) != -1)
++        if (file2str(PT->taskfd, "io", &ub) != -1)
+             io2proc(ub.buf, t);
+     }
+ 
+     if (flags & PROC_FILLSMAPS) {               // read /proc/#/task/#/smaps_rollup
+-        if (file2str(path, "smaps_rollup", &ub) != -1)
++        if (file2str(PT->taskfd, "smaps_rollup", &ub) != -1)
+             smaps2proc(ub.buf, t);
+     }
+ 
+     if (flags & PROC_FILLMEM) {                 // read /proc/#/task/#/statm
+-        if (file2str(path, "statm", &ub) != -1)
++        if (file2str(PT->taskfd, "statm", &ub) != -1)
+             statm2proc(ub.buf, t);
+     }
+ 
+     if (flags & PROC_FILLSTATUS) {              // read /proc/#/task/#/status
+-        if (file2str(path, "status", &ub) != -1) {
++        if (file2str(PT->taskfd, "status", &ub) != -1) {
+             rc += status2proc(ub.buf, t, 0);
+             if (flags & (PROC_FILL_SUPGRP & ~PROC_FILLSTATUS))
+                 rc += supgrps_from_supgids(t);
+@@ -1315,28 +1343,28 @@
+     if (!IS_THREAD(t)) {
+ #endif
+     if (flags & PROC_FILLARG)                   // read /proc/#/task/#/cmdline
+-        if (!(t->cmdline_v = file2strvec(path, "cmdline")))
++        if (!(t->cmdline_v = file2strvec(PT->taskfd, "cmdline")))
+             rc += vectorize_dash_rc(&t->cmdline_v);
+     if (flags & PROC_EDITCMDLCVT)
+-        rc += fill_cmdline_cvt(path, t);
++        rc += fill_cmdline_cvt(PT->taskfd, t);
+ 
+     if (flags & PROC_FILLENV)                   // read /proc/#/task/#/environ
+-        if (!(t->environ_v = file2strvec(path, "environ")))
++        if (!(t->environ_v = file2strvec(PT->taskfd, "environ")))
+             rc += vectorize_dash_rc(&t->environ_v);
+     if (flags & PROC_EDITENVRCVT)
+-        rc += fill_environ_cvt(path, t);
++        rc += fill_environ_cvt(PT->taskfd, t);
+ 
+     if ((flags & PROC_FILLCGROUP))              // read /proc/#/task/#/cgroup
+-        if (!(t->cgroup_v = file2strvec(path, "cgroup")))
++        if (!(t->cgroup_v = file2strvec(PT->taskfd, "cgroup")))
+             rc += vectorize_dash_rc(&t->cgroup_v);
+     if (flags & PROC_EDITCGRPCVT)
+-        rc += fill_cgroup_cvt(path, t);
++        rc += fill_cgroup_cvt(PT->taskfd, t);
+ 
+     if (flags & PROC_FILLSYSTEMD)               // get sd-login.h stuff
+         rc += sd2proc(t);
+ 
+     if (flags & PROC_FILL_EXE) {
+-        if (!(t->exe = readlink_exe(path)))
++        if (!(t->exe = readlink_exe(PT->taskfd)))
+             rc += 1;
+     }
+ #ifdef FALSE_THREADS
+@@ -1344,22 +1372,22 @@
+ #endif
+ 
+     if (flags & PROC_FILLOOM) {
+-        if (file2str(path, "oom_score", &ub) != -1)
++        if (file2str(PT->taskfd, "oom_score", &ub) != -1)
+             oomscore2proc(ub.buf, t);
+-        if (file2str(path, "oom_score_adj", &ub) != -1)
++        if (file2str(PT->taskfd, "oom_score_adj", &ub) != -1)
+             oomadj2proc(ub.buf, t);
+     }
+     if (flags & PROC_FILLNS)                    // read /proc/#/task/#/ns/*
+         procps_ns_read_pid(t->tid, &(t->ns));
+ 
+     if (flags & PROC_FILL_LXC)
+-        t->lxcname = lxc_containers(path);
++        t->lxcname = lxc_containers(&ub);
+ 
+     if (flags & PROC_FILL_LUID)
+-        t->luid = login_uid(path);
++        t->luid = login_uid(PT->taskfd);
+ 
+     if (flags & PROC_FILLAUTOGRP)               // value the 2 autogroup fields
+-        autogroup_fill(path, t);
++        autogroup_fill(PT->taskfd, t);
+ 
+     // openproc() ensured that a ppid will be present when needed ...
+     if (rc == 0) {
+@@ -1380,7 +1408,10 @@
+ // Return non-zero on success.
+ static int simple_nextpid(PROCTAB *restrict const PT, proc_t *restrict const p) {
+     static __thread struct dirent *ent;   /* dirent handle */
+-    char *restrict const path = PT->path;
++    char path[PROCPATHLEN];
++
++    close_dirfd(&(PT->pidfd));
++    close_dirfd(&(PT->taskfd));
+     for (;;) {
+         ent = readdir(PT->procfs);
+         if (!ent || !ent->d_name[0]) break;
+@@ -1390,6 +1421,7 @@
+             if (errno == 0) {
+                 p->tid = p->tgid;
+                 snprintf(path, PROCPATHLEN, "/proc/%d", p->tgid);
++                PT->pidfd = open(path, O_RDONLY | O_DIRECTORY);
+                 return 1;
+             }
+         }
+@@ -1401,15 +1433,15 @@
+ //////////////////////////////////////////////////////////////////////////////////
+ // This finds tasks in /proc/*/task/ in the traditional way.
+ // Return non-zero on success.
+-static int simple_nexttid(PROCTAB *restrict const PT, const proc_t *restrict const p, proc_t *restrict const t, char *restrict const path) {
++static int simple_nexttid(PROCTAB *restrict const PT, const proc_t *restrict const p, proc_t *restrict const t) {
+   static __thread struct dirent *ent;   /* dirent handle */
++  char taskpath[PROCPATHLEN];
++
+   if(PT->taskdir_user != p->tgid){
+     if(PT->taskdir){
+       closedir(PT->taskdir);
+     }
+-    // use "path" as some tmp space
+-    snprintf(path, PROCPATHLEN, "/proc/%d/task", p->tgid);
+-    PT->taskdir = opendir(path);
++    PT->taskdir = opendirat(PT->pidfd, "task");
+     if(!PT->taskdir) return 0;
+     PT->taskdir_user = p->tgid;
+   }
+@@ -1421,7 +1453,9 @@
+   t->tid = strtoul(ent->d_name, NULL, 10);
+   t->tgid = p->tgid;
+ //t->ppid = p->ppid;  // cover for kernel behavior? we want both actually...?
+-  snprintf(path, PROCPATHLEN, "/proc/%d/task/%.10s", p->tgid, ent->d_name);
++  close_dirfd(&(PT->taskfd));
++  snprintf(taskpath, PROCPATHLEN, "task/%.10s", ent->d_name);
++  PT->taskfd = openat(PT->pidfd, taskpath, O_RDONLY | O_DIRECTORY);
+   return 1;
+ }
+ 
+@@ -1432,10 +1466,11 @@
+ static int listed_nextpid (PROCTAB *PT, proc_t *p) {
+   static __thread struct utlbuf_s ub = { NULL, 0 };
+   pid_t pid = *(PT->pids)++;
+-  char *path = PT->path;
++  char path[PROCPATHLEN];
+ 
+   if (pid) {
+     snprintf(path, PROCPATHLEN, "/proc/%d", pid);
++    PT->pidfd = open(path, O_RDONLY | O_DIRECTORY);
+     p->tid = p->tgid = pid;        // this tgid may be a huge fib |
+ 
+     /* the 'status' directory is the only place where we find the |
+@@ -1443,7 +1478,7 @@
+        dealing with fewer processes, unlike the other 'next' guys |
+        (plus we need not parse the whole thing like status2proc)! | */
+ 
+-    if (file2str(path, "status", &ub) != -1) {
++    if (file2str(PT->pidfd, "status", &ub) != -1) {
+       char *str = strstr(ub.buf, "Tgid:");
+       if (str)
+         p->tgid = atoi(str + 5);   // this tgid is the proper one |
+@@ -1470,7 +1505,7 @@
+   free_acquired(p);
+ 
+   for(;;){
+-    // fills in the path, plus p->tid and p->tgid
++    // fills in p->tid and p->tgid
+     if (!PT->finder(PT,p)) goto out;
+ 
+     // go read the process data
+@@ -1491,7 +1526,6 @@
+     static __thread proc_t skel_p;    // skeleton proc_t, only uses tid + tgid
+     static __thread proc_t *new_p;    // for process/task transitions
+     static __thread int canary;
+-    char path[PROCPATHLEN];
+     proc_t *ret;
+ 
+     free_acquired(x);
+@@ -1504,7 +1538,7 @@
+ next_proc:
+     new_p = NULL;
+     for (;;) {
+-        // fills in the PT->path, plus skel_p.tid and skel_p.tgid
++        // fills in the skel_p.tid and skel_p.tgid
+         if (!PT->finder(PT,&skel_p)) goto end_procs;       // simple_nextpid
+         if (!task_dir_missing) break;
+         if ((ret = PT->reader(PT,x))) return ret;          // simple_readproc
+@@ -1512,8 +1546,8 @@
+ 
+ next_task:
+     // fills in our path, plus x->tid and x->tgid
+-    if ((!(PT->taskfinder(PT,&skel_p,x,path)))             // simple_nexttid
+-    || (!(ret = PT->taskreader(PT,x,path)))) {             // simple_readtask
++    if ((!(PT->taskfinder(PT,&skel_p,x)))             // simple_nexttid
++    || (!(ret = PT->taskreader(PT,x)))) {             // simple_readtask
+         goto next_proc;
+     }
+     if (!new_p) {
+@@ -1545,8 +1579,10 @@
+         task_dir_missing = stat("/proc/self/task", &sbuf);
+         did_stat = 1;
+     }
++    PT->pidfd = -1;
+     PT->taskdir = NULL;
+     PT->taskdir_user = -1;
++    PT->taskfd = -1;
+     PT->taskfinder = simple_nexttid;
+     PT->taskreader = simple_readtask;
+ 
+@@ -1611,13 +1647,16 @@
+     struct utlbuf_s ub = { NULL, 0 };
+     int rc = 0;
+     proc_t p;
++    int fd;
+ 
+     memset(&p, 0, sizeof(proc_t));
+-    if(file2str("/proc/self", "stat", &ub) == -1){
++    fd = open("/proc/self", O_PATH|O_DIRECTORY);
++    if(fd < 0 || file2str(fd, "stat", &ub) == -1){
+         fprintf(stderr, "Error, do this: mount -t proc proc /proc\n");
+         _exit(47);
+     }
+     rc = stat2proc(ub.buf, &p); // parse /proc/self/stat
++    close(fd);
+     free_acquired(&p);
+     free(ub.buf);
+     return !rc;
diff -pruN 2:4.0.4-8/debian/patches/series 2:4.0.4-8ubuntu3/debian/patches/series
--- 2:4.0.4-8/debian/patches/series	2025-04-14 08:06:27.000000000 +0000
+++ 2:4.0.4-8ubuntu3/debian/patches/series	2025-08-29 10:58:29.000000000 +0000
@@ -21,3 +21,8 @@ library_0_days_users
 library_lxc_leak
 sysctl_conf5_update
 library_use_clock_gettime
+ignore_eaccess.patch
+ignore_erofs.patch
+0010-testsuite-ps-etime-ELAPSED-doesn-t-match-full-format.patch
+lp2120904-openat.patch
+lp2120904-nullpointer.patch
diff -pruN 2:4.0.4-8/debian/procps.install 2:4.0.4-8ubuntu3/debian/procps.install
--- 2:4.0.4-8/debian/procps.install	2025-04-14 08:06:27.000000000 +0000
+++ 2:4.0.4-8ubuntu3/debian/procps.install	2025-08-29 10:58:29.000000000 +0000
@@ -1,5 +1,6 @@
 # Files to install for non-kfreebsd and non-hurd systems
 # I think that just means linux
+usr/lib/sysctl.d/*
 debian/README.sysctl etc/sysctl.d
 usr/bin
 usr/sbin/sysctl usr/sbin
diff -pruN 2:4.0.4-8/debian/procps.maintscript 2:4.0.4-8ubuntu3/debian/procps.maintscript
--- 2:4.0.4-8/debian/procps.maintscript	2025-04-14 08:06:27.000000000 +0000
+++ 2:4.0.4-8ubuntu3/debian/procps.maintscript	2025-08-29 10:58:29.000000000 +0000
@@ -1 +1,12 @@
 rm_conffile /etc/sysctl.conf 2:4.0.4-7~
+
+mv_conffile /etc/sysctl.d/10-bufferbloat.conf /usr/lib/sysctl.d/55-bufferbloat.conf 2:4.0.4-8ubuntu1~
+mv_conffile /etc/sysctl.d/10-console-messages.conf /usr/lib/sysctl.d/55-console-messages.conf 2:4.0.4-8ubuntu1~
+mv_conffile /etc/sysctl.d/10-ipv6-privacy.conf /usr/lib/sysctl.d/55-ipv6-privacy.conf 2:4.0.4-8ubuntu1~
+mv_conffile /etc/sysctl.d/10-kernel-hardening.conf /usr/lib/sysctl.d/55-kernel-hardening.conf 2:4.0.4-8ubuntu1~
+mv_conffile /etc/sysctl.d/10-magic-sysrq.conf /usr/lib/sysctl.d/55-magic-sysrq.conf 2:4.0.4-8ubuntu1~
+mv_conffile /etc/sysctl.d/10-map-count.conf /usr/lib/sysctl.d/55-map-count.conf 2:4.0.4-8ubuntu1~
+mv_conffile /etc/sysctl.d/10-network-security.conf /usr/lib/sysctl.d/55-network-security.conf 2:4.0.4-8ubuntu1~
+mv_conffile /etc/sysctl.d/10-ptrace.conf /usr/lib/sysctl.d/55-ptrace.conf 2:4.0.4-8ubuntu1~
+mv_conffile /etc/sysctl.d/10-qemu.conf /usr/lib/sysctl.d/55-qemu.conf 2:4.0.4-8ubuntu1~
+mv_conffile /etc/sysctl.d/10-zeropage.conf /usr/lib/sysctl.d/55-zeropage.conf 2:4.0.4-8ubuntu1~
diff -pruN 2:4.0.4-8/debian/rules 2:4.0.4-8ubuntu3/debian/rules
--- 2:4.0.4-8/debian/rules	2025-04-14 08:06:27.000000000 +0000
+++ 2:4.0.4-8ubuntu3/debian/rules	2025-08-29 10:58:29.000000000 +0000
@@ -48,6 +48,23 @@ override_dh_auto_configure:
 override_dh_auto_install: $(autogen-files)
 	dh_auto_install
 
+	# Build up sysctl.d
+	install -d $(DEBROOT)/usr/lib/sysctl.d/
+	install --mode 644 debian/sysctl.d/*.conf $(DEBROOT)/usr/lib/sysctl.d/
+ifneq (,$(wildcard debian/sysctl.d/*.conf.$(DEB_HOST_ARCH)))
+	# If a non-arch-specific default exists, install the arch-specific
+	# version of the conf in place of it, otherwise, build up a general
+	# 10-arch-specific.conf file.
+	for archconf in debian/sysctl.d/*.conf.$(DEB_HOST_ARCH); do \
+	    conf=$$(basename $$archconf .$(DEB_HOST_ARCH)); \
+	    if [ -f debian/sysctl.d/$$conf ]; then \
+		install --mode 644 $$archconf $(DEBROOT)/usr/lib/sysctl.d/$$conf; \
+	    else \
+		cat $$archconf >> $(DEBROOT)/usr/lib/sysctl.d/10-arch-specific.conf; \
+	    fi; \
+	done
+endif
+
 ifneq ($(DEB_HOST_ARCH_OS), linux)
 	rm -f \
 		$(DEBROOT)/bin/slabtop \
diff -pruN 2:4.0.4-8/debian/sysctl.d/55-bufferbloat.conf 2:4.0.4-8ubuntu3/debian/sysctl.d/55-bufferbloat.conf
--- 2:4.0.4-8/debian/sysctl.d/55-bufferbloat.conf	1970-01-01 00:00:00.000000000 +0000
+++ 2:4.0.4-8ubuntu3/debian/sysctl.d/55-bufferbloat.conf	2025-08-29 10:58:29.000000000 +0000
@@ -0,0 +1,8 @@
+# The Fair Queue CoDel packet scheduler is an across the board improvement to
+# the default pfifo_fast qdisc. It reduces bottleneck delays, provides accurate
+# RTT estimates to elephant TCP flows, and still allows shorter (sparser) flows
+# like DNS, ARP, SYN, routing, etc packets priority access. For technical
+# details, refer to https://www.bufferbloat.net/projects/codel/wiki/
+#
+# To fight bufferbloat, set it as the default qdisc in Ubuntu.
+-net.core.default_qdisc = fq_codel
diff -pruN 2:4.0.4-8/debian/sysctl.d/55-console-messages.conf 2:4.0.4-8ubuntu3/debian/sysctl.d/55-console-messages.conf
--- 2:4.0.4-8/debian/sysctl.d/55-console-messages.conf	1970-01-01 00:00:00.000000000 +0000
+++ 2:4.0.4-8ubuntu3/debian/sysctl.d/55-console-messages.conf	2025-08-29 10:58:29.000000000 +0000
@@ -0,0 +1,3 @@
+
+# the following stops low-level messages on console
+kernel.printk = 4 4 1 7
diff -pruN 2:4.0.4-8/debian/sysctl.d/55-ipv6-privacy.conf 2:4.0.4-8ubuntu3/debian/sysctl.d/55-ipv6-privacy.conf
--- 2:4.0.4-8/debian/sysctl.d/55-ipv6-privacy.conf	1970-01-01 00:00:00.000000000 +0000
+++ 2:4.0.4-8ubuntu3/debian/sysctl.d/55-ipv6-privacy.conf	2025-08-29 10:58:29.000000000 +0000
@@ -0,0 +1,12 @@
+# IPv6 Privacy Extensions (RFC 4941)
+# ---
+# IPv6 typically uses a device's MAC address when choosing an IPv6 address
+# to use in autoconfiguration. Privacy extensions allow using a randomly
+# generated IPv6 address, which increases privacy.
+#
+# Acceptable values:
+#    0 - don’t use privacy extensions.
+#    1 - generate privacy addresses
+#    2 - prefer privacy addresses and use them over the normal addresses.
+net.ipv6.conf.all.use_tempaddr = 2
+net.ipv6.conf.default.use_tempaddr = 2
diff -pruN 2:4.0.4-8/debian/sysctl.d/55-kernel-hardening.conf 2:4.0.4-8ubuntu3/debian/sysctl.d/55-kernel-hardening.conf
--- 2:4.0.4-8/debian/sysctl.d/55-kernel-hardening.conf	1970-01-01 00:00:00.000000000 +0000
+++ 2:4.0.4-8ubuntu3/debian/sysctl.d/55-kernel-hardening.conf	2025-08-29 10:58:29.000000000 +0000
@@ -0,0 +1,25 @@
+# These settings are specific to hardening the kernel itself from attack
+# from userspace, rather than protecting userspace from other malicious
+# userspace things.
+#
+#
+# When an attacker is trying to exploit the local kernel, it is often
+# helpful to be able to examine where in memory the kernel, modules,
+# and data structures live. As such, kernel addresses should be treated
+# as sensitive information.
+#
+# Many files and interfaces contain these addresses (e.g. /proc/kallsyms,
+# /proc/modules, etc), and this setting can censor the addresses. A value
+# of "0" allows all users to see the kernel addresses. A value of "1"
+# limits visibility to the root user, and "2" blocks even the root user.
+kernel.kptr_restrict = 1
+
+# Access to the kernel log buffer can be especially useful for an attacker
+# attempting to exploit the local kernel, as kernel addresses and detailed
+# call traces are frequently found in kernel oops messages. Setting
+# dmesg_restrict to "0" allows all users to view the kernel log buffer,
+# and setting it to "1" restricts access to those with CAP_SYSLOG.
+#
+# dmesg_restrict defaults to 1 via CONFIG_SECURITY_DMESG_RESTRICT, only
+# uncomment the following line to disable.
+# kernel.dmesg_restrict = 0
diff -pruN 2:4.0.4-8/debian/sysctl.d/55-magic-sysrq.conf 2:4.0.4-8ubuntu3/debian/sysctl.d/55-magic-sysrq.conf
--- 2:4.0.4-8/debian/sysctl.d/55-magic-sysrq.conf	1970-01-01 00:00:00.000000000 +0000
+++ 2:4.0.4-8ubuntu3/debian/sysctl.d/55-magic-sysrq.conf	2025-08-29 10:58:29.000000000 +0000
@@ -0,0 +1,26 @@
+# The magic SysRq key enables certain keyboard combinations to be
+# interpreted by the kernel to help with debugging. The kernel will respond
+# to these keys regardless of the current running applications.
+#
+# In general, the magic SysRq key is not needed for the average Ubuntu
+# system, and having it enabled by default can lead to security issues on
+# the console such as being able to dump memory or to kill arbitrary
+# processes including the running screen lock.
+#
+# Here is the list of possible values:
+#   0 - disable sysrq completely
+#   1 - enable all functions of sysrq
+#  >1 - enable certain functions by adding up the following values:
+#          2 - enable control of console logging level
+#          4 - enable control of keyboard (SAK, unraw)
+#          8 - enable debugging dumps of processes etc.
+#         16 - enable sync command
+#         32 - enable remount read-only
+#         64 - enable signalling of processes (term, kill, oom-kill)
+#        128 - allow reboot/poweroff
+#        256 - allow nicing of all RT tasks
+#
+#   For example, to enable both control of console logging level and
+#   debugging dumps of processes: kernel.sysrq = 10
+#
+kernel.sysrq = 176
diff -pruN 2:4.0.4-8/debian/sysctl.d/55-map-count.conf 2:4.0.4-8ubuntu3/debian/sysctl.d/55-map-count.conf
--- 2:4.0.4-8/debian/sysctl.d/55-map-count.conf	1970-01-01 00:00:00.000000000 +0000
+++ 2:4.0.4-8ubuntu3/debian/sysctl.d/55-map-count.conf	2025-08-29 10:58:29.000000000 +0000
@@ -0,0 +1,3 @@
+# Increase the number of virtual memory areas that one process may request
+# https://bugs.launchpad.net/ubuntu/+source/procps/+bug/2057792
+vm.max_map_count=1048576
diff -pruN 2:4.0.4-8/debian/sysctl.d/55-network-security.conf 2:4.0.4-8ubuntu3/debian/sysctl.d/55-network-security.conf
--- 2:4.0.4-8/debian/sysctl.d/55-network-security.conf	1970-01-01 00:00:00.000000000 +0000
+++ 2:4.0.4-8ubuntu3/debian/sysctl.d/55-network-security.conf	2025-08-29 10:58:29.000000000 +0000
@@ -0,0 +1,6 @@
+
+# Turn on Source Address Verification in all interfaces to
+# prevent some spoofing attacks.
+net.ipv4.conf.default.rp_filter=2
+net.ipv4.conf.all.rp_filter=2
+
diff -pruN 2:4.0.4-8/debian/sysctl.d/55-ptrace.conf 2:4.0.4-8ubuntu3/debian/sysctl.d/55-ptrace.conf
--- 2:4.0.4-8/debian/sysctl.d/55-ptrace.conf	1970-01-01 00:00:00.000000000 +0000
+++ 2:4.0.4-8ubuntu3/debian/sysctl.d/55-ptrace.conf	2025-08-29 10:58:29.000000000 +0000
@@ -0,0 +1,22 @@
+# The PTRACE system is used for debugging.  With it, a single user process
+# can attach to any other dumpable process owned by the same user.  In the
+# case of malicious software, it is possible to use PTRACE to access
+# credentials that exist in memory (re-using existing SSH connections,
+# extracting GPG agent information, etc).
+#
+# A PTRACE scope of "0" is the more permissive mode.  A scope of "1" limits
+# PTRACE only to direct child processes (e.g. "gdb name-of-program" and
+# "strace -f name-of-program" work, but gdb's "attach" and "strace -fp $PID"
+# do not).  The PTRACE scope is ignored when a user has CAP_SYS_PTRACE, so
+# "sudo strace -fp $PID" will work as before.  For more details see:
+# https://wiki.ubuntu.com/SecurityTeam/Roadmap/KernelHardening#ptrace
+#
+# For applications launching crash handlers that need PTRACE, exceptions can
+# be registered by the debugee by declaring in the segfault handler
+# specifically which process will be using PTRACE on the debugee:
+#   prctl(PR_SET_PTRACER, debugger_pid, 0, 0, 0);
+#
+# In general, PTRACE is not needed for the average running Ubuntu system.
+# To that end, the default is to set the PTRACE scope to "1".  This value
+# may not be appropriate for developers or servers with only admin accounts.
+kernel.yama.ptrace_scope = 1
diff -pruN 2:4.0.4-8/debian/sysctl.d/55-qemu.conf.s390x 2:4.0.4-8ubuntu3/debian/sysctl.d/55-qemu.conf.s390x
--- 2:4.0.4-8/debian/sysctl.d/55-qemu.conf.s390x	1970-01-01 00:00:00.000000000 +0000
+++ 2:4.0.4-8ubuntu3/debian/sysctl.d/55-qemu.conf.s390x	2025-08-29 10:58:29.000000000 +0000
@@ -0,0 +1,2 @@
+# for qemu-system
+vm.allocate_pgste = 1
diff -pruN 2:4.0.4-8/debian/sysctl.d/55-zeropage.conf 2:4.0.4-8ubuntu3/debian/sysctl.d/55-zeropage.conf
--- 2:4.0.4-8/debian/sysctl.d/55-zeropage.conf	1970-01-01 00:00:00.000000000 +0000
+++ 2:4.0.4-8ubuntu3/debian/sysctl.d/55-zeropage.conf	2025-08-29 10:58:29.000000000 +0000
@@ -0,0 +1,9 @@
+# Protect the zero page of memory from userspace mmap to prevent kernel
+# NULL-dereference attacks against potential future kernel security
+# vulnerabilities.  (Added in kernel 2.6.23.)
+#
+# While this default is built into the Ubuntu kernel, there is no way to
+# restore the kernel default if the value is changed during runtime; for
+# example via package removal (e.g. wine, dosemu).  Therefore, this value
+# is reset to the secure default each time the sysctl values are loaded.
+vm.mmap_min_addr = 65536
diff -pruN 2:4.0.4-8/debian/sysctl.d/55-zeropage.conf.arm64 2:4.0.4-8ubuntu3/debian/sysctl.d/55-zeropage.conf.arm64
--- 2:4.0.4-8/debian/sysctl.d/55-zeropage.conf.arm64	1970-01-01 00:00:00.000000000 +0000
+++ 2:4.0.4-8ubuntu3/debian/sysctl.d/55-zeropage.conf.arm64	2025-08-29 10:58:29.000000000 +0000
@@ -0,0 +1,11 @@
+# Protect the zero page of memory from userspace mmap to prevent kernel
+# NULL-dereference attacks against potential future kernel security
+# vulnerabilities.  (Added in kernel 2.6.23.)
+#
+# While this default is built into the Ubuntu kernel, there is no way to
+# restore the kernel default if the value is changed during runtime; for
+# example via package removal (e.g. wine, dosemu).  Therefore, this value
+# is reset to the secure default each time the sysctl values are loaded.
+#
+# ARM-specific default:
+vm.mmap_min_addr = 32768
diff -pruN 2:4.0.4-8/debian/sysctl.d/55-zeropage.conf.armhf 2:4.0.4-8ubuntu3/debian/sysctl.d/55-zeropage.conf.armhf
--- 2:4.0.4-8/debian/sysctl.d/55-zeropage.conf.armhf	1970-01-01 00:00:00.000000000 +0000
+++ 2:4.0.4-8ubuntu3/debian/sysctl.d/55-zeropage.conf.armhf	2025-08-29 10:58:29.000000000 +0000
@@ -0,0 +1,11 @@
+# Protect the zero page of memory from userspace mmap to prevent kernel
+# NULL-dereference attacks against potential future kernel security
+# vulnerabilities.  (Added in kernel 2.6.23.)
+#
+# While this default is built into the Ubuntu kernel, there is no way to
+# restore the kernel default if the value is changed during runtime; for
+# example via package removal (e.g. wine, dosemu).  Therefore, this value
+# is reset to the secure default each time the sysctl values are loaded.
+#
+# ARM-specific default:
+vm.mmap_min_addr = 32768
diff -pruN 2:4.0.4-8/debian/tests/control 2:4.0.4-8ubuntu3/debian/tests/control
--- 2:4.0.4-8/debian/tests/control	2025-04-14 08:06:27.000000000 +0000
+++ 2:4.0.4-8ubuntu3/debian/tests/control	2025-08-29 10:58:29.000000000 +0000
@@ -1,2 +1,10 @@
 Tests: version free pgrep pmap ps pwdx uptime vmstat w
 Depends: @, shunit2
+
+Tests: stack-limit
+Restrictions: superficial
+
+Test-Command: /usr/lib/systemd/systemd-sysctl --cat-config && pytest debian/tests/test_sysctl_defaults.py
+Depends: @, python3-pytest
+Features: test-name=sysctl-defaults
+Restrictions: isolation-machine
diff -pruN 2:4.0.4-8/debian/tests/stack-limit 2:4.0.4-8ubuntu3/debian/tests/stack-limit
--- 2:4.0.4-8/debian/tests/stack-limit	1970-01-01 00:00:00.000000000 +0000
+++ 2:4.0.4-8ubuntu3/debian/tests/stack-limit	2025-08-29 10:58:29.000000000 +0000
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+set -e
+
+# set the stack size to unlimited and then run pgrep
+ulimit -S -s unlimited
+
+pgrep systemd
diff -pruN 2:4.0.4-8/debian/tests/test_sysctl_defaults.py 2:4.0.4-8ubuntu3/debian/tests/test_sysctl_defaults.py
--- 2:4.0.4-8/debian/tests/test_sysctl_defaults.py	1970-01-01 00:00:00.000000000 +0000
+++ 2:4.0.4-8ubuntu3/debian/tests/test_sysctl_defaults.py	2025-08-29 10:58:29.000000000 +0000
@@ -0,0 +1,75 @@
+import os
+import pathlib
+import pytest
+import subprocess
+
+
+def expected_sysctl_defaults():
+    """
+    Inspect sysctl.d snippets shipped by procps to gather expected settings.
+    """
+    expected = []
+
+    arch = subprocess.check_output(
+        ['dpkg', '--print-architecture']
+    ).decode().strip()
+
+    paths = [
+        f.strip() for f in subprocess.check_output(
+            ['dpkg', '-L', 'procps']
+        ).decode().splitlines()
+    ]
+
+    for path in paths:
+        p = pathlib.Path(path)
+
+        if not p.is_file():
+            continue
+
+        if not p.match('*/sysctl.d/*'):
+            continue
+
+        if p.suffix not in ('.conf', f'.{arch}'):
+            # arch-specific config, not for this arch
+            continue
+
+        with p.open() as conf:
+            lines = [line.strip() for line in conf.readlines()]
+
+        for line in lines:
+            if not line or line.startswith('#'):
+                continue
+
+            (key, _, value) = line.partition('=')
+
+            expected.append((key.strip().lstrip('-'), value.strip()))
+
+    return expected
+
+
+@pytest.mark.parametrize("key, expected", expected_sysctl_defaults())
+def test_sysctl_defaults(key, expected):
+    # If the sysctl key does not exist, skip the test.
+    if not os.path.exists(f'/proc/sys/{key}'.replace('.', '/')):
+        pytest.skip(f'{key} does not exist on this system, ignoring')
+
+    actual = subprocess.check_output(['sysctl', '-n', key])
+    actual = actual.decode().strip()
+    actual = ' '.join(actual.split())
+
+    # Due to LP: #1068756, cloud images ship /etc/sysctl.d/cloudimg-ipv6.conf
+    # which overrides procps's defaults for net.ipv6.conf.{all,default}.use_tempaddr.
+    #
+    # If that override exists, expect a failure for those settings.
+    if (
+        os.path.exists('/etc/sysctl.d/99-cloudimg-ipv6.conf') and
+        key in (
+            'net.ipv6.conf.all.use_tempaddr',
+            'net.ipv6.conf.default.use_tempaddr',
+        )
+    ):
+        pytest.xfail(
+            f'/etc/systctl.d/99-cloudimg-ipv6.conf overrides {key}'
+        )
+
+    assert actual == expected
