diff -Nru systemd-247.3/debian/changelog systemd-247.3/debian/changelog
--- systemd-247.3/debian/changelog	2024-08-25 16:05:15.000000000 -0300
+++ systemd-247.3/debian/changelog	2025-06-25 21:44:53.000000000 -0300
@@ -1,3 +1,12 @@
+systemd (247.3-7+deb11u7) bullseye-security; urgency=medium
+
+  * Non-maintainer upload by the LTS Team.
+  * debian/patches/CVE-2025-4598-{0,1,2,3,4}.patch: import and backport
+    patches from upstream to fix CVE-2025-4598.
+  * debian/salsa-ci.yml: add (E)LTS pipeline for bullseye.
+
+ -- Carlos Henrique Lima Melara <charlesmelara@riseup.net>  Wed, 25 Jun 2025 21:44:53 -0300
+
 systemd (247.3-7+deb11u6) bullseye-security; urgency=medium
 
   * Non-maintainer upload by the LTS Team.
diff -Nru systemd-247.3/debian/patches/CVE-2025-4598-0.patch systemd-247.3/debian/patches/CVE-2025-4598-0.patch
--- systemd-247.3/debian/patches/CVE-2025-4598-0.patch	1969-12-31 21:00:00.000000000 -0300
+++ systemd-247.3/debian/patches/CVE-2025-4598-0.patch	2025-06-25 21:44:53.000000000 -0300
@@ -0,0 +1,88 @@
+From: =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Tue, 29 Apr 2025 14:47:59 +0200
+Subject: coredump: restore compatibility with older patterns
+
+This was broken in f45b8015513d38ee5f7cc361db9c5b88c9aae704. Unfortunately
+the review does not talk about backward compatibility at all. There are
+two places where it matters:
+- During upgrades, the replacement of kernel.core_pattern is asynchronous.
+  For example, during rpm upgrades, it would be updated a post-transaction
+  file trigger. In other scenarios, the update might only happen after
+  reboot. We have a potentially long window where the old pattern is in
+  place. We need to capture coredumps during upgrades too.
+- With --backtrace. The interface of --backtrace, in hindsight, is not
+  great. But there are users of --backtrace which were written to use
+  a specific set of arguments, and we can't just break compatiblity.
+  One example is systemd-coredump-python, but there are also reports of
+  users using --backtrace to generate coredump logs.
+
+Thus, we require the original set of args, and will use the additional args if
+found.
+
+A test is added to verify that --backtrace works with and without the optional
+args.
+
+(cherry picked from commit ded0aac389e647d35bce7ec4a48e718d77c0435b)
+(cherry picked from commit f9b8b75c11bba9b63096904be98cc529c304eb97)
+(cherry picked from commit 385a33b043406ad79a7207f3906c3b15192a3333)
+(cherry picked from commit c6f79626b6d175c6a5b62b8c5d957a83eb882301)
+(cherry picked from commit 9f02346d50e33c24acf879ce4dd5937d56473325)
+(cherry picked from commit ac0aa5d1fdc21db1ef035fce562cb6fc8602b544)
+
+Origin: upstream, https://github.com/systemd/systemd-stable/commit/cadd1b1a1f39fd13b1115a10f563017201d7b56a
+Forwarded: not-needed
+Last-Update: 2025-06-23
+---
+ src/coredump/coredump.c | 21 ++++++++++++++-------
+ 1 file changed, 14 insertions(+), 7 deletions(-)
+
+diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c
+index b60dff3..a5fcb94 100644
+--- a/src/coredump/coredump.c
++++ b/src/coredump/coredump.c
+@@ -81,8 +81,12 @@ enum {
+         META_ARGV_SIGNAL,       /* %s: number of signal causing dump */
+         META_ARGV_TIMESTAMP,    /* %t: time of dump, expressed as seconds since the Epoch (we expand this to µs granularity) */
+         META_ARGV_RLIMIT,       /* %c: core file size soft resource limit */
+-        META_ARGV_HOSTNAME,     /* %h: hostname */
++        _META_ARGV_REQUIRED,
++        /* The fields below were added to kernel/core_pattern at later points, so they might be missing. */
++        META_ARGV_HOSTNAME = _META_ARGV_REQUIRED,  /* %h: hostname */
+         _META_ARGV_MAX,
++        /* If new fields are added, they should be added here, to maintain compatibility
++         * with callers which don't know about the new fields. */
+
+         /* The following indexes are cached for a couple of special fields we use (and
+          * thereby need to be retrieved quickly) for naming coredump files, and attaching
+@@ -93,7 +97,7 @@ enum {
+         _META_MANDATORY_MAX,
+
+         /* The rest are similar to the previous ones except that we won't fail if one of
+-         * them is missing. */
++         * them is missing in a message sent over the socket. */
+
+         META_EXE = _META_MANDATORY_MAX,
+         META_UNIT,
+@@ -1182,14 +1186,17 @@ static int gather_pid_metadata_from_argv(
+         char *t;
+
+         /* We gather all metadata that were passed via argv[] into an array of iovecs that
+-         * we'll forward to the socket unit */
++         * we'll forward to the socket unit.
++         *
++         * We require at least _META_ARGV_REQUIRED args, but will accept more.
++         * We know how to parse _META_ARGV_MAX args. The rest will be ignored. */
+
+-        if (argc < _META_ARGV_MAX)
++        if (argc < _META_ARGV_REQUIRED)
+                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+-                                       "Not enough arguments passed by the kernel (%i, expected %i).",
+-                                       argc, _META_ARGV_MAX);
++                                       "Not enough arguments passed by the kernel (%i, expected between %i and %i).",
++                                       argc, _META_ARGV_REQUIRED, _META_ARGV_MAX);
+
+-        for (i = 0; i < _META_ARGV_MAX; i++) {
++        for (i = 0; i < MIN(argc, _META_ARGV_MAX); i++) {
+
+                 t = argv[i];
+
diff -Nru systemd-247.3/debian/patches/CVE-2025-4598-1.patch systemd-247.3/debian/patches/CVE-2025-4598-1.patch
--- systemd-247.3/debian/patches/CVE-2025-4598-1.patch	1969-12-31 21:00:00.000000000 -0300
+++ systemd-247.3/debian/patches/CVE-2025-4598-1.patch	2025-06-25 21:44:53.000000000 -0300
@@ -0,0 +1,33 @@
+From c288a3aafdf11cd93eb7a21e4d587c6fc218a29c Mon Sep 17 00:00:00 2001
+From: Dan Streetman <ddstreet@ieee.org>
+Date: Thu, 2 Feb 2023 15:58:10 -0500
+Subject: [PATCH] basic/macro: add macro to iterate variadic args
+
+(cherry picked from commit e179f2d89c9f0c951636d74de00136b4075cd1ac)
+(cherry picked from commit cd4f43bf378ff33ce5cfeacd96f7f3726603bddc)
+
+Origin: upstream, https://github.com/systemd/systemd-stable/commit/c288a3aafdf11cd93eb7a21e4d587c6fc218a29c
+Forwarded: not-needed
+Last-Update: 2025-06-23
+---
+ src/basic/macro.h | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/src/basic/macro.h b/src/basic/macro.h
+index 2782553..ee83541 100644
+--- a/src/basic/macro.h
++++ b/src/basic/macro.h
+@@ -654,4 +654,13 @@ static inline size_t size_add(size_t x, size_t y) {
+         return y >= SIZE_MAX - x ? SIZE_MAX : x + y;
+ }
+ 
++/* Iterate through each variadic arg. All must be the same type as 'entry' or must be implicitly
++ * convertable. The iteration variable 'entry' must already be defined. */
++#define VA_ARGS_FOREACH(entry, ...)                                     \
++        _VA_ARGS_FOREACH(entry, UNIQ_T(_entries_, UNIQ), UNIQ_T(_current_, UNIQ), ##__VA_ARGS__)
++#define _VA_ARGS_FOREACH(entry, _entries_, _current_, ...)         \
++        for (typeof(entry) _entries_[] = { __VA_ARGS__ }, *_current_ = _entries_; \
++             ((long)(_current_ - _entries_) < (long)ELEMENTSOF(_entries_)) && ({ entry = *_current_; true; }); \
++             _current_++)
++
+ #include "log.h"
diff -Nru systemd-247.3/debian/patches/CVE-2025-4598-2.patch systemd-247.3/debian/patches/CVE-2025-4598-2.patch
--- systemd-247.3/debian/patches/CVE-2025-4598-2.patch	1969-12-31 21:00:00.000000000 -0300
+++ systemd-247.3/debian/patches/CVE-2025-4598-2.patch	2025-06-25 21:44:53.000000000 -0300
@@ -0,0 +1,74 @@
+From 31ba3f4ea0f472355e985c7bcca66ffc35e5735c Mon Sep 17 00:00:00 2001
+From: Frantisek Sumsal <frantisek@sumsal.cz>
+Date: Wed, 17 Jan 2024 13:11:14 +0100
+Subject: [PATCH] macro: terminate the temporary VA_ARGS_FOREACH() array with a
+ sentinel
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+So gcc-14 doesn't complain we're out of bounds on the last iteration:
+
+[2092/2414] Compiling C object test-macro.p/src_test_test-macro.c.o
+In file included from ../src/basic/list.h:209,
+                 from ../src/basic/log.h:10,
+                 from ../src/test/test-macro.c:5:
+../src/test/test-macro.c: In function ‘test_FOREACH_VA_ARGS’:
+../src/basic/macro.h:395:90: warning: array subscript 1 is outside array bounds of ‘uint8_t[1]’ {aka ‘unsigned char[1]’} [-Warray-bounds=]
+  395 |              ((long)(_current_ - _entries_) < (long)ELEMENTSOF(_entries_)) && ({ entry = *_current_; true; }); \
+../src/basic/macro.h:392:9: note: in expansion of macro ‘_VA_ARGS_FOREACH’
+  392 |         _VA_ARGS_FOREACH(entry, UNIQ_T(_entries_, UNIQ), UNIQ_T(_current_, UNIQ), ##__VA_ARGS__)
+      |         ^~~~~~~~~~~~~~~~
+../src/test/test-macro.c:322:9: note: in expansion of macro ‘VA_ARGS_FOREACH’
+  322 |         VA_ARGS_FOREACH(u8, 0) {
+      |         ^~~~~~~~~~~~~~~
+../src/fundamental/macro-fundamental.h:163:37: note: at offset 1 into object ‘__unique_prefix__entries_181’ of size 1
+  163 | #define UNIQ_T(x, uniq) CONCATENATE(__unique_prefix_, CONCATENATE(x, uniq))
+      |                                     ^~~~~~~~~~~~~~~~
+../src/basic/macro.h:394:28: note: in definition of macro ‘_VA_ARGS_FOREACH’
+  394 |         for (typeof(entry) _entries_[] = { __VA_ARGS__ }, *_current_ = _entries_; \
+      |                            ^~~~~~~~~
+../src/fundamental/macro-fundamental.h:109:27: note: in expansion of macro ‘XCONCATENATE’
+  109 | #define CONCATENATE(x, y) XCONCATENATE(x, y)
+      |                           ^~~~~~~~~~~~
+../src/fundamental/macro-fundamental.h:163:25: note: in expansion of macro ‘CONCATENATE’
+  163 | #define UNIQ_T(x, uniq) CONCATENATE(__unique_prefix_, CONCATENATE(x, uniq))
+      |                         ^~~~~~~~~~~
+../src/basic/macro.h:392:33: note: in expansion of macro ‘UNIQ_T’
+  392 |         _VA_ARGS_FOREACH(entry, UNIQ_T(_entries_, UNIQ), UNIQ_T(_current_, UNIQ), ##__VA_ARGS__)
+      |                                 ^~~~~~
+../src/test/test-macro.c:322:9: note: in expansion of macro ‘VA_ARGS_FOREACH’
+  322 |         VA_ARGS_FOREACH(u8, 0) {
+      |         ^~~~~~~~~~~~~~~
+
+(cherry picked from commit dc571cccd75db7be49b2aada64baf92e3a498c39)
+(cherry picked from commit 0ddd788136622da3320e43aaa5005b0a68c89137)
+(cherry picked from commit d44fe47f2ea48fd6da83d1748ff37f46df8b4ddd)
+(cherry picked from commit 6a8d6e29cee540e06eb7dba6d5c2185a7a0ac00b)
+
+Origin: upstream, https://github.com/systemd/systemd-stable/commit/31ba3f4ea0f472355e985c7bcca66ffc35e5735c
+Forwarded: not-needed
+Last-Update: 2025-06-23
+---
+ src/basic/macro.h | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/basic/macro.h b/src/basic/macro.h
+index ee83541..e57014c 100644
+--- a/src/basic/macro.h
++++ b/src/basic/macro.h
+@@ -657,10 +657,10 @@ static inline size_t size_add(size_t x, size_t y) {
+ /* Iterate through each variadic arg. All must be the same type as 'entry' or must be implicitly
+  * convertable. The iteration variable 'entry' must already be defined. */
+ #define VA_ARGS_FOREACH(entry, ...)                                     \
+-        _VA_ARGS_FOREACH(entry, UNIQ_T(_entries_, UNIQ), UNIQ_T(_current_, UNIQ), ##__VA_ARGS__)
+-#define _VA_ARGS_FOREACH(entry, _entries_, _current_, ...)         \
+-        for (typeof(entry) _entries_[] = { __VA_ARGS__ }, *_current_ = _entries_; \
+-             ((long)(_current_ - _entries_) < (long)ELEMENTSOF(_entries_)) && ({ entry = *_current_; true; }); \
++        _VA_ARGS_FOREACH(entry, UNIQ_T(_entries_, UNIQ), UNIQ_T(_current_, UNIQ), UNIQ_T(_va_sentinel_, UNIQ), ##__VA_ARGS__)
++#define _VA_ARGS_FOREACH(entry, _entries_, _current_, _va_sentinel_, ...)         \
++        for (typeof(entry) _va_sentinel_[1] = {}, _entries_[] = { __VA_ARGS__ __VA_OPT__(,) _va_sentinel_[0] }, *_current_ = _entries_; \
++             ((long)(_current_ - _entries_) < (long)(ELEMENTSOF(_entries_) - 1)) && ({ entry = *_current_; true; }); \
+              _current_++)
+ 
+ #include "log.h"
diff -Nru systemd-247.3/debian/patches/CVE-2025-4598-3.patch systemd-247.3/debian/patches/CVE-2025-4598-3.patch
--- systemd-247.3/debian/patches/CVE-2025-4598-3.patch	1969-12-31 21:00:00.000000000 -0300
+++ systemd-247.3/debian/patches/CVE-2025-4598-3.patch	2025-06-25 21:44:53.000000000 -0300
@@ -0,0 +1,101 @@
+From 2c81e60fe0b8c506a4fe902e45bed6f58f482b39 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Mon, 26 May 2025 12:04:44 +0200
+Subject: [PATCH] coredump: get rid of _META_MANDATORY_MAX
+
+No functional change. This change is done in preparation for future changes.
+Currently, the list of fields which are received on the command line is a
+strict subset of the fields which are always expected to be received on a
+socket. But when we add new kernel args in the future, we'll have two
+non-overlapping sets and this approach will not work. Get rid of the variable
+and enumerate the required fields. This set will never change, so this is
+actually more maintainable.
+
+The message with the hint where to add new fields is switched with
+_META_ARGV_MAX. The new order is more correct.
+
+(cherry-picked from 49f1f2d4a7612bbed5211a73d11d6a94fbe3bb69)
+(cherry-picked from aea6a631bca93e8b04a11aaced694f25f4da155e)
+(cherry picked from cf16b6b6b2e0a656531bfd73ad66be3817b155cd)
+
+(cherry picked from commit b46a4f023cd80b24c8f1aa7a95700bc0cb828cdc)
+(cherry picked from commit 5855552310ed279180c21cb803408aa2ce36053d)
+(cherry picked from commit cc31f2d4146831b9f2fe7bf584468908ff9c4de5)
+
+Origin: upstream, https://github.com/systemd/systemd-stable/commit/2c81e60fe0b8c506a4fe902e45bed6f58f482b39
+Forwarded: not-needed
+Last-Update: 2025-06-23
+---
+ src/coredump/coredump.c | 29 ++++++++++++++++++++---------
+ 1 file changed, 20 insertions(+), 9 deletions(-)
+
+diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c
+index a5fcb94..f787a7a 100644
+--- a/src/coredump/coredump.c
++++ b/src/coredump/coredump.c
+@@ -68,7 +68,7 @@
+  * size. See DATA_SIZE_MAX in journal-importer.h. */
+ assert_cc(JOURNAL_SIZE_MAX <= DATA_SIZE_MAX);
+ 
+-enum {
++typedef enum {
+         /* We use these as array indexes for our process metadata cache.
+          *
+          * The first indices of the cache stores the same metadata as the ones passed by
+@@ -94,16 +94,15 @@ enum {
+          * environment. */
+ 
+         META_COMM = _META_ARGV_MAX,
+-        _META_MANDATORY_MAX,
+ 
+         /* The rest are similar to the previous ones except that we won't fail if one of
+          * them is missing in a message sent over the socket. */
+ 
+-        META_EXE = _META_MANDATORY_MAX,
++        META_EXE,
+         META_UNIT,
+         META_PROC_AUXV,
+         _META_MAX
+-};
++} meta_argv_t;
+ 
+ static const char * const meta_field_names[_META_MAX] = {
+         [META_ARGV_PID]          = "COREDUMP_PID=",
+@@ -1018,7 +1017,7 @@ static int process_socket(int fd) {
+         Context context = {};
+         struct iovec_wrapper iovw = {};
+         struct iovec iovec;
+-        int i, r;
++        int r;
+ 
+         assert(fd >= 0);
+ 
+@@ -1095,12 +1094,24 @@ static int process_socket(int fd) {
+         if (r < 0)
+                 goto finish;
+ 
+-        /* Make sure we received at least all fields we need. */
+-        for (i = 0; i < _META_MANDATORY_MAX; i++)
++        /* Make sure we received all the expected fields. We support being called by an *older*
++         * systemd-coredump from the outside, so we require only the basic set of fields that
++         * was being sent when the support for sending to containers over a socket was added
++         * in a108c43e36d3ceb6e34efe37c014fc2cda856000. */
++        meta_argv_t i;
++        VA_ARGS_FOREACH(i,
++                        META_ARGV_PID,
++                        META_ARGV_UID,
++                        META_ARGV_GID,
++                        META_ARGV_SIGNAL,
++                        META_ARGV_TIMESTAMP,
++                        META_ARGV_RLIMIT,
++                        META_ARGV_HOSTNAME,
++                        META_COMM)
+                 if (!context.meta[i]) {
+                         r = log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+-                                            "A mandatory argument (%i) has not been sent, aborting.",
+-                                            i);
++                                            "Mandatory argument %s not received on socket, aborting.",
++                                            meta_field_names[i]);
+                         goto finish;
+                 }
+ 
diff -Nru systemd-247.3/debian/patches/CVE-2025-4598-4.patch systemd-247.3/debian/patches/CVE-2025-4598-4.patch
--- systemd-247.3/debian/patches/CVE-2025-4598-4.patch	1969-12-31 21:00:00.000000000 -0300
+++ systemd-247.3/debian/patches/CVE-2025-4598-4.patch	2025-06-25 21:44:53.000000000 -0300
@@ -0,0 +1,267 @@
+From 2eb46dce078334805c547cbcf5e6462cf9d2f9f0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Tue, 29 Apr 2025 14:47:59 +0200
+Subject: [PATCH] coredump: use %d in kernel core pattern
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The kernel provides %d which is documented as
+"dump mode—same as value returned by prctl(2) PR_GET_DUMPABLE".
+
+We already query /proc/pid/auxv for this information, but unfortunately this
+check is subject to a race, because the crashed process may be replaced by an
+attacker before we read this data, for example replacing a SUID process that
+was killed by a signal with another process that is not SUID, tricking us into
+making the coredump of the original process readable by the attacker.
+
+With this patch, we effectively add one more check to the list of conditions
+that need be satisfied if we are to make the coredump accessible to the user.
+
+Reportedy-by: Qualys Security Advisory <qsa@qualys.com>
+
+(cherry-picked from commit 0c49e0049b7665bb7769a13ef346fef92e1ad4d6)
+(cherry-picked from commit c58a8a6ec9817275bb4babaa2c08e0e35090d4e3)
+(cherry picked from commit 19d439189ab85dd7222bdd59fd442bbcc8ea99a7)
+(cherry picked from commit 254ab8d2a7866679cee006d844d078774cbac3c9)
+(cherry picked from commit 7fc7aa5a4d28d7768dfd1eb85be385c3ea949168)
+(cherry picked from commit 19b228662e0fcc6596c0395a0af8486a4b3f1627)
+
+Origin: upstream, https://github.com/systemd/systemd-stable/commit/2eb46dce078334805c547cbcf5e6462cf9d2f9f0
+Forwarded: not-needed
+Last-Update: 2025-06-23
+---
+ src/coredump/coredump.c             |  21 +++++-
+ sysctl.d/50-coredump.conf.in        |   2 +-
+ test/units/testsuite-74.coredump.sh | 144 ++++++++++++++++++++++++++++++++++++
+ 3 files changed, 163 insertions(+), 4 deletions(-)
+ create mode 100755 test/units/testsuite-74.coredump.sh
+
+diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c
+index f787a7a..a4678f6 100644
+--- a/src/coredump/coredump.c
++++ b/src/coredump/coredump.c
+@@ -84,6 +84,7 @@ typedef enum {
+         _META_ARGV_REQUIRED,
+         /* The fields below were added to kernel/core_pattern at later points, so they might be missing. */
+         META_ARGV_HOSTNAME = _META_ARGV_REQUIRED,  /* %h: hostname */
++        META_ARGV_DUMPABLE,     /* %d: as set by the kernel */
+         _META_ARGV_MAX,
+         /* If new fields are added, they should be added here, to maintain compatibility
+          * with callers which don't know about the new fields. */
+@@ -112,6 +113,7 @@ static const char * const meta_field_names[_META_MAX] = {
+         [META_ARGV_TIMESTAMP]    = "COREDUMP_TIMESTAMP=",
+         [META_ARGV_RLIMIT]       = "COREDUMP_RLIMIT=",
+         [META_ARGV_HOSTNAME]     = "COREDUMP_HOSTNAME=",
++        [META_ARGV_DUMPABLE]     = "COREDUMP_DUMPABLE=",
+         [META_COMM]              = "COREDUMP_COMM=",
+         [META_EXE]               = "COREDUMP_EXE=",
+         [META_UNIT]              = "COREDUMP_UNIT=",
+@@ -122,6 +124,7 @@ typedef struct Context {
+         const char *meta[_META_MAX];
+         size_t meta_size[_META_MAX];
+         pid_t pid;
++        unsigned dumpable;
+         bool is_pid1;
+         bool is_journald;
+ } Context;
+@@ -469,14 +472,16 @@ static int grant_user_access(int core_fd, const Context *context) {
+         if (r < 0)
+                 return r;
+ 
+-        /* We allow access if we got all the data and at_secure is not set and
+-         * the uid/gid matches euid/egid. */
++        /* We allow access if dumpable on the command line was exactly 1, we got all the data,
++         * at_secure is not set, and the uid/gid match euid/egid. */
+         bool ret =
++                context->dumpable == 1 &&
+                 at_secure == 0 &&
+                 uid != UID_INVALID && euid != UID_INVALID && uid == euid &&
+                 gid != GID_INVALID && egid != GID_INVALID && gid == egid;
+-        log_debug("Will %s access (uid="UID_FMT " euid="UID_FMT " gid="GID_FMT " egid="GID_FMT " at_secure=%s)",
++        log_debug("Will %s access (dumpable=%u uid="UID_FMT " euid="UID_FMT " gid="GID_FMT " egid="GID_FMT " at_secure=%s)",
+                   ret ? "permit" : "restrict",
++                  context->dumpable,
+                   uid, euid, gid, egid, yes_no(at_secure));
+         return ret;
+ }
+@@ -1005,6 +1010,16 @@ static int save_context(Context *context, const struct iovec_wrapper *iovw) {
+         if (r < 0)
+                 return log_error_errno(r, "Failed to parse PID \"%s\": %m", context->meta[META_ARGV_PID]);
+ 
++        /* The value is set to contents of /proc/sys/fs/suid_dumpable, which we set to 2,
++         * if the process is marked as not dumpable, see PR_SET_DUMPABLE(2const). */
++        if (context->meta[META_ARGV_DUMPABLE]) {
++                r = safe_atou(context->meta[META_ARGV_DUMPABLE], &context->dumpable);
++                if (r < 0)
++                        return log_error_errno(r, "Failed to parse dumpable field \"%s\": %m", context->meta[META_ARGV_DUMPABLE]);
++                if (context->dumpable > 2)
++                        log_notice("Got unexpected %%d/dumpable value %u.", context->dumpable);
++        }
++
+         unit = context->meta[META_UNIT];
+         context->is_pid1 = streq(context->meta[META_ARGV_PID], "1") || streq_ptr(unit, SPECIAL_INIT_SCOPE);
+         context->is_journald = streq_ptr(unit, SPECIAL_JOURNALD_SERVICE);
+diff --git a/sysctl.d/50-coredump.conf.in b/sysctl.d/50-coredump.conf.in
+index 8e501c4..2f92294 100644
+--- a/sysctl.d/50-coredump.conf.in
++++ b/sysctl.d/50-coredump.conf.in
+@@ -13,7 +13,7 @@
+ # the core dump.
+ #
+ # See systemd-coredump(8) and core(5).
+-kernel.core_pattern=|@rootlibexecdir@/systemd-coredump %P %u %g %s %t 9223372036854775808 %h
++kernel.core_pattern=|@rootlibexecdir@/systemd-coredump %P %u %g %s %t 9223372036854775808 %h %d
+ 
+ # Allow that 16 coredumps are dispatched in parallel by the kernel. We want to
+ # be able to collect process metadata from /proc/%P/ while processing
+diff --git a/test/units/testsuite-74.coredump.sh b/test/units/testsuite-74.coredump.sh
+new file mode 100755
+index 0000000..ff23418
+--- /dev/null
++++ b/test/units/testsuite-74.coredump.sh
+@@ -0,0 +1,144 @@
++#!/usr/bin/env bash
++# SPDX-License-Identifier: LGPL-2.1-or-later
++set -eux
++set -o pipefail
++
++# Make sure the binary name fits into 15 characters
++CORE_TEST_BIN="/tmp/test-dump"
++MAKE_DUMP_SCRIPT="/tmp/make-dump"
++# Unset $PAGER so we don't have to use --no-pager everywhere
++export PAGER=
++
++at_exit() {
++    rm -fv -- "$CORE_TEST_BIN" "$MAKE_DUMP_SCRIPT"
++}
++
++trap at_exit EXIT
++
++if systemd-detect-virt -cq; then
++    echo "Running in a container, skipping the systemd-coredump test..."
++    exit 0
++fi
++
++# To make all coredump entries stored in system.journal.
++journalctl --rotate
++
++# Check that we're the ones to receive coredumps
++sysctl kernel.core_pattern | grep systemd-coredump
++
++# Prepare "fake" binaries for coredumps, so we can properly exercise
++# the matching stuff too
++cp -vf /bin/sleep "${CORE_TEST_BIN:?}"
++# Simple script that spawns given "fake" binary and then kills it with
++# given signal
++cat >"${MAKE_DUMP_SCRIPT:?}" <<\EOF
++#!/bin/bash -ex
++
++bin="${1:?}"
++sig="${2:?}"
++
++ulimit -c unlimited
++"$bin" infinity &
++pid=$!
++# Sync with the "fake" binary, so we kill it once it's fully forked off,
++# otherwise we might kill it during fork and kernel would then report
++# "wrong" binary name (i.e. $MAKE_DUMP_SCRIPT instead of $CORE_TEST_BIN).
++# In this case, wait until the "fake" binary (sleep in this case) enters
++# the "interruptible sleep" state, at which point it should be ready
++# to be sacrificed.
++for _ in {0..9}; do
++    read -ra self_stat <"/proc/$pid/stat"
++    [[ "${self_stat[2]}" == S ]] && break
++    sleep .5
++done
++kill -s "$sig" "$pid"
++# This should always fail
++! wait "$pid"
++EOF
++chmod +x "$MAKE_DUMP_SCRIPT"
++
++# Privileged stuff
++[[ "$(id -u)" -eq 0 ]]
++# Trigger a couple of coredumps
++"$MAKE_DUMP_SCRIPT" "$CORE_TEST_BIN" "SIGTRAP"
++"$MAKE_DUMP_SCRIPT" "$CORE_TEST_BIN" "SIGABRT"
++# In the tests we store the coredumps in journals, so let's generate a couple
++# with Storage=external as well
++mkdir -p /run/systemd/coredump.conf.d/
++printf '[Coredump]\nStorage=external' >/run/systemd/coredump.conf.d/99-external.conf
++"$MAKE_DUMP_SCRIPT" "$CORE_TEST_BIN" "SIGTRAP"
++"$MAKE_DUMP_SCRIPT" "$CORE_TEST_BIN" "SIGABRT"
++rm -fv /run/systemd/coredump.conf.d/99-external.conf
++# Wait a bit for the coredumps to get processed
++timeout 30 bash -c "while [[ \$(coredumpctl list -q --no-legend $CORE_TEST_BIN | wc -l) -lt 4 ]]; do sleep 1; done"
++
++coredumpctl
++SYSTEMD_LOG_LEVEL=debug coredumpctl
++coredumpctl --help
++coredumpctl --version
++coredumpctl --no-pager --no-legend
++coredumpctl -1
++coredumpctl --reverse
++coredumpctl -F COREDUMP_EXE
++coredumpctl --directory=/var/log/journal
++coredumpctl --file="/var/log/journal/$(</etc/machine-id)/system.journal"
++coredumpctl --since=@0
++coredumpctl --since=yesterday --until=tomorrow
++# We should have a couple of externally stored coredumps
++coredumpctl --field=COREDUMP_FILENAME | tee /tmp/coredumpctl.out
++grep "/var/lib/systemd/coredump/core" /tmp/coredumpctl.out
++rm -f /tmp/coredumpctl.out
++
++coredumpctl info
++coredumpctl info "$CORE_TEST_BIN"
++coredumpctl info /foo /bar/ /baz "$CORE_TEST_BIN"
++coredumpctl info "${CORE_TEST_BIN##*/}"
++coredumpctl info foo bar baz "${CORE_TEST_BIN##*/}"
++coredumpctl info COREDUMP_EXE="$CORE_TEST_BIN"
++coredumpctl info COREDUMP_EXE=aaaaa COREDUMP_EXE= COREDUMP_EXE="$CORE_TEST_BIN"
++
++coredumpctl debug --debugger=/bin/true "$CORE_TEST_BIN"
++SYSTEMD_DEBUGGER=/bin/true coredumpctl debug "$CORE_TEST_BIN"
++
++coredumpctl dump "$CORE_TEST_BIN" >/tmp/core.redirected
++test -s /tmp/core.redirected
++coredumpctl dump -o /tmp/core.output "${CORE_TEST_BIN##*/}"
++test -s /tmp/core.output
++rm -f /tmp/core.{output,redirected}
++
++# --backtrace mode
++# Pass one of the existing journal coredump records to systemd-coredump.
++# Use our PID as the source to be able to create a PIDFD and to make matching easier.
++# systemd-coredump args: PID UID GID SIGNUM TIMESTAMP CORE_SOFT_RLIMIT [HOSTNAME]
++journalctl -b -n 1 --output=export --output-fields=MESSAGE,COREDUMP COREDUMP_EXE="/usr/bin/test-dump" |
++    /usr/lib/systemd/systemd-coredump --backtrace $$ 0 0 6 1679509900 12345
++journalctl -b -n 1 --output=export --output-fields=MESSAGE,COREDUMP COREDUMP_EXE="/usr/bin/test-dump" |
++    /usr/lib/systemd/systemd-coredump --backtrace $$ 0 0 6 1679509901 12345 mymachine
++journalctl -b -n 1 --output=export --output-fields=MESSAGE,COREDUMP COREDUMP_EXE="/usr/bin/test-dump" |
++    /usr/lib/systemd/systemd-coredump --backtrace $$ 0 0 6 1679509902 12345 youmachine 1
++# Wait a bit for the coredumps to get processed
++timeout 30 bash -c "while [[ \$(coredumpctl list -q --no-legend $$ | wc -l) -lt 2 ]]; do sleep 1; done"
++coredumpctl info $$
++coredumpctl info COREDUMP_TIMESTAMP=1679509900000000
++coredumpctl info COREDUMP_TIMESTAMP=1679509901000000
++coredumpctl info COREDUMP_HOSTNAME="mymachine"
++coredumpctl info COREDUMP_TIMESTAMP=1679509902000000
++coredumpctl info COREDUMP_HOSTNAME="youmachine"
++coredumpctl info COREDUMP_DUMPABLE="1"
++
++systemd-run -t --property CoredumpFilter=default ls /tmp
++
++(! coredumpctl --hello-world)
++(! coredumpctl --file=/dev/null)
++(! coredumpctl --since=0)
++(! coredumpctl --until='')
++(! coredumpctl --since=today --until=yesterday)
++(! coredumpctl -F foo -F bar)
++(! coredumpctl list 0)
++(! coredumpctl list -- -1)
++(! coredumpctl list '')
++(! coredumpctl info /../.~=)
++(! coredumpctl info '')
++(! coredumpctl dump --output=/dev/full "$CORE_TEST_BIN")
++(! coredumpctl dump --output=/dev/null --output=/dev/null "$CORE_TEST_BIN")
++(! coredumpctl debug --debugger=/bin/false)
diff -Nru systemd-247.3/debian/patches/series systemd-247.3/debian/patches/series
--- systemd-247.3/debian/patches/series	2024-08-25 16:05:15.000000000 -0300
+++ systemd-247.3/debian/patches/series	2025-06-25 21:44:53.000000000 -0300
@@ -69,3 +69,8 @@
 0001-resolved-actually-check-authenticated-flag-of-SOA-tr.patch
 0002-resolved-limit-the-number-of-signature-validations-i.patch
 0003-resolved-reduce-the-maximum-nsec3-iterations-to-100.patch
+CVE-2025-4598-0.patch
+CVE-2025-4598-1.patch
+CVE-2025-4598-2.patch
+CVE-2025-4598-3.patch
+CVE-2025-4598-4.patch
diff -Nru systemd-247.3/debian/salsa-ci.yml systemd-247.3/debian/salsa-ci.yml
--- systemd-247.3/debian/salsa-ci.yml	1969-12-31 21:00:00.000000000 -0300
+++ systemd-247.3/debian/salsa-ci.yml	2025-06-25 21:44:53.000000000 -0300
@@ -0,0 +1,4 @@
+---
+# (E)LTS CI
+include:
+- https://salsa.debian.org/lts-team/pipeline/raw/master/recipes/bullseye.yml
