[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