diff options
Diffstat (limited to 'devel/wasmer/files/patch-rust-1.89.0')
-rw-r--r-- | devel/wasmer/files/patch-rust-1.89.0 | 471 |
1 files changed, 0 insertions, 471 deletions
diff --git a/devel/wasmer/files/patch-rust-1.89.0 b/devel/wasmer/files/patch-rust-1.89.0 deleted file mode 100644 index 0baa5c9f6fcc..000000000000 --- a/devel/wasmer/files/patch-rust-1.89.0 +++ /dev/null @@ -1,471 +0,0 @@ -https://github.com/wasmerio/wasmer/issues/5610 -https://github.com/wasmerio/wasmer/pull/5690 - - -From fc021be5c6f30ff0625d0fe8bd37a7d0ead6b0e9 Mon Sep 17 00:00:00 2001 -From: StackOverflowExcept1on - <109800286+StackOverflowExcept1on@users.noreply.github.com> -Date: Thu, 7 Aug 2025 17:50:19 +0300 -Subject: [PATCH] fix(lib/vm): vendor `compiler-builtins` to fix undefined - symbol `__rust_probestack` - ---- - Cargo.lock | 1 + - lib/vm/Cargo.toml | 4 + - lib/vm/build.rs | 7 + - lib/vm/src/probestack/compiler_builtins.rs | 358 ++++++++++++++++++ - .../src/{probestack.rs => probestack/mod.rs} | 20 +- - 5 files changed, 386 insertions(+), 4 deletions(-) - create mode 100644 lib/vm/build.rs - create mode 100644 lib/vm/src/probestack/compiler_builtins.rs - rename lib/vm/src/{probestack.rs => probestack/mod.rs} (77%) - -diff --git Cargo.lock Cargo.lock -index 2d980929125..c554ac0997f 100644 ---- Cargo.lock -+++ Cargo.lock -@@ -7240,6 +7240,7 @@ dependencies = [ - "memoffset 0.9.1", - "more-asserts", - "region", -+ "rustversion", - "scopeguard", - "serde", - "thiserror 1.0.69", -diff --git lib/vm/Cargo.toml lib/vm/Cargo.toml -index 6c9f5cbee87..e7a40580a80 100644 ---- lib/vm/Cargo.toml -+++ lib/vm/Cargo.toml -@@ -49,10 +49,14 @@ windows-sys = { version = "0.59", features = [ - - [build-dependencies] - cc = "1.0" -+rustversion = "1.0" - - [badges] - maintenance = { status = "actively-developed" } - -+[lints.rust] -+unexpected_cfgs = { level = "warn", check-cfg = ['cfg(missing_rust_probestack)'] } -+ - [features] - default = [] - enable-serde = ["serde", "indexmap/serde", "wasmer-types/enable-serde"] -diff --git lib/vm/build.rs lib/vm/build.rs -new file mode 100644 -index 00000000000..a2f1dcd8e8a ---- /dev/null -+++ lib/vm/build.rs -@@ -0,0 +1,7 @@ -+#[rustversion::since(1.89)] -+fn main() { -+ println!("cargo::rustc-cfg=missing_rust_probestack"); -+} -+ -+#[rustversion::before(1.89)] -+fn main() {} -diff --git lib/vm/src/probestack/compiler_builtins.rs lib/vm/src/probestack/compiler_builtins.rs -new file mode 100644 -index 00000000000..a16c1069f58 ---- /dev/null -+++ lib/vm/src/probestack/compiler_builtins.rs -@@ -0,0 +1,358 @@ -+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -+// file at the top-level directory of this distribution and at -+// http://rust-lang.org/COPYRIGHT. -+// -+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -+// option. This file may not be copied, modified, or distributed -+// except according to those terms. -+ -+//! This module defines the `__rust_probestack` intrinsic which is used in the -+//! implementation of "stack probes" on certain platforms. -+//! -+//! The purpose of a stack probe is to provide a static guarantee that if a -+//! thread has a guard page then a stack overflow is guaranteed to hit that -+//! guard page. If a function did not have a stack probe then there's a risk of -+//! having a stack frame *larger* than the guard page, so a function call could -+//! skip over the guard page entirely and then later hit maybe the heap or -+//! another thread, possibly leading to security vulnerabilities such as [The -+//! Stack Clash], for example. -+//! -+//! [The Stack Clash]: https://blog.qualys.com/securitylabs/2017/06/19/the-stack-clash -+//! -+//! The `__rust_probestack` is called in the prologue of functions whose stack -+//! size is larger than the guard page, for example larger than 4096 bytes on -+//! x86. This function is then responsible for "touching" all pages relevant to -+//! the stack to ensure that that if any of them are the guard page we'll hit -+//! them guaranteed. -+//! -+//! The precise ABI for how this function operates is defined by LLVM. There's -+//! no real documentation as to what this is, so you'd basically need to read -+//! the LLVM source code for reference. Often though the test cases can be -+//! illuminating as to the ABI that's generated, or just looking at the output -+//! of `llc`. -+//! -+//! Note that `#[naked]` is typically used here for the stack probe because the -+//! ABI corresponds to no actual ABI. -+//! -+//! Finally it's worth noting that at the time of this writing LLVM only has -+//! support for stack probes on x86 and x86_64. There's no support for stack -+//! probes on any other architecture like ARM or PowerPC64. LLVM I'm sure would -+//! be more than welcome to accept such a change! -+ -+// Windows and Cygwin already has builtins to do this. -+#![cfg(not(any(windows, target_os = "cygwin")))] -+// We only define stack probing for these architectures today. -+#![cfg(any(target_arch = "x86_64", target_arch = "x86"))] -+ -+// SAFETY: defined in this module. -+// FIXME(extern_custom): the ABI is not correct. -+unsafe extern "C" { -+ pub fn __rust_probestack(); -+} -+ -+// A wrapper for our implementation of __rust_probestack, which allows us to -+// keep the assembly inline while controlling all CFI directives in the assembly -+// emitted for the function. -+// -+// This is the ELF version. -+#[cfg(not(any(target_vendor = "apple", target_os = "uefi")))] -+macro_rules! define_rust_probestack { -+ ($body: expr) => { -+ concat!( -+ " -+ .pushsection .text.__rust_probestack -+ .globl __rust_probestack -+ .type __rust_probestack, @function -+ .hidden __rust_probestack -+ __rust_probestack: -+ ", -+ $body, -+ " -+ .size __rust_probestack, . - __rust_probestack -+ .popsection -+ " -+ ) -+ }; -+} -+ -+#[cfg(all(target_os = "uefi", target_arch = "x86_64"))] -+macro_rules! define_rust_probestack { -+ ($body: expr) => { -+ concat!( -+ " -+ .globl __rust_probestack -+ __rust_probestack: -+ ", -+ $body -+ ) -+ }; -+} -+ -+// Same as above, but for Mach-O. Note that the triple underscore -+// is deliberate -+#[cfg(target_vendor = "apple")] -+macro_rules! define_rust_probestack { -+ ($body: expr) => { -+ concat!( -+ " -+ .globl ___rust_probestack -+ ___rust_probestack: -+ ", -+ $body -+ ) -+ }; -+} -+ -+// In UEFI x86 arch, triple underscore is deliberate. -+#[cfg(all(target_os = "uefi", target_arch = "x86"))] -+macro_rules! define_rust_probestack { -+ ($body: expr) => { -+ concat!( -+ " -+ .globl ___rust_probestack -+ ___rust_probestack: -+ ", -+ $body -+ ) -+ }; -+} -+ -+// Our goal here is to touch each page between %rsp+8 and %rsp+8-%rax, -+// ensuring that if any pages are unmapped we'll make a page fault. -+// -+// FIXME(abi_custom): This function is unsafe because it uses a custom ABI, -+// it does not actually match `extern "C"`. -+// -+// The ABI here is that the stack frame size is located in `%rax`. Upon -+// return we're not supposed to modify `%rsp` or `%rax`. -+// -+// Any changes to this function should be replicated to the SGX version below. -+#[cfg(all( -+ target_arch = "x86_64", -+ not(all(target_env = "sgx", target_vendor = "fortanix")) -+))] -+core::arch::global_asm!( -+ define_rust_probestack!( -+ " -+ .cfi_startproc -+ pushq %rbp -+ .cfi_adjust_cfa_offset 8 -+ .cfi_offset %rbp, -16 -+ movq %rsp, %rbp -+ .cfi_def_cfa_register %rbp -+ -+ mov %rax,%r11 // duplicate %rax as we're clobbering %r11 -+ -+ // Main loop, taken in one page increments. We're decrementing rsp by -+ // a page each time until there's less than a page remaining. We're -+ // guaranteed that this function isn't called unless there's more than a -+ // page needed. -+ // -+ // Note that we're also testing against `8(%rsp)` to account for the 8 -+ // bytes pushed on the stack orginally with our return address. Using -+ // `8(%rsp)` simulates us testing the stack pointer in the caller's -+ // context. -+ -+ // It's usually called when %rax >= 0x1000, but that's not always true. -+ // Dynamic stack allocation, which is needed to implement unsized -+ // rvalues, triggers stackprobe even if %rax < 0x1000. -+ // Thus we have to check %r11 first to avoid segfault. -+ cmp $0x1000,%r11 -+ jna 3f -+2: -+ sub $0x1000,%rsp -+ test %rsp,8(%rsp) -+ sub $0x1000,%r11 -+ cmp $0x1000,%r11 -+ ja 2b -+ -+3: -+ // Finish up the last remaining stack space requested, getting the last -+ // bits out of r11 -+ sub %r11,%rsp -+ test %rsp,8(%rsp) -+ -+ // Restore the stack pointer to what it previously was when entering -+ // this function. The caller will readjust the stack pointer after we -+ // return. -+ add %rax,%rsp -+ -+ leave -+ .cfi_def_cfa_register %rsp -+ .cfi_adjust_cfa_offset -8 -+ ret -+ .cfi_endproc -+ " -+ ), -+ options(att_syntax) -+); -+ -+// This function is the same as above, except that some instructions are -+// [manually patched for LVI]. -+// -+// [manually patched for LVI]: https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection#specialinstructions -+#[cfg(all( -+ target_arch = "x86_64", -+ all(target_env = "sgx", target_vendor = "fortanix") -+))] -+core::arch::global_asm!( -+ define_rust_probestack!( -+ " -+ .cfi_startproc -+ pushq %rbp -+ .cfi_adjust_cfa_offset 8 -+ .cfi_offset %rbp, -16 -+ movq %rsp, %rbp -+ .cfi_def_cfa_register %rbp -+ -+ mov %rax,%r11 // duplicate %rax as we're clobbering %r11 -+ -+ // Main loop, taken in one page increments. We're decrementing rsp by -+ // a page each time until there's less than a page remaining. We're -+ // guaranteed that this function isn't called unless there's more than a -+ // page needed. -+ // -+ // Note that we're also testing against `8(%rsp)` to account for the 8 -+ // bytes pushed on the stack orginally with our return address. Using -+ // `8(%rsp)` simulates us testing the stack pointer in the caller's -+ // context. -+ -+ // It's usually called when %rax >= 0x1000, but that's not always true. -+ // Dynamic stack allocation, which is needed to implement unsized -+ // rvalues, triggers stackprobe even if %rax < 0x1000. -+ // Thus we have to check %r11 first to avoid segfault. -+ cmp $0x1000,%r11 -+ jna 3f -+2: -+ sub $0x1000,%rsp -+ test %rsp,8(%rsp) -+ sub $0x1000,%r11 -+ cmp $0x1000,%r11 -+ ja 2b -+ -+3: -+ // Finish up the last remaining stack space requested, getting the last -+ // bits out of r11 -+ sub %r11,%rsp -+ test %rsp,8(%rsp) -+ -+ // Restore the stack pointer to what it previously was when entering -+ // this function. The caller will readjust the stack pointer after we -+ // return. -+ add %rax,%rsp -+ -+ leave -+ .cfi_def_cfa_register %rsp -+ .cfi_adjust_cfa_offset -8 -+ pop %r11 -+ lfence -+ jmp *%r11 -+ .cfi_endproc -+ " -+ ), -+ options(att_syntax) -+); -+ -+#[cfg(all(target_arch = "x86", not(target_os = "uefi")))] -+// This is the same as x86_64 above, only translated for 32-bit sizes. Note -+// that on Unix we're expected to restore everything as it was, this -+// function basically can't tamper with anything. -+// -+// FIXME(abi_custom): This function is unsafe because it uses a custom ABI, -+// it does not actually match `extern "C"`. -+// -+// The ABI here is the same as x86_64, except everything is 32-bits large. -+core::arch::global_asm!( -+ define_rust_probestack!( -+ " -+ .cfi_startproc -+ push %ebp -+ .cfi_adjust_cfa_offset 4 -+ .cfi_offset %ebp, -8 -+ mov %esp, %ebp -+ .cfi_def_cfa_register %ebp -+ push %ecx -+ mov %eax,%ecx -+ -+ cmp $0x1000,%ecx -+ jna 3f -+2: -+ sub $0x1000,%esp -+ test %esp,8(%esp) -+ sub $0x1000,%ecx -+ cmp $0x1000,%ecx -+ ja 2b -+ -+3: -+ sub %ecx,%esp -+ test %esp,8(%esp) -+ -+ add %eax,%esp -+ pop %ecx -+ leave -+ .cfi_def_cfa_register %esp -+ .cfi_adjust_cfa_offset -4 -+ ret -+ .cfi_endproc -+ " -+ ), -+ options(att_syntax) -+); -+ -+#[cfg(all(target_arch = "x86", target_os = "uefi"))] -+// UEFI target is windows like target. LLVM will do _chkstk things like windows. -+// probestack function will also do things like _chkstk in MSVC. -+// So we need to sub %ax %sp in probestack when arch is x86. -+// -+// FIXME(abi_custom): This function is unsafe because it uses a custom ABI, -+// it does not actually match `extern "C"`. -+// -+// REF: Rust commit(74e80468347) -+// rust\src\llvm-project\llvm\lib\Target\X86\X86FrameLowering.cpp: 805 -+// Comments in LLVM: -+// MSVC x32's _chkstk and cygwin/mingw's _alloca adjust %esp themselves. -+// MSVC x64's __chkstk and cygwin/mingw's ___chkstk_ms do not adjust %rsp -+// themselves. -+core::arch::global_asm!( -+ define_rust_probestack!( -+ " -+ .cfi_startproc -+ push %ebp -+ .cfi_adjust_cfa_offset 4 -+ .cfi_offset %ebp, -8 -+ mov %esp, %ebp -+ .cfi_def_cfa_register %ebp -+ push %ecx -+ push %edx -+ mov %eax,%ecx -+ -+ cmp $0x1000,%ecx -+ jna 3f -+2: -+ sub $0x1000,%esp -+ test %esp,8(%esp) -+ sub $0x1000,%ecx -+ cmp $0x1000,%ecx -+ ja 2b -+ -+3: -+ sub %ecx,%esp -+ test %esp,8(%esp) -+ mov 4(%ebp),%edx -+ mov %edx, 12(%esp) -+ add %eax,%esp -+ pop %edx -+ pop %ecx -+ leave -+ -+ sub %eax, %esp -+ .cfi_def_cfa_register %esp -+ .cfi_adjust_cfa_offset -4 -+ ret -+ .cfi_endproc -+ " -+ ), -+ options(att_syntax) -+); -diff --git lib/vm/src/probestack.rs lib/vm/src/probestack/mod.rs -similarity index 77% -rename from lib/vm/src/probestack.rs -rename to lib/vm/src/probestack/mod.rs -index 814ddf9c20c..84dfd22fb8a 100644 ---- lib/vm/src/probestack.rs -+++ lib/vm/src/probestack/mod.rs -@@ -14,6 +14,11 @@ - //! - //! [The Stack Clash]: https://blog.qualys.com/securitylabs/2017/06/19/the-stack-clash - -+// Based on `compiler-builtins` crate with changes in `#[cfg(...)]`: -+// https://raw.githubusercontent.com/rust-lang/compiler-builtins/319637f544d9dda8fc3dd482d9979e0da135a258/compiler-builtins/src/probestack.rs -+#[cfg(missing_rust_probestack)] -+mod compiler_builtins; -+ - // A declaration for the stack probe function in Rust's standard library, for - // catching callstack overflow. - cfg_if::cfg_if! { -@@ -55,10 +60,17 @@ cfg_if::cfg_if! { - /// A default probestack for other architectures - pub const PROBESTACK: unsafe extern "C" fn() = empty_probestack; - } else { -- extern "C" { -- pub fn __rust_probestack(); -+ cfg_if::cfg_if! { -+ if #[cfg(not(missing_rust_probestack))] { -+ extern "C" { -+ pub fn __rust_probestack(); -+ } -+ /// The probestack based on the Rust probestack -+ pub static PROBESTACK: unsafe extern "C" fn() = __rust_probestack; -+ } else if #[cfg(missing_rust_probestack)] { -+ /// The probestack based on the Rust probestack -+ pub static PROBESTACK: unsafe extern "C" fn() = compiler_builtins::__rust_probestack; -+ } - } -- /// The probestack based on the Rust probestack -- pub static PROBESTACK: unsafe extern "C" fn() = __rust_probestack; - } - } |