Handle uninit data in pthread_condattr_destroy

This commit is contained in:
5225225 2021-12-05 13:54:25 +00:00
parent 5e9cf62b89
commit eadeedde42
3 changed files with 50 additions and 1 deletions

View File

@ -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)
}

View File

@ -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::<libc::pthread_condattr_t>::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
}
}

View File

@ -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::<libc::pthread_condattr_t>::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);
}
}