From: Waldemar Brodkorb <wbx@openadk.org>
To: Titouan Christophe <titouan.christophe@mind.be>
Cc: buildroot@buildroot.org,
Giulio Benetti <giulio.benetti@benettiengineering.com>,
thomas.perale@mind.be
Subject: Re: [Buildroot] [PATCH for 2025.02.x] package/util-linux: add patch for CVE-2026-27456
Date: Thu, 7 May 2026 15:14:37 +0200 [thread overview]
Message-ID: <afyQPbG8W74rRqfN@waldemar-brodkorb.de> (raw)
In-Reply-To: <20260427101206.1362913-1-titouan.christophe@mind.be>
Hi,
this patch breaks compilation on Debian 13 with following error:
lib/loopdev.c: In function ‘loopcxt_set_backing_file’:
lib/loopdev.c:1273:32: error: implicit declaration of function ‘ul_canonicalize_path’; did you mean ‘canonicalize_path’? [-Wimplicit-function-declaration]
1273 | lc->filename = ul_canonicalize_path(filename);
| ^~~~~~~~~~~~~~~~~~~~
| canonicalize_path
lib/loopdev.c:1273:32: warning: nested extern declaration of ‘ul_canonicalize_path’ [-Wnested-externs]
lib/loopdev.c:1273:30: error: assignment to ‘char *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
1273 | lc->filename = ul_canonicalize_path(filename);
| ^
make[4]: *** [Makefile:11808: lib/libcommon_la-loopdev.lo] Error 1
make[3]: *** [Makefile:16952: all-recursive] Error 1
make[2]: *** [Makefile:7294: all] Error 2
make[1]: *** [package/pkg-generic.mk:273: /home/wbx/br-2025.02/output/build/host-util-linux-2.40.2/.stamp_built] Error 2
make: *** [Makefile:83: _all] Error 2
best regards
Waldemar
Titouan Christophe via buildroot wrote,
> Signed-off-by: Titouan Christophe <titouan.christophe@mind.be>
> ---
> .../0006-add-loopdev-fl-nofollow.patch | 111 ++++++++++++++++++
> package/util-linux/util-linux.mk | 3 +
> 2 files changed, 114 insertions(+)
> create mode 100644 package/util-linux/0006-add-loopdev-fl-nofollow.patch
>
> diff --git a/package/util-linux/0006-add-loopdev-fl-nofollow.patch b/package/util-linux/0006-add-loopdev-fl-nofollow.patch
> new file mode 100644
> index 0000000000..21b1e2596c
> --- /dev/null
> +++ b/package/util-linux/0006-add-loopdev-fl-nofollow.patch
> @@ -0,0 +1,111 @@
> +From 5e390467b26a3cf3fecc04e1a0d482dff3162fc4 Mon Sep 17 00:00:00 2001
> +From: Karel Zak <kzak@redhat.com>
> +Date: Thu, 19 Feb 2026 13:59:46 +0100
> +Subject: [PATCH] loopdev: add LOOPDEV_FL_NOFOLLOW to prevent symlink attacks
> +
> +Add a new LOOPDEV_FL_NOFOLLOW flag for loop device context that
> +prevents symlink following in both path canonicalization and file open.
> +
> +When set:
> +- loopcxt_set_backing_file() uses strdup() instead of
> + ul_canonicalize_path() (which calls realpath() and follows symlinks)
> +- loopcxt_setup_device() adds O_NOFOLLOW to open() flags
> +
> +The flag is set for non-root (restricted) mount operations in
> +libmount's loop device hook. This prevents a TOCTOU race condition
> +where an attacker could replace the backing file (specified in
> +/etc/fstab) with a symlink to an arbitrary root-owned file between
> +path resolution and open().
> +
> +Vulnerable Code Flow:
> +
> + mount /mnt/point (non-root, SUID)
> + mount.c: sanitize_paths() on user args (mountpoint only)
> + mnt_context_mount()
> + mnt_context_prepare_mount()
> + mnt_context_apply_fstab() <-- source path from fstab
> + hooks run at MNT_STAGE_PREP_SOURCE
> + hook_loopdev.c: setup_loopdev()
> + backing_file = fstab source path ("/home/user/disk.img")
> + loopcxt_set_backing_file() <-- calls realpath() as ROOT
> + ul_canonicalize_path() <-- follows symlinks!
> + loopcxt_setup_device()
> + open(lc->filename, O_RDWR|O_CLOEXEC) <-- no O_NOFOLLOW
> +
> +Two vulnerabilities in the path:
> +
> +1) loopcxt_set_backing_file() calls ul_canonicalize_path() which uses
> + realpath() -- this follows symlinks as euid=0. If the attacker swaps
> + the file to a symlink before this call, lc->filename becomes the
> + resolved target path (e.g., /root/secret.img).
> +
> +2) loopcxt_setup_device() opens lc->filename without O_NOFOLLOW. Even
> + if canonicalization happened correctly, the file can be swapped to a
> + symlink between canonicalize and open.
> +
> +Addresses: https://github.com/util-linux/util-linux/security/advisories/GHSA-qq4x-vfq4-9h9g
> +Signed-off-by: Karel Zak <kzak@redhat.com>
> +
> +CVE: CVE-2026-27456
> +Upstream: https://github.com/util-linux/util-linux/commit/5e390467b26a3cf3fecc04e1a0d482dff3162fc4
> +[Titouan: Adapt patch to apply cleanly onto util-linux 2.40]
> +Signed-off-by: Titouan Christophe <titouan.christophe@mind.be>
> +---
> + include/loopdev.h | 3 ++-
> + lib/loopdev.c | 7 ++++++-
> + libmount/src/hook_loopdev.c | 3 ++-
> + 3 files changed, 10 insertions(+), 3 deletions(-)
> +
> +diff --git a/include/loopdev.h b/include/loopdev.h
> +index d10bf7f37..0f85dd254 100644
> +--- a/include/loopdev.h
> ++++ b/include/loopdev.h
> +@@ -139,7 +139,8 @@ enum {
> + LOOPDEV_FL_NOIOCTL = (1 << 6),
> + LOOPDEV_FL_DEVSUBDIR = (1 << 7),
> + LOOPDEV_FL_CONTROL = (1 << 8), /* system with /dev/loop-control */
> +- LOOPDEV_FL_SIZELIMIT = (1 << 9)
> ++ LOOPDEV_FL_SIZELIMIT = (1 << 9),
> ++ LOOPDEV_FL_NOFOLLOW = (1 << 10) /* O_NOFOLLOW, don't follow symlinks */
> + };
> +
> + /*
> +diff --git a/lib/loopdev.c b/lib/loopdev.c
> +index c72fb2c40..3d2274693 100644
> +--- a/lib/loopdev.c
> ++++ b/lib/loopdev.c
> +@@ -1267,7 +1267,10 @@ int loopcxt_set_backing_file(struct loopdev_cxt *lc, const char *filename)
> + if (!lc)
> + return -EINVAL;
> +
> +- lc->filename = canonicalize_path(filename);
> ++ if (lc->flags & LOOPDEV_FL_NOFOLLOW)
> ++ lc->filename = strdup(filename);
> ++ else
> ++ lc->filename = ul_canonicalize_path(filename);
> + if (!lc->filename)
> + return -errno;
> +
> +@@ -1408,6 +1411,8 @@ int loopcxt_setup_device(struct loopdev_cxt *lc)
> +
> + if (lc->config.info.lo_flags & LO_FLAGS_DIRECT_IO)
> + flags |= O_DIRECT;
> ++ if (lc->flags & LOOPDEV_FL_NOFOLLOW)
> ++ flags |= O_NOFOLLOW;
> +
> + if ((file_fd = open(lc->filename, mode | flags)) < 0) {
> + if (mode != O_RDONLY && (errno == EROFS || errno == EACCES))
> +diff --git a/libmount/src/hook_loopdev.c b/libmount/src/hook_loopdev.c
> +index 597b9339a..4df1915a6 100644
> +--- a/libmount/src/hook_loopdev.c
> ++++ b/libmount/src/hook_loopdev.c
> +@@ -272,7 +272,8 @@ static int setup_loopdev(struct libmnt_context *cxt,
> + }
> +
> + DBG(LOOP, ul_debugobj(cxt, "not found; create a new loop device"));
> +- rc = loopcxt_init(&lc, 0);
> ++ rc = loopcxt_init(&lc,
> ++ mnt_context_is_restricted(cxt) ? LOOPDEV_FL_NOFOLLOW : 0);
> + if (rc)
> + goto done_no_deinit;
> + if (mnt_opt_has_value(loopopt)) {
> diff --git a/package/util-linux/util-linux.mk b/package/util-linux/util-linux.mk
> index 5d761e01c9..d30c26deb5 100644
> --- a/package/util-linux/util-linux.mk
> +++ b/package/util-linux/util-linux.mk
> @@ -36,6 +36,9 @@ UTIL_LINUX_CPE_ID_VENDOR = kernel
> # 0001-libmount-ifdef-statx-call.patch
> UTIL_LINUX_AUTORECONF = YES
>
> +# 0006-add-loopdev-fl-nofollow.patch
> +UTIL_LINUX_IGNORE_CVES += CVE-2026-27456
> +
> UTIL_LINUX_INSTALL_STAGING = YES
> UTIL_LINUX_DEPENDENCIES = \
> host-pkgconf \
> --
> 2.53.0
>
> _______________________________________________
> buildroot mailing list
> buildroot@buildroot.org
> https://lists.buildroot.org/mailman/listinfo/buildroot
>
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot
prev parent reply other threads:[~2026-05-07 13:14 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-27 10:12 [Buildroot] [PATCH for 2025.02.x] package/util-linux: add patch for CVE-2026-27456 Titouan Christophe via buildroot
2026-05-04 14:47 ` Thomas Perale via buildroot
2026-05-07 13:14 ` Waldemar Brodkorb [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=afyQPbG8W74rRqfN@waldemar-brodkorb.de \
--to=wbx@openadk.org \
--cc=buildroot@buildroot.org \
--cc=giulio.benetti@benettiengineering.com \
--cc=thomas.perale@mind.be \
--cc=titouan.christophe@mind.be \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox