From eadeedde425e5a8027cf745da233bf3de58419a9 Mon Sep 17 00:00:00 2001 From: 5225225 <5225225@mailbox.org> Date: Sun, 5 Dec 2021 13:54:25 +0000 Subject: [PATCH] Handle uninit data in pthread_condattr_destroy --- src/shims/posix/sync.rs | 12 ++++++++++- .../libc_pthread_condattr_double_destroy.rs | 19 ++++++++++++++++++ .../concurrency/pthread_condattr_init.rs | 20 +++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 tests/compile-fail/sync/libc_pthread_condattr_double_destroy.rs create mode 100644 tests/run-pass/concurrency/pthread_condattr_init.rs diff --git a/src/shims/posix/sync.rs b/src/shims/posix/sync.rs index 606f58a207e5..abf52a94e7e7 100644 --- a/src/shims/posix/sync.rs +++ b/src/shims/posix/sync.rs @@ -189,6 +189,14 @@ fn condattr_set_clock_id<'mir, 'tcx: 'mir>( ecx.write_scalar_at_offset(attr_op, 0, clock_id, ecx.machine.layouts.i32) } +fn condattr_deinit_clock_id<'mir, 'tcx: 'mir>( + ecx: &mut MiriEvalContext<'mir, 'tcx>, + attr_op: &OpTy<'tcx, Tag>, +) -> InterpResult<'tcx, ()> { + let layout = layout_of_maybe_uninit(ecx.tcx, ecx.machine.layouts.i32.ty); + ecx.write_scalar_at_offset(attr_op, 0, ScalarMaybeUninit::Uninit, layout) +} + // pthread_cond_t // Our chosen memory layout for the emulated conditional variable (does not have @@ -652,7 +660,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx fn pthread_condattr_destroy(&mut self, attr_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> { let this = self.eval_context_mut(); - condattr_set_clock_id(this, attr_op, ScalarMaybeUninit::Uninit)?; + condattr_get_clock_id(this, attr_op)?.check_init()?; + + condattr_deinit_clock_id(this, attr_op)?; Ok(0) } diff --git a/tests/compile-fail/sync/libc_pthread_condattr_double_destroy.rs b/tests/compile-fail/sync/libc_pthread_condattr_double_destroy.rs new file mode 100644 index 000000000000..44af51a3e871 --- /dev/null +++ b/tests/compile-fail/sync/libc_pthread_condattr_double_destroy.rs @@ -0,0 +1,19 @@ +// ignore-windows: No libc on Windows +#![feature(rustc_private)] + +/// Test that destroying a pthread_condattr twice fails, even without a check for number validity +extern crate libc; + +fn main() { + unsafe { + use core::mem::MaybeUninit; + let mut attr = MaybeUninit::::uninit(); + + libc::pthread_condattr_init(attr.as_mut_ptr()); + + libc::pthread_condattr_destroy(attr.as_mut_ptr()); + + libc::pthread_condattr_destroy(attr.as_mut_ptr()); + //~^ Undefined Behavior: using uninitialized data, but this operation requires initialized memory + } +} diff --git a/tests/run-pass/concurrency/pthread_condattr_init.rs b/tests/run-pass/concurrency/pthread_condattr_init.rs new file mode 100644 index 000000000000..285c6014e2d9 --- /dev/null +++ b/tests/run-pass/concurrency/pthread_condattr_init.rs @@ -0,0 +1,20 @@ +// ignore-windows: No libc on Windows +// compile-flags: -Zmiri-check-number-validity + +#![feature(rustc_private)] + +/// Test that pthread_condattr_destroy doesn't trigger a number validity error. +extern crate libc; + +fn main() { + unsafe { + use core::mem::MaybeUninit; + let mut attr = MaybeUninit::::uninit(); + + let r = libc::pthread_condattr_init(attr.as_mut_ptr()); + assert_eq!(r, 0); + + let r = libc::pthread_condattr_destroy(attr.as_mut_ptr()); + assert_eq!(r, 0); + } +}