[libc-commits] [libc] [libc] fortify jmp buffer for x86-64 (PR #112769)

Simon Tatham via libc-commits libc-commits at lists.llvm.org
Fri Oct 18 08:50:58 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"
----------------
statham-arm wrote:

Checking integrity is also a well studied cryptographic problem, just as much as encryption to hide information. If the aim is to protect against an attacker, the question is: how easy is it to make a controlled change to the `jmp_buf` and update the hash value so that the check passes?

The switching between XOR and multiplication makes it not immediately obvious, but I'm sure a cryptanalyst would be able to find a break.

I do understand that you're trying to balance having _some_ protection against not losing too much speed. So I'm not saying you should switch over to AES and HMAC. But I do think you should write down your reasoning in a comment alongside the algorithm itself.

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


More information about the libc-commits mailing list