unix: Unsafe-wrap stack_overflow::{drop,make}_handler · model-checking/verify-rust-std@9e11e01 (original) (raw)

`@@ -206,34 +206,48 @@ mod imp {

`

206

206

` libc::stack_t { ss_sp: stackp, ss_flags: 0, ss_size: sigstack_size }

`

207

207

`}

`

208

208

``

``

209

`+

/// # Safety

`

``

210

`+

/// Mutates the alternate signal stack

`

``

211

`+

#[forbid(unsafe_op_in_unsafe_fn)]

`

209

212

`pub unsafe fn make_handler(main_thread: bool) -> Handler {

`

210

213

`if !NEED_ALTSTACK.load(Ordering::Relaxed) {

`

211

214

`return Handler::null();

`

212

215

`}

`

213

216

``

214

217

`if !main_thread {

`

215

218

`// Always write to GUARD to ensure the TLS variable is allocated.

`

216

``

`-

let guard = current_guard().unwrap_or(0..0);

`

``

219

`+

let guard = unsafe { current_guard() }.unwrap_or(0..0);

`

217

220

`GUARD.set((guard.start, guard.end));

`

218

221

`}

`

219

222

``

220

``

`-

let mut stack = mem::zeroed();

`

221

``

`-

sigaltstack(ptr::null(), &mut stack);

`

``

223

`+

// SAFETY: assuming stack_t is zero-initializable

`

``

224

`+

let mut stack = unsafe { mem::zeroed() };

`

``

225

`+

// SAFETY: reads current stack_t into stack

`

``

226

`+

unsafe { sigaltstack(ptr::null(), &mut stack) };

`

222

227

`// Configure alternate signal stack, if one is not already set.

`

223

228

`if stack.ss_flags & SS_DISABLE != 0 {

`

224

``

`-

stack = get_stack();

`

225

``

`-

sigaltstack(&stack, ptr::null_mut());

`

``

229

`+

// SAFETY: We warned our caller this would happen!

`

``

230

`+

unsafe {

`

``

231

`+

stack = get_stack();

`

``

232

`+

sigaltstack(&stack, ptr::null_mut());

`

``

233

`+

}

`

226

234

`Handler { data: stack.ss_sp as *mut libc::c_void }

`

227

235

`} else {

`

228

236

`Handler::null()

`

229

237

`}

`

230

238

`}

`

231

239

``

``

240

`+

/// # Safety

`

``

241

`+

/// Must be called

`

``

242

`+

/// - only with our handler or nullptr

`

``

243

`+

/// - only when done with our altstack

`

``

244

`+

/// This disables the alternate signal stack!

`

``

245

`+

#[forbid(unsafe_op_in_unsafe_fn)]

`

232

246

`pub unsafe fn drop_handler(data: *mut libc::c_void) {

`

233

247

`if !data.is_null() {

`

234

248

`let sigstack_size = sigstack_size();

`

235

249

`let page_size = PAGE_SIZE.load(Ordering::Relaxed);

`

236

``

`-

let stack = libc::stack_t {

`

``

250

`+

let disabling_stack = libc::stack_t {

`

237

251

`ss_sp: ptr::null_mut(),

`

238

252

`ss_flags: SS_DISABLE,

`

239

253

`// Workaround for bug in macOS implementation of sigaltstack

`

`@@ -242,10 +256,11 @@ mod imp {

`

242

256

`// both ss_sp and ss_size should be ignored in this case.

`

243

257

`ss_size: sigstack_size,

`

244

258

`};

`

245

``

`-

sigaltstack(&stack, ptr::null_mut());

`

246

``

`` -

// We know from get_stackp that the alternate stack we installed is part of a mapping

``

247

``

`-

// that started one page earlier, so walk back a page and unmap from there.

`

248

``

`-

munmap(data.sub(page_size), sigstack_size + page_size);

`

``

259

`+

// SAFETY: we warned the caller this disables the alternate signal stack!

`

``

260

`+

unsafe { sigaltstack(&disabling_stack, ptr::null_mut()) };

`

``

261

`` +

// SAFETY: We know from get_stackp that the alternate stack we installed is part of

``

``

262

`+

// a mapping that started one page earlier, so walk back a page and unmap from there.

`

``

263

`+

unsafe { munmap(data.sub(page_size), sigstack_size + page_size) };

`

249

264

`}

`

250

265

`}

`

251

266

``

`@@ -446,6 +461,7 @@ mod imp {

`

446

461

`}

`

447

462

``

448

463

`#[cfg(any(target_os = "macos", target_os = "openbsd", target_os = "solaris"))]

`

``

464

`+

// FIXME: I am probably not unsafe.

`

449

465

`unsafe fn current_guard() -> Option<Range> {

`

450

466

`let stackptr = get_stack_start()?;

`

451

467

`let stackaddr = stackptr.addr();

`

`@@ -460,6 +476,7 @@ mod imp {

`

460

476

` target_os = "netbsd",

`

461

477

` target_os = "l4re"

`

462

478

`))]

`

``

479

`+

// FIXME: I am probably not unsafe.

`

463

480

`unsafe fn current_guard() -> Option<Range> {

`

464

481

`let mut ret = None;

`

465

482

`let mut attr: libc::pthread_attr_t = crate::mem::zeroed();

`