[git commit] libbb: Prevent clang from reading the G pointer before it is assigned

Denys Vlasenko vda.linux at googlemail.com
Tue Jul 1 19:21:16 UTC 2025


commit: https://git.busybox.net/busybox/commit/?id=244f5c47954010d45b7bf19dc4c7c9c041bf6807
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

It was observed that getty crashes on RISC-V 64-bit target, with the
busybox binary compiled by clang/LLVM 17 with -O2. Not only getty,
but also some other applets like syslogd/vi are broken too.

Commit 5156b245 ("Make const ptr assign as function call in clang")
introduced XZALLOC_CONST_PTR() to defeat the compiler optimization,
however it only fixed a small number of broken places when compiling
busybox with clang/LLVM. A large number of places remain broken.

This commit treats ASSIGN_CONST_PTR() the same way as XZALLOC_CONST_PTR().

Signed-off-by: Bin Meng <bmeng.cn at gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 include/libbb.h    | 22 +++-------------------
 libbb/const_hack.c | 21 ++++++++++++++++++++-
 2 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/include/libbb.h b/include/libbb.h
index 558f3c627..287103756 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -2337,26 +2337,10 @@ extern struct globals *BB_GLOBAL_CONST ptr_to_globals;
 #define barrier() asm volatile ("":::"memory")
 
 #if defined(__clang_major__) && __clang_major__ >= 9
-/* Clang/llvm drops assignment to "constant" storage. Silently.
- * Needs serious convincing to not eliminate the store.
- */
-static ALWAYS_INLINE void* not_const_pp(const void *p)
-{
-	void *pp;
-	asm volatile (
-		"# forget that p points to const"
-		: /*outputs*/ "=r" (pp)
-		: /*inputs*/ "0" (p)
-	);
-	return pp;
-}
-# define ASSIGN_CONST_PTR(pptr, v) do { \
-	*(void**)not_const_pp(pptr) = (void*)(v); \
-	barrier(); \
-} while (0)
-/* XZALLOC_CONST_PTR() is an out-of-line function to prevent
- * clang from reading pointer before it is assigned.
+/* {ASSIGN,XZALLOC}_CONST_PTR() are out-of-line functions
+ * to prevent clang from reading pointer before it is assigned.
  */
+void ASSIGN_CONST_PTR(const void *pptr, void *v) FAST_FUNC;
 void XZALLOC_CONST_PTR(const void *pptr, size_t size) FAST_FUNC;
 #else
 # define ASSIGN_CONST_PTR(pptr, v) do { \
diff --git a/libbb/const_hack.c b/libbb/const_hack.c
index 9575e6d67..1d175481b 100644
--- a/libbb/const_hack.c
+++ b/libbb/const_hack.c
@@ -9,8 +9,27 @@
 #include "libbb.h"
 
 #if defined(__clang_major__) && __clang_major__ >= 9
+/* Clang/llvm drops assignment to "constant" storage. Silently.
+ * Needs serious convincing to not eliminate the store.
+ */
+static ALWAYS_INLINE void* not_const_pp(const void *p)
+{
+	void *pp;
+	asm volatile (
+		"# forget that p points to const"
+		: /*outputs*/ "=r" (pp)
+		: /*inputs*/ "0" (p)
+	);
+	return pp;
+}
+void FAST_FUNC ASSIGN_CONST_PTR(const void *pptr, void *v)
+{
+	*(void**)not_const_pp(pptr) = v;
+	barrier();
+}
 void FAST_FUNC XZALLOC_CONST_PTR(const void *pptr, size_t size)
 {
-	ASSIGN_CONST_PTR(pptr, xzalloc(size));
+	*(void**)not_const_pp(pptr) = xzalloc(size);
+	barrier();
 }
 #endif


More information about the busybox-cvs mailing list