[libc-commits] [libc] [libc] fortify jmp buffer for x86-64 (PR #112769)
Nick Desaulniers via libc-commits
libc-commits at lists.llvm.org
Thu Oct 17 14:28:17 PDT 2024
================
@@ -8,35 +8,83 @@
#include "src/setjmp/longjmp.h"
#include "include/llvm-libc-macros/offsetof-macro.h"
+#include "src/__support/OSUtil/io.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
+#include "src/setjmp/checksum.h"
+#include "src/stdlib/abort.h"
#if !defined(LIBC_TARGET_ARCH_IS_X86_64)
#error "Invalid file include"
#endif
namespace LIBC_NAMESPACE_DECL {
+#if LIBC_COPT_SETJMP_ENABLE_FORTIFICATION
+extern "C" [[gnu::cold, noreturn]] void __libc_jmpbuf_corruption() {
+ write_to_stderr("invalid checksum detected in longjmp\n");
+ abort();
+}
+#define LOAD_CHKSUM_STATE_REGISTERS() \
+ asm("mov %0, %%rcx\n\t" ::"m"(jmpbuf::value_mask) : "rcx"); \
+ asm("mov %0, %%rdx\n\t" ::"m"(jmpbuf::checksum_cookie) : "rdx");
+
+#define RESTORE_REG(DST) \
+ "movq %c[" #DST "](%%rdi), %%rax\n\t" \
+ "movq %%rax, %%" #DST "\n\t" \
+ "xor %%rcx, %%" #DST "\n\t" \
+ "mul %%rdx\n\t" \
+ "xor %%rax, %%rdx\n\t" \
+ "rol $%c[rotation], %%rdx\n\t"
+
+#define RESTORE_RIP() \
+ "movq %c[rip](%%rdi), %%rax\n\t" \
+ "xor %%rax, %%rcx\n\t" \
+ "mul %%rdx\n\t" \
+ "xor %%rax, %%rdx\n\t" \
+ "rol $%c[rotation], %%rdx\n\t" \
+ "cmp %c[chksum](%%rdi), %%rdx\n\t" \
+ "jne __libc_jmpbuf_corruption\n\t" \
+ "cmpl $0x1, %%esi\n\t" \
+ "adcl $0x0, %%esi\n\t" \
+ "movq %%rsi, %%rax\n\t" \
+ "jmp *%%rcx\n\t"
+#else
+#define LOAD_CHKSUM_STATE_REGISTERS()
+#define RESTORE_REG(DST) "movq %c[" #DST "](%%rdi), %%" #DST "\n\t"
+#define RESTORE_RIP() \
+ "cmpl $0x1, %%esi\n\t" \
+ "adcl $0x0, %%esi\n\t" \
+ "movq %%rsi, %%rax\n\t" \
----------------
nickdesaulniers wrote:
These three instructions aren't logically part of restoring the instruction pointer; they're for setting the "return value." This is apparent in how the instruction sequences do not differ between whether LIBC_COPT_SETJMP_ENABLE_FORTIFICATION is set or not.
https://github.com/llvm/llvm-project/pull/112769
More information about the libc-commits
mailing list