[libc-commits] [libc] [libc] check a few syscall #'s to avoid wrong syscalls (PR #123100)

Nick Desaulniers via libc-commits libc-commits at lists.llvm.org
Fri Jan 17 13:40:14 PST 2025


https://github.com/nickdesaulniers updated https://github.com/llvm/llvm-project/pull/123100

>From 955c79433f9a367f2042f4bf64dc0834e429b942 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Wed, 15 Jan 2025 09:57:26 -0800
Subject: [PATCH 1/7] [libc] check a few syscall #'s to avoid wrong syscalls

When cross compiling, llvm-libc currently has build hermeticity issues. It
looks at the host's sysroot, which for cross compiling is a big no-no. In
particular, the system call numbers for the Linux kernel may be different
between different architectures.

I wasted a day debugging segfaults running our hermetic tests cross compiled
for aarch64 because of this. In particular, the startup code tries to allocate
thread local storage using a raw syscall to mmap and assign the return value
to tpidr_el0 (thread pointer for exception level zero (userspace)). Later, upon
first access to any thread local variable, we segfault. When we have the
syscall number wrong, __NR_mmap from my x86_64 host is used (9) rather than the
expected (222) when targeting aarch64, which is interpreted by the kernel as a
call to lgetxattr rather than mmap. The kernel returns -EFAULT which is stored
in tpidr_el0, which now contains the wrong base later used by the compiler to
access thread local variables.

This patch does not fix the build hermiticity issues with llvm-libc. Instead it
adds a check to the startup code to try to catch these kinds of footguns in the
future.
---
 .../src/__support/OSUtil/linux/CMakeLists.txt |  8 ++++
 .../OSUtil/linux/cross_compile_clippy.h       | 45 +++++++++++++++++++
 libc/startup/linux/CMakeLists.txt             |  3 +-
 libc/startup/linux/do_start.h                 |  1 +
 4 files changed, 56 insertions(+), 1 deletion(-)
 create mode 100644 libc/src/__support/OSUtil/linux/cross_compile_clippy.h

diff --git a/libc/src/__support/OSUtil/linux/CMakeLists.txt b/libc/src/__support/OSUtil/linux/CMakeLists.txt
index 6c7014940407d8..08e779e75fd9d1 100644
--- a/libc/src/__support/OSUtil/linux/CMakeLists.txt
+++ b/libc/src/__support/OSUtil/linux/CMakeLists.txt
@@ -53,3 +53,11 @@ add_object_library(
     libc.src.errno.errno
     libc.src.sys.auxv.getauxval
 )
