Skip to content

Commit 3d0ed4a

Browse files
committed
Refactor panic_unwind/seh.rs pointer use; x86 now conforms to strict-provenance
1 parent d009f60 commit 3d0ed4a

File tree

2 files changed

+65
-41
lines changed

2 files changed

+65
-41
lines changed

library/panic_unwind/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#![feature(panic_unwind)]
2020
#![feature(staged_api)]
2121
#![feature(std_internals)]
22+
#![feature(strict_provenance)]
23+
#![feature(exposed_provenance)]
2224
#![feature(rustc_attrs)]
2325
#![panic_runtime]
2426
#![feature(panic_runtime)]

library/panic_unwind/src/seh.rs

+63-41
Original file line numberDiff line numberDiff line change
@@ -109,58 +109,80 @@ struct Exception {
109109
// [1]: https://www.geoffchappell.com/studies/msvc/language/predefined/
110110

111111
#[cfg(target_arch = "x86")]
112-
#[macro_use]
113112
mod imp {
114-
pub type ptr_t = *mut u8;
115-
116-
macro_rules! ptr {
117-
(0) => {
118-
core::ptr::null_mut()
119-
};
120-
($e:expr) => {
121-
$e as *mut u8
122-
};
113+
#[repr(transparent)]
114+
#[derive(Copy, Clone)]
115+
pub struct ptr_t(*mut u8);
116+
117+
impl ptr_t {
118+
pub const fn null() -> Self {
119+
Self(core::ptr::null_mut())
120+
}
121+
122+
pub const fn new(ptr: *mut u8) -> Self {
123+
Self(ptr)
124+
}
123125
}
124126
}
125127

126128
#[cfg(not(target_arch = "x86"))]
127-
#[macro_use]
128129
mod imp {
129-
pub type ptr_t = u32;
130+
use core::ptr::addr_of;
131+
132+
// On 64-bit systems, SEH represents pointers as 32-bit offsets from `__ImageBase`.
133+
#[repr(transparent)]
134+
#[derive(Copy, Clone)]
135+
pub struct ptr_t(u32);
130136

131137
extern "C" {
132138
pub static __ImageBase: u8;
133139
}
134140

135-
macro_rules! ptr {
136-
(0) => (0);
137-
($e:expr) => {
138-
(($e as usize) - (addr_of!(imp::__ImageBase) as usize)) as u32
141+
impl ptr_t {
142+
pub const fn null() -> Self {
143+
Self(0)
144+
}
145+
146+
pub fn new(ptr: *mut u8) -> Self {
147+
// We need to expose the provenance of the pointer because it is not carried by
148+
// the `u32`, while the FFI needs to have this provenance to excess our statics.
149+
//
150+
// NOTE(niluxv): we could use `MaybeUninit<u32>` instead to leak the provenance
151+
// into the FFI. In theory then the other side would need to do some processing
152+
// to get a pointer with correct provenance, but these system functions aren't
153+
// going to be cross-lang LTOed anyway. However, using expose is shorter and
154+
// requires less unsafe.
155+
let addr: usize = ptr.expose_provenance();
156+
let image_base = unsafe { addr_of!(__ImageBase) }.addr();
157+
let offset: usize = addr - image_base;
158+
Self(offset as u32)
139159
}
140160
}
141161
}
142162

163+
use imp::ptr_t;
164+
143165
#[repr(C)]
144166
pub struct _ThrowInfo {
145167
pub attributes: c_uint,
146-
pub pmfnUnwind: imp::ptr_t,
147-
pub pForwardCompat: imp::ptr_t,
148-
pub pCatchableTypeArray: imp::ptr_t,
168+
pub pmfnUnwind: ptr_t,
169+
pub pForwardCompat: ptr_t,
170+
pub pCatchableTypeArray: ptr_t,
149171
}
150172

151173
#[repr(C)]
152174
pub struct _CatchableTypeArray {
153175
pub nCatchableTypes: c_int,
154-
pub arrayOfCatchableTypes: [imp::ptr_t; 1],
176+
pub arrayOfCatchableTypes: [ptr_t; 1],
155177
}
156178

157179
#[repr(C)]
158180
pub struct _CatchableType {
159181
pub properties: c_uint,
160-
pub pType: imp::ptr_t,
182+
pub pType: ptr_t,
161183
pub thisDisplacement: _PMD,
162184
pub sizeOrOffset: c_int,
163-
pub copyFunction: imp::ptr_t,
185+
pub copyFunction: ptr_t,
164186
}
165187

166188
#[repr(C)]
@@ -186,20 +208,20 @@ const TYPE_NAME: [u8; 11] = *b"rust_panic\0";
186208

187209
static mut THROW_INFO: _ThrowInfo = _ThrowInfo {
188210
attributes: 0,
189-
pmfnUnwind: ptr!(0),
190-
pForwardCompat: ptr!(0),
191-
pCatchableTypeArray: ptr!(0),
211+
pmfnUnwind: ptr_t::null(),
212+
pForwardCompat: ptr_t::null(),
213+
pCatchableTypeArray: ptr_t::null(),
192214
};
193215

194216
static mut CATCHABLE_TYPE_ARRAY: _CatchableTypeArray =
195-
_CatchableTypeArray { nCatchableTypes: 1, arrayOfCatchableTypes: [ptr!(0)] };
217+
_CatchableTypeArray { nCatchableTypes: 1, arrayOfCatchableTypes: [ptr_t::null()] };
196218

197219
static mut CATCHABLE_TYPE: _CatchableType = _CatchableType {
198220
properties: 0,
199-
pType: ptr!(0),
221+
pType: ptr_t::null(),
200222
thisDisplacement: _PMD { mdisp: 0, pdisp: -1, vdisp: 0 },
201223
sizeOrOffset: mem::size_of::<Exception>() as c_int,
202-
copyFunction: ptr!(0),
224+
copyFunction: ptr_t::null(),
203225
};
204226

205227
extern "C" {
@@ -246,9 +268,9 @@ macro_rules! define_cleanup {
246268
super::__rust_drop_panic();
247269
}
248270
}
249-
unsafe extern $abi2 fn exception_copy(_dest: *mut Exception,
250-
_src: *mut Exception)
251-
-> *mut Exception {
271+
unsafe extern $abi2 fn exception_copy(
272+
_dest: *mut Exception, _src: *mut Exception
273+
) -> *mut Exception {
252274
panic!("Rust panics cannot be copied");
253275
}
254276
}
@@ -296,24 +318,24 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
296318
// In any case, we basically need to do something like this until we can
297319
// express more operations in statics (and we may never be able to).
298320
atomic_store_seqcst(
299-
addr_of_mut!(THROW_INFO.pmfnUnwind) as *mut u32,
300-
ptr!(exception_cleanup) as u32,
321+
addr_of_mut!(THROW_INFO.pmfnUnwind).cast(),
322+
ptr_t::new(exception_cleanup as *mut u8),
301323
);
302324
atomic_store_seqcst(
303-
addr_of_mut!(THROW_INFO.pCatchableTypeArray) as *mut u32,
304-
ptr!(addr_of!(CATCHABLE_TYPE_ARRAY)) as u32,
325+
addr_of_mut!(THROW_INFO.pCatchableTypeArray).cast(),
326+
ptr_t::new(addr_of_mut!(CATCHABLE_TYPE_ARRAY).cast()),
305327
);
306328
atomic_store_seqcst(
307-
addr_of_mut!(CATCHABLE_TYPE_ARRAY.arrayOfCatchableTypes[0]) as *mut u32,
308-
ptr!(addr_of!(CATCHABLE_TYPE)) as u32,
329+
addr_of_mut!(CATCHABLE_TYPE_ARRAY.arrayOfCatchableTypes[0]).cast(),
330+
ptr_t::new(addr_of_mut!(CATCHABLE_TYPE).cast()),
309331
);
310332
atomic_store_seqcst(
311-
addr_of_mut!(CATCHABLE_TYPE.pType) as *mut u32,
312-
ptr!(addr_of!(TYPE_DESCRIPTOR)) as u32,
333+
addr_of_mut!(CATCHABLE_TYPE.pType).cast(),
334+
ptr_t::new(addr_of_mut!(TYPE_DESCRIPTOR).cast()),
313335
);
314336
atomic_store_seqcst(
315-
addr_of_mut!(CATCHABLE_TYPE.copyFunction) as *mut u32,
316-
ptr!(exception_copy) as u32,
337+
addr_of_mut!(CATCHABLE_TYPE.copyFunction).cast(),
338+
ptr_t::new(exception_copy as *mut u8),
317339
);
318340

319341
extern "system-unwind" {

0 commit comments

Comments
 (0)