|
| 1 | +From 4900a67c4daabedbf83b563d77830c3f1c6eb599 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Gilles Duboscq < [email protected]> |
| 3 | +Date: Wed, 23 Apr 2025 18:45:10 +0200 |
| 4 | +Subject: [PATCH 2/3] Add support __SANDBOX_SWCFI__ in unix64.S and win64.S |
| 5 | + |
| 6 | +This mode requires a software check for jump targets. |
| 7 | +--- |
| 8 | + src/x86/internal64.h | 4 +++ |
| 9 | + src/x86/unix64.S | 30 ++++++++++++++++++++ |
| 10 | + src/x86/win64.S | 65 +++++++++++++++++++++++++++++++++++++++++++- |
| 11 | + 3 files changed, 98 insertions(+), 1 deletion(-) |
| 12 | + |
| 13 | +diff --git a/src/x86/internal64.h b/src/x86/internal64.h |
| 14 | +index 282b408..7142645 100644 |
| 15 | +--- a/src/x86/internal64.h |
| 16 | ++++ b/src/x86/internal64.h |
| 17 | +@@ -29,7 +29,11 @@ |
| 18 | + #define UNIX64_TRAMP_MAP_SHIFT 12 |
| 19 | + #define UNIX64_TRAMP_MAP_SIZE (1 << UNIX64_TRAMP_MAP_SHIFT) |
| 20 | + #ifdef ENDBR_PRESENT |
| 21 | ++#ifdef __SANDBOX_SWCFI__ |
| 22 | ++#define UNIX64_TRAMP_SIZE 48 |
| 23 | ++#else |
| 24 | + #define UNIX64_TRAMP_SIZE 40 |
| 25 | ++#endif |
| 26 | + #else |
| 27 | + #define UNIX64_TRAMP_SIZE 32 |
| 28 | + #endif |
| 29 | +diff --git a/src/x86/unix64.S b/src/x86/unix64.S |
| 30 | +index d9c5bd4..10d9c8d 100644 |
| 31 | +--- a/src/x86/unix64.S |
| 32 | ++++ b/src/x86/unix64.S |
| 33 | +@@ -98,6 +98,13 @@ L(ret_from_load_sse): |
| 34 | + |
| 35 | + /* Deallocate the reg arg area, except for r10, then load via pop. */ |
| 36 | + leaq 0xb8(%r10), %rsp |
| 37 | ++#ifdef __SANDBOX_SWCFI__ |
| 38 | ++ movl (%r11), %r10d |
| 39 | ++ addl $0x5e1f00d, %r10d |
| 40 | ++ jz 1f |
| 41 | ++ int3 |
| 42 | ++1: |
| 43 | ++#endif |
| 44 | + popq %r10 |
| 45 | + |
| 46 | + /* Call the user function. */ |
| 47 | +@@ -126,6 +133,13 @@ L(UW2): |
| 48 | + #endif |
| 49 | + leaq (%r11, %r10, 8), %r10 |
| 50 | + |
| 51 | ++#ifdef __SANDBOX_SWCFI__ |
| 52 | ++ movl (%r10), %r11d |
| 53 | ++ addl $0x5e1f00d, %r11d |
| 54 | ++ jz 1f |
| 55 | ++ int3 |
| 56 | ++1: |
| 57 | ++#endif |
| 58 | + /* Prep for the structure cases: scratch area in redzone. */ |
| 59 | + leaq -20(%rsp), %rsi |
| 60 | + jmp *%r10 |
| 61 | +@@ -318,6 +332,13 @@ L(UW10): |
| 62 | + addl %r10d, %r10d |
| 63 | + #endif |
| 64 | + leaq (%r11, %r10, 8), %r10 |
| 65 | ++#ifdef __SANDBOX_SWCFI__ |
| 66 | ++ movl (%r10), %r11d |
| 67 | ++ addl $0x5e1f00d, %r11d |
| 68 | ++ jz 1f |
| 69 | ++ int3 |
| 70 | ++1: |
| 71 | ++#endif |
| 72 | + leaq ffi_closure_RED_RVALUE(%rsp), %rsi |
| 73 | + jmp *%r10 |
| 74 | + |
| 75 | +@@ -538,6 +559,15 @@ C(trampoline_code_table): |
| 76 | + movl X86_CODE_OFFSET(%rip), %r10d /* Copy code into %r10 */ |
| 77 | + #else |
| 78 | + movq X86_CODE_OFFSET(%rip), %r10 /* Copy code into %r10 */ |
| 79 | ++#endif |
| 80 | ++#ifdef __SANDBOX_SWCFI__ |
| 81 | ++ pushq %rdi |
| 82 | ++ movl (%r10), %edi |
| 83 | ++ addl $0x5e1f00d, %edi |
| 84 | ++ jz 1f |
| 85 | ++ int3 |
| 86 | ++1: |
| 87 | ++ popq %rdi |
| 88 | + #endif |
| 89 | + jmp *%r10 /* Jump to code */ |
| 90 | + .align 8 |
| 91 | +diff --git a/src/x86/win64.S b/src/x86/win64.S |
| 92 | +index 58ec6a1..d1a180a 100644 |
| 93 | +--- a/src/x86/win64.S |
| 94 | ++++ b/src/x86/win64.S |
| 95 | +@@ -27,7 +27,10 @@ |
| 96 | + actual table. The entry points into the table are all 8 bytes. |
| 97 | + The use of ORG asserts that we're at the correct location. */ |
| 98 | + /* ??? The clang assembler doesn't handle .org with symbolic expressions. */ |
| 99 | +-#if defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__)) |
| 100 | ++#ifdef __SANDBOX_SWCFI__ |
| 101 | ++/* Triple slot size to 24 byte to add ENDBR64 and jump for ret. */ |
| 102 | ++# define E(BASE, X) .balign 8; .org BASE + (X) * 24 |
| 103 | ++#elif defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__)) |
| 104 | + # define E(BASE, X) .balign 8 |
| 105 | + #else |
| 106 | + # define E(BASE, X) .balign 8; .org BASE + (X) * 8 |
| 107 | +@@ -73,18 +76,58 @@ C(ffi_call_win64): |
| 108 | + movq 24(%rsp), %r9 |
| 109 | + movsd 24(%rsp), %xmm3 |
| 110 | + |
| 111 | ++#ifdef __SANDBOX_SWCFI__ |
| 112 | ++ movq 16(%rbp), %r11 |
| 113 | ++ pushq %r10 |
| 114 | ++ movl (%r11), %r10d |
| 115 | ++ addl $0x5e1f00d, %r10d |
| 116 | ++ jz 1f |
| 117 | ++ int3 |
| 118 | ++1: |
| 119 | ++ popq %r10 |
| 120 | ++ call *%r11 |
| 121 | ++#else |
| 122 | + call *16(%rbp) |
| 123 | ++#endif |
| 124 | + |
| 125 | + movl 24(%rbp), %ecx |
| 126 | + movq 32(%rbp), %r8 |
| 127 | + leaq 0f(%rip), %r10 |
| 128 | + cmpl $FFI_TYPE_SMALL_STRUCT_4B, %ecx |
| 129 | ++ |
| 130 | ++#ifdef __SANDBOX_SWCFI__ |
| 131 | ++ /* avoid leave in this mode, use larger slots (3*8) */ |
| 132 | ++ ja 99f |
| 133 | ++ movl %ecx, %r11d |
| 134 | ++ addl %ecx, %ecx |
| 135 | ++ addl %r11d, %ecx |
| 136 | ++ leaq (%r10, %rcx, 8), %r10 |
| 137 | ++ movl (%r10), %ecx |
| 138 | ++ addl $0x5e1f00d, %ecx |
| 139 | ++ jz 1f |
| 140 | ++ int3 |
| 141 | ++1: |
| 142 | ++ jmp *%r10 |
| 143 | ++ |
| 144 | ++#define jmp_target \ |
| 145 | ++ _CET_ENDBR |
| 146 | ++#define epilogue \ |
| 147 | ++ movq %rbp, %rsp; \ |
| 148 | ++ popq %rbp; \ |
| 149 | ++ cfi_remember_state; \ |
| 150 | ++ cfi_def_cfa(%rsp, 8); \ |
| 151 | ++ cfi_restore(%rbp); \ |
| 152 | ++ ret; \ |
| 153 | ++ cfi_restore_state |
| 154 | ++#else |
| 155 | ++ |
| 156 | + leaq (%r10, %rcx, 8), %r10 |
| 157 | + ja 99f |
| 158 | + _CET_NOTRACK jmp *%r10 |
| 159 | + |
| 160 | + /* Below, we're space constrained most of the time. Thus we eschew the |
| 161 | + modern "mov, pop, ret" sequence (5 bytes) for "leave, ret" (2 bytes). */ |
| 162 | ++#define jmp_target |
| 163 | + #define epilogue \ |
| 164 | + leaveq; \ |
| 165 | + cfi_remember_state; \ |
| 166 | +@@ -92,66 +135,86 @@ C(ffi_call_win64): |
| 167 | + cfi_restore(%rbp); \ |
| 168 | + ret; \ |
| 169 | + cfi_restore_state |
| 170 | ++#endif |
| 171 | + |
| 172 | + .align 8 |
| 173 | + 0: |
| 174 | + E(0b, FFI_TYPE_VOID) |
| 175 | ++ jmp_target |
| 176 | + epilogue |
| 177 | + E(0b, FFI_TYPE_INT) |
| 178 | ++ jmp_target |
| 179 | + movslq %eax, %rax |
| 180 | + movq %rax, (%r8) |
| 181 | + epilogue |
| 182 | + E(0b, FFI_TYPE_FLOAT) |
| 183 | ++ jmp_target |
| 184 | + movss %xmm0, (%r8) |
| 185 | + epilogue |
| 186 | + E(0b, FFI_TYPE_DOUBLE) |
| 187 | ++ jmp_target |
| 188 | + movsd %xmm0, (%r8) |
| 189 | + epilogue |
| 190 | + // FFI_TYPE_LONGDOUBLE may be FFI_TYPE_DOUBLE but we need a different value here. |
| 191 | + E(0b, FFI_TYPE_DOUBLE + 1) |
| 192 | ++ jmp_target |
| 193 | + call PLT(C(abort)) |
| 194 | + E(0b, FFI_TYPE_UINT8) |
| 195 | ++ jmp_target |
| 196 | + movzbl %al, %eax |
| 197 | + movq %rax, (%r8) |
| 198 | + epilogue |
| 199 | + E(0b, FFI_TYPE_SINT8) |
| 200 | ++ jmp_target |
| 201 | + movsbq %al, %rax |
| 202 | + jmp 98f |
| 203 | + E(0b, FFI_TYPE_UINT16) |
| 204 | ++ jmp_target |
| 205 | + movzwl %ax, %eax |
| 206 | + movq %rax, (%r8) |
| 207 | + epilogue |
| 208 | + E(0b, FFI_TYPE_SINT16) |
| 209 | ++ jmp_target |
| 210 | + movswq %ax, %rax |
| 211 | + jmp 98f |
| 212 | + E(0b, FFI_TYPE_UINT32) |
| 213 | ++ jmp_target |
| 214 | + movl %eax, %eax |
| 215 | + movq %rax, (%r8) |
| 216 | + epilogue |
| 217 | + E(0b, FFI_TYPE_SINT32) |
| 218 | ++ jmp_target |
| 219 | + movslq %eax, %rax |
| 220 | + movq %rax, (%r8) |
| 221 | + epilogue |
| 222 | + E(0b, FFI_TYPE_UINT64) |
| 223 | ++ jmp_target |
| 224 | + 98: movq %rax, (%r8) |
| 225 | + epilogue |
| 226 | + E(0b, FFI_TYPE_SINT64) |
| 227 | ++ jmp_target |
| 228 | + movq %rax, (%r8) |
| 229 | + epilogue |
| 230 | + E(0b, FFI_TYPE_STRUCT) |
| 231 | ++ jmp_target |
| 232 | + epilogue |
| 233 | + E(0b, FFI_TYPE_POINTER) |
| 234 | ++ jmp_target |
| 235 | + movq %rax, (%r8) |
| 236 | + epilogue |
| 237 | + E(0b, FFI_TYPE_COMPLEX) |
| 238 | ++ jmp_target |
| 239 | + call PLT(C(abort)) |
| 240 | + E(0b, FFI_TYPE_SMALL_STRUCT_1B) |
| 241 | ++ jmp_target |
| 242 | + movb %al, (%r8) |
| 243 | + epilogue |
| 244 | + E(0b, FFI_TYPE_SMALL_STRUCT_2B) |
| 245 | ++ jmp_target |
| 246 | + movw %ax, (%r8) |
| 247 | + epilogue |
| 248 | + E(0b, FFI_TYPE_SMALL_STRUCT_4B) |
| 249 | ++ jmp_target |
| 250 | + movl %eax, (%r8) |
| 251 | + epilogue |
| 252 | + |
| 253 | +-- |
| 254 | +2.43.0 |
| 255 | + |
0 commit comments