diff --git a/SPECS-SIGNED/systemd-boot-signed/systemd-boot-signed.spec b/SPECS-SIGNED/systemd-boot-signed/systemd-boot-signed.spec index 73238100e8d..381e6c76687 100644 --- a/SPECS-SIGNED/systemd-boot-signed/systemd-boot-signed.spec +++ b/SPECS-SIGNED/systemd-boot-signed/systemd-boot-signed.spec @@ -20,7 +20,7 @@ Version: 255 # determine the build information from local checkout Version: %(tools/meson-vcs-tag.sh . error | sed -r 's/-([0-9])/.^\1/; s/-g/_g/') %endif -Release: 34%{?dist} +Release: 35%{?dist} License: LGPL-2.1-or-later AND MIT AND GPL-2.0-or-later Vendor: Microsoft Corporation Distribution: Azure Linux @@ -98,6 +98,9 @@ popd /boot/efi/EFI/BOOT/%{grubefiname} %changelog +* Fri Aug 28 2026 Pawel Winogrodzki - 255-35 +- Bump release to match systemd spec. + * Mon Aug 17 2026 Aditya Singh - 255-34 - Bump release to match systemd spec. diff --git a/SPECS/systemd/systemd-fsck-lock-whole-disk.patch b/SPECS/systemd/systemd-fsck-lock-whole-disk.patch new file mode 100644 index 00000000000..04c672d0284 --- /dev/null +++ b/SPECS/systemd/systemd-fsck-lock-whole-disk.patch @@ -0,0 +1,112 @@ +Lock the whole parent disk while fsck runs so udev cannot probe sibling +partitions during filesystem repair. + +Wait up to 60 seconds for the lock. If the timeout expires, warn and run +the filesystem check without the lock to preserve the previous behavior. + +This downstream workaround tracks the competing upstream proposals: + +- https://github.com/systemd/systemd/issues/43695 +- https://github.com/systemd/systemd/pull/43696 +- https://lore.kernel.org/linux-ext4/20260824224006.GB6038@frogsfrogsfrogs/t/ + +Remove this patch when the selected upstream solution is integrated. It +cannot coexist with native e2fsprogs (e2fsck) whole-disk locking: +systemd-fsck retains its lock descriptor while waiting for fsck, so an +independently opened exclusive lock in the child would deadlock. + +diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c +index 000ed69..8eb209a 100644 +--- a/src/fsck/fsck.c ++++ b/src/fsck/fsck.c +@@ -15,6 +15,7 @@ + #include "sd-device.h" + + #include "alloc-util.h" ++#include "blockdev-util.h" + #include "bus-common-errors.h" + #include "bus-error.h" + #include "bus-locator.h" +@@ -23,6 +24,7 @@ + #include "fd-util.h" + #include "fs-util.h" + #include "fsck-util.h" ++#include "lock-util.h" + #include "main-func.h" + #include "parse-util.h" + #include "path-util.h" +@@ -32,6 +34,7 @@ + #include "socket-util.h" + #include "special.h" + #include "stdio-util.h" ++#include "time-util.h" + + static bool arg_skip = false; + static bool arg_force = false; +@@ -233,8 +236,49 @@ static int fsck_progress_socket(void) { + return TAKE_FD(fd); + } + ++static const usec_t whole_disk_lock_timeout = 60 * USEC_PER_SEC; ++ ++static int lock_whole_disk(const char *device) { ++ _cleanup_free_ char *whole_disk = NULL; ++ _cleanup_close_ int fd = -EBADF; ++ struct stat st; ++ dev_t devno; ++ int r; ++ ++ assert(device); ++ ++ r = path_get_whole_disk(device, /* backing = */ false, &devno); ++ if (r < 0) ++ return log_error_errno(r, "Failed to find whole block device for '%s': %m", device); ++ ++ r = devname_from_devnum(S_IFBLK, devno, &whole_disk); ++ if (r < 0) ++ return log_error_errno(r, "Failed to resolve whole block device for '%s': %m", device); ++ ++ fd = open(whole_disk, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); ++ if (fd < 0) ++ return log_error_errno(errno, "Failed to open whole block device '%s': %m", whole_disk); ++ ++ if (fstat(fd, &st) < 0) ++ return log_error_errno(errno, "Failed to stat whole block device '%s': %m", whole_disk); ++ if (!S_ISBLK(st.st_mode) || st.st_rdev != devno) ++ return log_error_errno(SYNTHETIC_ERRNO(ENXIO), ++ "Path '%s' no longer refers to block device %u:%u.", ++ whole_disk, major(devno), minor(devno)); ++ ++ r = lock_generic_with_timeout(fd, LOCK_BSD, LOCK_EX, whole_disk_lock_timeout); ++ if (r == -ETIMEDOUT) ++ return r; ++ if (r < 0) ++ return log_error_errno(r, "Failed to lock whole block device '%s': %m", whole_disk); ++ ++ log_debug("Locked whole block device %s while checking %s.", whole_disk, device); ++ return TAKE_FD(fd); ++} ++ + static int run(int argc, char *argv[]) { + _cleanup_close_pair_ int progress_pipe[2] = EBADF_PAIR; ++ _cleanup_close_ int lock_fd = -EBADF; + _cleanup_(sd_device_unrefp) sd_device *dev = NULL; + _cleanup_free_ char *dpath = NULL; + _cleanup_fclose_ FILE *console = NULL; +@@ -333,6 +377,16 @@ static int run(int argc, char *argv[]) { + } + } + ++ lock_fd = lock_whole_disk(device); ++ if (lock_fd == -ETIMEDOUT) { ++ log_warning( ++ "Timed out waiting %s for whole block device lock for '%s'; proceeding without lock.", ++ FORMAT_TIMESPAN(whole_disk_lock_timeout, USEC_PER_SEC), ++ device); ++ lock_fd = -EBADF; ++ } else if (lock_fd < 0) ++ return lock_fd; ++ + console = fopen("/dev/console", "we"); + if (console && + arg_show_progress && diff --git a/SPECS/systemd/systemd.spec b/SPECS/systemd/systemd.spec index bc46e768f95..0e8504ca881 100644 --- a/SPECS/systemd/systemd.spec +++ b/SPECS/systemd/systemd.spec @@ -50,7 +50,7 @@ Version: 255 # determine the build information from local checkout Version: %(tools/meson-vcs-tag.sh . error | sed -r 's/-([0-9])/.^\1/; s/-g/_g/') %endif -Release: 34%{?dist} +Release: 35%{?dist} # FIXME - hardcode to 'stable' for now as that's what we have in our blobstore %global stable 1 @@ -161,6 +161,7 @@ Patch0913: network-also-check-ID_NET_MANAGED_BY-property-on-rec.patch Patch0914: Prevent-corruption-from-stale-alias-state-on-daemon-reload.patch Patch0915: CVE-2026-15059.patch Patch0916: CVE-2026-16742.patch +Patch0917: systemd-fsck-lock-whole-disk.patch %ifarch %{ix86} x86_64 aarch64 %global want_bootloader 1 @@ -1259,6 +1260,10 @@ rm -f %{name}.lang # %autochangelog. So we need to continue manually maintaining the # changelog here. %changelog +* Fri Aug 28 2026 Pawel Winogrodzki - 255-35 +- Lock the whole disk in systemd-fsck while its child fsck process checks + the filesystem. + * Thu Aug 13 2026 Azure Linux Security Servicing Account - 255-34 - Patch for CVE-2026-16742, CVE-2026-15059