+
+add_header_library(
+  cross_compile_clippy
+  HDRS
+    cross_compile_clippy.h
+  DEPENDS
+  libc.src.__support.macros.properties.architectures
+)
diff --git a/libc/src/__support/OSUtil/linux/cross_compile_clippy.h b/libc/src/__support/OSUtil/linux/cross_compile_clippy.h
new file mode 100644
index 00000000000000..5ae796c60ac3ce
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/cross_compile_clippy.h
@@ -0,0 +1,45 @@
+//===-------------- Simple checks for cross compilation -------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_CROSS_COMPILE_CLIPPY_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_CROSS_COMPILE_CLIPPY_H
+
+
+#include "src/__support/macros/properties/architectures.h"
+#include <sys/syscall.h>
+
+#define MSG "Looks like you may be using the host kernel headers to cross " \
+  "compile. This is bad because the syscall numbers frequently (but not " \
+  "always) differ between architectures.  What frequently happens as a " \
+  "result are crashes in startup."
+
+// https://github.com/hrw/syscalls-table is super helpful for trying to find
+// syscalls with unique numbers.
+
+#ifdef LIBC_TARGET_ARCH_IS_AARCH64
+static_assert(__NR_renameat == 38, MSG);
+#elif defined(LIBC_TARGET_ARCH_IS_ARM)
+static_assert(__NR_renameat == 329, MSG);
+#elif defined(LIBC_TARGET_ARCH_IS_X86_32)
+static_assert(__NR_renameat == 302, MSG);
+#elif defined(LIBC_TARGET_ARCH_IS_X86_64)
+static_assert(__NR_renameat == 264, MSG);
+#elif defined(LIBC_TARGET_ARCH_IS_RISCV64)
+static_assert(__NR_riscv_flush_icache == 259, MSG);
+static_assert(__NR_renameat2 == 276, MSG);
+#elif defined(LIBC_TARGET_ARCH_IS_RISCV32)
+static_assert(__NR_riscv_flush_icache == 259, MSG);
+#ifdef __NR_iodestroy
+#error MSG
+#endif
+#else
+#error "Missing cross compile check for new arch"
+#endif
+
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_CROSS_COMPILE_CLIPPY_H
diff --git a/libc/startup/linux/CMakeLists.txt b/libc/startup/linux/CMakeLists.txt
index eaa724e41f1685..d92d261fa20d8b 100644
--- a/libc/startup/linux/CMakeLists.txt
+++ b/libc/startup/linux/CMakeLists.txt
@@ -99,8 +99,9 @@ add_object_library(
     libc.include.sys_mman
     libc.include.sys_syscall
     libc.include.llvm-libc-macros.link_macros
-    libc.src.__support.threads.thread
+    libc.src.__support.OSUtil.linux.cross_compile_clippy
     libc.src.__support.OSUtil.osutil
+    libc.src.__support.threads.thread
     libc.src.stdlib.exit
     libc.src.stdlib.atexit
     libc.src.unistd.environ
diff --git a/libc/startup/linux/do_start.h b/libc/startup/linux/do_start.h
index 8fc8c3716f2ac0..29e642b9dbc9cc 100644
--- a/libc/startup/linux/do_start.h
+++ b/libc/startup/linux/do_start.h
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "config/app.h"
+#include "src/__support/OSUtil/linux/cross_compile_clippy.h"
 #include "src/__support/macros/config.h"
 
 namespace LIBC_NAMESPACE_DECL {

>From 8628ef9b3f3456a342e6dc737b7a856361a76998 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Wed, 15 Jan 2025 10:37:17 -0800
Subject: [PATCH 2/7] fixup

---
 libc/src/__support/OSUtil/linux/cross_compile_clippy.h | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/libc/src/__support/OSUtil/linux/cross_compile_clippy.h b/libc/src/__support/OSUtil/linux/cross_compile_clippy.h
index 5ae796c60ac3ce..7ddf20b5bfe960 100644
--- a/libc/src/__support/OSUtil/linux/cross_compile_clippy.h
+++ b/libc/src/__support/OSUtil/linux/cross_compile_clippy.h
@@ -9,13 +9,13 @@
 #ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_CROSS_COMPILE_CLIPPY_H
 #define LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_CROSS_COMPILE_CLIPPY_H
 
-
 #include "src/__support/macros/properties/architectures.h"
 #include <sys/syscall.h>
 
-#define MSG "Looks like you may be using the host kernel headers to cross " \
-  "compile. This is bad because the syscall numbers frequently (but not " \
-  "always) differ between architectures.  What frequently happens as a " \
+#define MSG                                                                    \
+  "Looks like you may be using the host kernel headers to cross "              \
+  "compile. This is bad because the syscall numbers frequently (but not "      \
+  "always) differ between architectures.  What frequently happens as a "       \
   "result are crashes in startup."
 
 // https://github.com/hrw/syscalls-table is super helpful for trying to find
@@ -41,5 +41,4 @@ static_assert(__NR_riscv_flush_icache == 259, MSG);
 #error "Missing cross compile check for new arch"
 #endif
 
-
 #endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_CROSS_COMPILE_CLIPPY_H

>From fb00dd727a79f4d3f79366763367517801d7dadd Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Fri, 17 Jan 2025 08:39:10 -0800
Subject: [PATCH 3/7] fix indentation

---
 libc/src/__support/OSUtil/linux/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/src/__support/OSUtil/linux/CMakeLists.txt b/libc/src/__support/OSUtil/linux/CMakeLists.txt
index 08e779e75fd9d1..d0e328aa1a231e 100644
--- a/libc/src/__support/OSUtil/linux/CMakeLists.txt
+++ b/libc/src/__support/OSUtil/linux/CMakeLists.txt
@@ -59,5 +59,5 @@ add_header_library(
   HDRS
     cross_compile_clippy.h
   DEPENDS
-  libc.src.__support.macros.properties.architectures
+    libc.src.__support.macros.properties.architectures
 )

>From 7a5963fca8bc2a0a43cba91eb74137da65eba0f7 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Fri, 17 Jan 2025 08:46:48 -0800
Subject: [PATCH 4/7] convert to preprocessor, add comment

---
 .../OSUtil/linux/cross_compile_clippy.h       | 26 +++++++------------
 1 file changed, 9 insertions(+), 17 deletions(-)

diff --git a/libc/src/__support/OSUtil/linux/cross_compile_clippy.h b/libc/src/__support/OSUtil/linux/cross_compile_clippy.h
index 7ddf20b5bfe960..d9909b7f88c3c7 100644
--- a/libc/src/__support/OSUtil/linux/cross_compile_clippy.h
+++ b/libc/src/__support/OSUtil/linux/cross_compile_clippy.h
@@ -21,24 +21,16 @@
 // https://github.com/hrw/syscalls-table is super helpful for trying to find
 // syscalls with unique numbers.
 
-#ifdef LIBC_TARGET_ARCH_IS_AARCH64
-static_assert(__NR_renameat == 38, MSG);
-#elif defined(LIBC_TARGET_ARCH_IS_ARM)
-static_assert(__NR_renameat == 329, MSG);
-#elif defined(LIBC_TARGET_ARCH_IS_X86_32)
-static_assert(__NR_renameat == 302, MSG);
-#elif defined(LIBC_TARGET_ARCH_IS_X86_64)
-static_assert(__NR_renameat == 264, MSG);
-#elif defined(LIBC_TARGET_ARCH_IS_RISCV64)
-static_assert(__NR_riscv_flush_icache == 259, MSG);
-static_assert(__NR_renameat2 == 276, MSG);
-#elif defined(LIBC_TARGET_ARCH_IS_RISCV32)
-static_assert(__NR_riscv_flush_icache == 259, MSG);
-#ifdef __NR_iodestroy
+// As of Linux 6.12.10, 32b RISCV does not define __NR_iodestroy.
+#if (defined(LIBC_TARGET_ARCH_IS_AARCH64) && (__NR_renameat) != 38) || \
+    (defined(LIBC_TARGET_ARCH_IS_ARM) && (__NR_renameat) != 329) || \
+    (defined(LIBC_TARGET_ARCH_IS_X86_32) && (__NR_renameat) != 302) || \
+    (defined(LIBC_TARGET_ARCH_IS_X86_64) && (__NR_renameat) != 264) || \
+    (defined(LIBC_TARGET_ARCH_IS_RISCV64) && \
+      (__NR_riscv_flush_icache) != 259 && (__NR_renameat2) != 276) || \
+    (defined(LIBC_TARGET_ARCH_IS_RISCV32) && \
+      (__NR_riscv_flush_icache) != 259 && !defined(__NR_iodestroy))
 #error MSG
 #endif
-#else
-#error "Missing cross compile check for new arch"
-#endif
 
 #endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_CROSS_COMPILE_CLIPPY_H

>From 869bd514d92a2fa704d702881c94444b305f6040 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Fri, 17 Jan 2025 10:45:23 -0800
Subject: [PATCH 5/7] reformat

---
 .../OSUtil/linux/cross_compile_clippy.h          | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/libc/src/__support/OSUtil/linux/cross_compile_clippy.h b/libc/src/__support/OSUtil/linux/cross_compile_clippy.h
index d9909b7f88c3c7..a31def58b945a6 100644
--- a/libc/src/__support/OSUtil/linux/cross_compile_clippy.h
+++ b/libc/src/__support/OSUtil/linux/cross_compile_clippy.h
@@ -22,14 +22,14 @@
 // syscalls with unique numbers.
 
 // As of Linux 6.12.10, 32b RISCV does not define __NR_iodestroy.
-#if (defined(LIBC_TARGET_ARCH_IS_AARCH64) && (__NR_renameat) != 38) || \
-    (defined(LIBC_TARGET_ARCH_IS_ARM) && (__NR_renameat) != 329) || \
-    (defined(LIBC_TARGET_ARCH_IS_X86_32) && (__NR_renameat) != 302) || \
-    (defined(LIBC_TARGET_ARCH_IS_X86_64) && (__NR_renameat) != 264) || \
-    (defined(LIBC_TARGET_ARCH_IS_RISCV64) && \
-      (__NR_riscv_flush_icache) != 259 && (__NR_renameat2) != 276) || \
-    (defined(LIBC_TARGET_ARCH_IS_RISCV32) && \
-      (__NR_riscv_flush_icache) != 259 && !defined(__NR_iodestroy))
+#if (defined(LIBC_TARGET_ARCH_IS_AARCH64) && (__NR_renameat) != 38) ||         \
+    (defined(LIBC_TARGET_ARCH_IS_ARM) && (__NR_renameat) != 329) ||            \
+    (defined(LIBC_TARGET_ARCH_IS_X86_32) && (__NR_renameat) != 302) ||         \
+    (defined(LIBC_TARGET_ARCH_IS_X86_64) && (__NR_renameat) != 264) ||         \
+    (defined(LIBC_TARGET_ARCH_IS_RISCV64) &&                                   \
+     (__NR_riscv_flush_icache) != 259 && (__NR_renameat2) != 276) ||           \
+    (defined(LIBC_TARGET_ARCH_IS_RISCV32) &&                                   \
+     (__NR_riscv_flush_icache) != 259 && !defined(__NR_iodestroy))
 #error MSG
 #endif
 

>From 290366b55c8e6c7196baccbaa8eea3246462e2cb Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Fri, 17 Jan 2025 13:38:27 -0800
Subject: [PATCH 6/7] fix up printing MSG

---
 .../__support/OSUtil/linux/cross_compile_clippy.h   | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/libc/src/__support/OSUtil/linux/cross_compile_clippy.h b/libc/src/__support/OSUtil/linux/cross_compile_clippy.h
index a31def58b945a6..6c34be08ba0613 100644
--- a/libc/src/__support/OSUtil/linux/cross_compile_clippy.h
+++ b/libc/src/__support/OSUtil/linux/cross_compile_clippy.h
@@ -12,12 +12,6 @@
 #include "src/__support/macros/properties/architectures.h"
 #include <sys/syscall.h>
 
-#define MSG                                                                    \
-  "Looks like you may be using the host kernel headers to cross "              \
-  "compile. This is bad because the syscall numbers frequently (but not "      \
-  "always) differ between architectures.  What frequently happens as a "       \
-  "result are crashes in startup."
-
 // https://github.com/hrw/syscalls-table is super helpful for trying to find
 // syscalls with unique numbers.
 
@@ -30,7 +24,12 @@
      (__NR_riscv_flush_icache) != 259 && (__NR_renameat2) != 276) ||           \
     (defined(LIBC_TARGET_ARCH_IS_RISCV32) &&                                   \
      (__NR_riscv_flush_icache) != 259 && !defined(__NR_iodestroy))
-#error MSG
+
+// This is bad because the syscall numbers frequently (but not always) differ
+// between architectures.  What frequently happens as a result are crashes in
+// startup."
+#error "Host kernel headers cannot be used to cross compile"
+
 #endif
 
 #endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_CROSS_COMPILE_CLIPPY_H

>From 0aa54c5798ca237445f201634b8cfa8a93b91cc9 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Fri, 17 Jan 2025 13:39:58 -0800
Subject: [PATCH 7/7] remove trailing double quote

---
 libc/src/__support/OSUtil/linux/cross_compile_clippy.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/src/__support/OSUtil/linux/cross_compile_clippy.h b/libc/src/__support/OSUtil/linux/cross_compile_clippy.h
index 6c34be08ba0613..a57152d89df5da 100644
--- a/libc/src/__support/OSUtil/linux/cross_compile_clippy.h
+++ b/libc/src/__support/OSUtil/linux/cross_compile_clippy.h
@@ -27,7 +27,7 @@
 
 // This is bad because the syscall numbers frequently (but not always) differ
 // between architectures.  What frequently happens as a result are crashes in
-// startup."
+// startup.
 #error "Host kernel headers cannot be used to cross compile"
 
 #endif



More information about the libc-commits mailing list