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

via libc-commits libc-commits at lists.llvm.org
Wed Jan 15 10:09:39 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libc

Author: Nick Desaulniers (nickdesaulniers)

<details>
<summary>Changes</summary>

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.


---
Full diff: https://github.com/llvm/llvm-project/pull/123100.diff


4 Files Affected:

- (modified) libc/src/__support/OSUtil/linux/CMakeLists.txt (+8) 
- (added) libc/src/__support/OSUtil/linux/cross_compile_clippy.h (+45) 
- (modified) libc/startup/linux/CMakeLists.txt (+2-1) 
- (modified) libc/startup/linux/do_start.h (+1) 


``````````diff
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 {

``````````

</details>


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


More information about the libc-commits mailing list