[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