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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.