* [PATCH] um: drivers: use libc strrchr() in cow_user.o
[not found] <20260407164435.726012-1-michael.bommarito@gmail.com>
@ 2026-04-07 16:44 ` Michael Bommarito
2026-04-07 16:57 ` Johannes Berg
2026-04-07 18:15 ` [PATCH v2] um: drivers: call kernel_strrchr() explicitly in cow_user.c Michael Bommarito
1 sibling, 1 reply; 3+ messages in thread
From: Michael Bommarito @ 2026-04-07 16:44 UTC (permalink / raw)
To: Richard Weinberger, Anton Ivanov, Johannes Berg
Cc: linux-um, linux-kernel, Michael Bommarito, stable
Building ARCH=um on a host with glibc >= 2.43 fails:
arch/um/drivers/cow_user.c:156:17: error: implicit declaration of
function 'strrchr' [-Wimplicit-function-declaration]
cow_user.o is a host-side helper (compiled with -D__UM_HOST__) that
calls libc strrchr(). It inherits the global -Dstrrchr=kernel_strrchr
remap from arch/um/Makefile, which is intentionally kept in USER_CFLAGS
to prevent linker clashes between libc and kernel symbols.
This combination was harmless until glibc 2.43, which added (glibc
commit cd748a63ab1a, "Implement C23 const-preserving standard library
macros"):
#define strrchr(S,C) __glibc_const_generic(S, const char *, strrchr(S, C))
The glibc function-like macro replaces the -D object-like macro. The
inner strrchr token in the expansion is protected from recursive
expansion, so it refers to the bare symbol strrchr -- but the header
declaration was already rewritten to kernel_strrchr by the -D. The
result is an implicit-declaration error.
The remap was originally added in commit 2c51a4bc0233 ("um: fix
strrchr() problems") to resolve a linker clash when both
CONFIG_STATIC_LINK and CONFIG_UML_NET_VDE are set. Recently, commit
a74b6c0e53a6 ("um: Don't rename vmap to kernel_vmap") trimmed
the now-obsolete vmap remap from arch/um/Makefile and updated the
comment to explicitly call out -Dstrrchr=kernel_strrchr as one of the
remaps that still prevents libc symbol clashes. That framing is kept
here: the global strrchr remap is still needed for kernel-side
objects, but cow_user.o is host-side and should use libc strrchr
directly.
cow_user.o is built whenever CONFIG_BLK_DEV_UBD=y (the standard UML
block device), so this affects most non-trivial UML configurations.
cow_user.c is the only file under arch/um/ that calls strrchr().
Fix this by undoing the remap for just this translation unit via
per-object CFLAGS. In UML's Makefile.rules, CFLAGS_$(basetarget).o
is appended after USER_CFLAGS, so -Ustrrchr correctly overrides the
earlier -Dstrrchr=kernel_strrchr.
Standalone reproducer (fails on glibc >= 2.43, succeeds on older):
printf '#include <string.h>\nvoid f(void) { char *p = strrchr("foo", 47); }\n' \
| gcc -c -Dstrrchr=kernel_strrchr -x c - -o /dev/null
Tested on:
- Host: Ubuntu, glibc 2.43-2ubuntu1, gcc 15.2.0
- Kernel: v7.0.0-rc6 (3aae9383f42f)
- Build: ARCH=um defconfig + CONFIG_BLK_DEV_UBD=y, clean compile
- Boot: UML boots to Debian bookworm multi-user target
- COW: UML boots with COW overlay (ubd0=cow,backing), exercising
the absolutize() -> strrchr() path in cow_user.c
AI coding tools (Claude Code with Opus 4.6, and Codex with GPT-5.4)
assisted with debugging, test design, and drafting; the author
manually reviewed every line and executed every build and boot test
on the host. Full disclosure in the cover letter.
Fixes: 2c51a4bc0233 ("um: fix strrchr() problems")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-6
Assisted-by: Codex:gpt-5-4
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
---
arch/um/drivers/Makefile | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
index 36dc57840..e387ae33f 100644
--- a/arch/um/drivers/Makefile
+++ b/arch/um/drivers/Makefile
@@ -49,6 +49,9 @@ obj-$(CONFIG_UML_PCI_OVER_VFIO) += vfio_uml.o
# pcap_user.o must be added explicitly.
USER_OBJS := fd.o null.o pty.o tty.o xterm.o vector_user.o
CFLAGS_null.o = -DDEV_NULL=$(DEV_NULL_PATH)
+# cow_user.o is a host-side helper that uses libc strrchr(); undo the global
+# UML remap to kernel_strrchr for this translation unit.
+CFLAGS_cow_user.o += -Ustrrchr
CFLAGS_xterm.o += '-DCONFIG_XTERM_CHAN_DEFAULT_EMULATOR="$(CONFIG_XTERM_CHAN_DEFAULT_EMULATOR)"'
--
2.49.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] um: drivers: use libc strrchr() in cow_user.o
2026-04-07 16:44 ` [PATCH] um: drivers: use libc strrchr() in cow_user.o Michael Bommarito
@ 2026-04-07 16:57 ` Johannes Berg
0 siblings, 0 replies; 3+ messages in thread
From: Johannes Berg @ 2026-04-07 16:57 UTC (permalink / raw)
To: Michael Bommarito, Richard Weinberger, Anton Ivanov
Cc: linux-um, linux-kernel, stable
On Tue, 2026-04-07 at 12:44 -0400, Michael Bommarito wrote:
> That framing is kept
> here: the global strrchr remap is still needed for kernel-side
> objects, but cow_user.o is host-side and should use libc strrchr
> directly.
Not sure. glibc has an unfortunate tendency to use a huge amount of
stack space for just about anything (though I admit that's unlikely for
strrchr) - we should probably just explicitly call kernel_strrchr() in
the file instead.
johannes
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH v2] um: drivers: call kernel_strrchr() explicitly in cow_user.c
[not found] <20260407164435.726012-1-michael.bommarito@gmail.com>
2026-04-07 16:44 ` [PATCH] um: drivers: use libc strrchr() in cow_user.o Michael Bommarito
@ 2026-04-07 18:15 ` Michael Bommarito
1 sibling, 0 replies; 3+ messages in thread
From: Michael Bommarito @ 2026-04-07 18:15 UTC (permalink / raw)
To: Richard Weinberger, Anton Ivanov, Johannes Berg
Cc: linux-um, linux-kernel, Michael Bommarito, stable
Building ARCH=um on a host with glibc >= 2.43 fails:
arch/um/drivers/cow_user.c:156:17: error: implicit declaration of
function 'strrchr' [-Wimplicit-function-declaration]
cow_user.o is a host-side helper (compiled with -D__UM_HOST__) that
calls strrchr(). It inherits the global -Dstrrchr=kernel_strrchr
remap from arch/um/Makefile, which is intentionally kept in
USER_CFLAGS to prevent libc/kernel symbol clashes.
This combination was harmless until glibc 2.43, which added (glibc
commit cd748a63ab1a, "Implement C23 const-preserving standard library
macros"):
#define strrchr(S,C) __glibc_const_generic(S, const char *, strrchr(S, C))
The glibc function-like macro replaces the -D object-like macro. The
inner strrchr token in the expansion is protected from recursive
expansion, so it refers to the bare symbol strrchr -- but the header
declaration was already rewritten to kernel_strrchr by the -D. The
result is an implicit-declaration error.
The global -Dstrrchr=kernel_strrchr remap was originally added in
commit 2c51a4bc0233 ("um: fix strrchr() problems") to resolve a
linker clash when both CONFIG_STATIC_LINK and CONFIG_UML_NET_VDE are
set. Recently, commit a74b6c0e53a6 ("um: Don't rename vmap to
kernel_vmap") trimmed the now-obsolete vmap remap and updated the
comment in arch/um/Makefile to explicitly call out
-Dstrrchr=kernel_strrchr as one of the remaps that still prevents
libc symbol clashes. That global remap stays in place.
Rather than exempting cow_user.o from the remap at build time, call
kernel_strrchr() explicitly in the source. This is slightly more
honest about which strrchr the code wants (the kernel's, as it has
been since 2011), sidesteps the interaction with glibc's C23 macro
entirely, avoids adding a new libc strrchr dependency to the UML
binary, and is robust to future C23 const-preserving macros for
strchr, memchr, strstr, etc.
cow_user.o is built whenever CONFIG_BLK_DEV_UBD=y (the standard UML
block device), so this affects most non-trivial UML configurations.
cow_user.c is the only file under arch/um/ that calls strrchr(), so
no other translation units need changes.
Standalone reproducer (fails on glibc >= 2.43, succeeds on older):
printf '#include <string.h>\nvoid f(void) { char *p = strrchr("foo", 47); }\n' \
| gcc -c -Dstrrchr=kernel_strrchr -x c - -o /dev/null
Tested on:
- Host: Ubuntu, glibc 2.43-2ubuntu1, gcc 15.2.0
- Kernel: v7.0-rc6 (3aae9383f42f); verified that neither
arch/um/drivers/Makefile nor arch/um/drivers/cow_user.c
changed between rc6 and rc7, so the fix applies and
behaves identically on both
- Build: ARCH=um defconfig + CONFIG_BLK_DEV_UBD=y, clean compile
with no warnings
- nm: cow_user.o references 'U kernel_strrchr' (not libc
strrchr), and the final linux binary has no
strrchr@GLIBC_2.2.5 symbol anywhere; kernel_strrchr is
defined exactly once by lib/string.o and
EXPORT_SYMBOL'd
- Boot: UML boots to Debian bookworm multi-user and graphical
targets with a COW overlay (ubd0=cow,backing), which
exercises the patched absolutize() -> kernel_strrchr()
code path in cow_user.c
AI coding tools (Claude Code with Opus 4.6, and Codex with GPT-5.4)
assisted with debugging, test design, and drafting; the author
manually reviewed every line and executed every build and boot test
on the host. Full disclosure was posted with v1; a shorter summary
is in the Assisted-by: trailers below.
Fixes: 2c51a4bc0233 ("um: fix strrchr() problems")
Suggested-by: Johannes Berg <johannes@sipsolutions.net>
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-6
Assisted-by: Codex:gpt-5-4
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
---
v1: https://lore.kernel.org/all/20260407164435.726012-2-michael.bommarito@gmail.com/
Review: https://lore.kernel.org/linux-um/1e15d25c23b444eae1dcfc01432e7ec1e19e25a0.camel@sipsolutions.net/
Changes since v1:
- Per Johannes Berg's review (link above): rather than exempting
cow_user.o from the global -Dstrrchr=kernel_strrchr remap via
-Ustrrchr in arch/um/drivers/Makefile, call kernel_strrchr()
explicitly in cow_user.c. This keeps the existing semantic that
cow_user.o uses the kernel's strrchr (no new libc dependency on
the host side), and the source no longer relies on the build-time
rewrite at all.
- Reverted the arch/um/drivers/Makefile CFLAGS change from v1.
- Verified locally on v7.0-rc6: clean build, cow_user.o references
'U kernel_strrchr' (no libc strrchr), the final linux binary has
no strrchr@GLIBC_2.2.5 reference anywhere, and the kernel boots
to multi-user with a COW overlay that exercises the patched
code path. Full boot log captured locally.
arch/um/drivers/cow_user.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c
index 29b46581ddd1..ec8e6121b402 100644
--- a/arch/um/drivers/cow_user.c
+++ b/arch/um/drivers/cow_user.c
@@ -15,6 +15,12 @@
#include "cow.h"
#include "cow_sys.h"
+/*
+ * arch/um/Makefile remaps strrchr to kernel_strrchr; call the kernel
+ * name directly to avoid glibc >= 2.43's C23 strrchr macro.
+ */
+extern char *kernel_strrchr(const char *, int);
+
#define PATH_LEN_V1 256
/* unsigned time_t works until year 2106 */
@@ -153,7 +159,7 @@ static int absolutize(char *to, int size, char *from)
errno);
return -1;
}
- slash = strrchr(from, '/');
+ slash = kernel_strrchr(from, '/');
if (slash != NULL) {
*slash = '\0';
if (chdir(from)) {
--
2.49.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-04-07 18:15 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20260407164435.726012-1-michael.bommarito@gmail.com>
2026-04-07 16:44 ` [PATCH] um: drivers: use libc strrchr() in cow_user.o Michael Bommarito
2026-04-07 16:57 ` Johannes Berg
2026-04-07 18:15 ` [PATCH v2] um: drivers: call kernel_strrchr() explicitly in cow_user.c Michael Bommarito
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox