[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
Wed Jan 15 10:37:29 PST 2025


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

>From 10ca093c1329ec0f7cd14ea611e87b7c1dca5dd0 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/2] [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 ea1d2872ed7eaeea4314c96da4576027f94b360a 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/2] 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



More information about the libc-commits mailing list