Skip to content

Commit d4b1db5

Browse files
committed
validate CreateThread args
1 parent d2dee4b commit d4b1db5

File tree

2 files changed

+40
-12
lines changed

2 files changed

+40
-12
lines changed

src/shims/windows/foreign_items.rs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use std::iter;
22
use std::time::{Duration, Instant};
33

44
use rustc_middle::mir;
5-
use rustc_middle::ty::layout::LayoutOf;
65
use rustc_span::Symbol;
76
use rustc_target::abi::Size;
87
use rustc_target::spec::abi::Abi;
@@ -401,19 +400,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
401400

402401
// Threading
403402
"CreateThread" => {
404-
let [_security, _stacksize, start, arg, _flags, thread] =
403+
let [security, stacksize, start, arg, flags, thread] =
405404
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
406405

407-
let thread =
408-
if this.ptr_is_null(this.read_pointer(thread)?)? { None } else { Some(thread) };
409-
410-
let thread_id = this.start_thread(
411-
thread,
412-
start,
413-
Abi::System { unwind: false },
414-
arg,
415-
this.layout_of(this.tcx.types.u32)?,
416-
)?;
406+
let thread_id =
407+
this.CreateThread(security, stacksize, start, arg, flags, thread)?;
417408

418409
this.write_scalar(Handle::Thread(thread_id).to_scalar(this), dest)?;
419410
}

src/shims/windows/thread.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use std::time::{Duration, Instant};
22

3+
use rustc_middle::ty::layout::LayoutOf;
4+
use rustc_target::spec::abi::Abi;
5+
36
use crate::thread::Time;
47
use crate::*;
58
use shims::windows::handle::Handle;
@@ -8,6 +11,40 @@ impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mi
811

912
#[allow(non_snake_case)]
1013
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
14+
fn CreateThread(
15+
&mut self,
16+
security_op: &OpTy<'tcx, Tag>,
17+
stacksize_op: &OpTy<'tcx, Tag>,
18+
start_op: &OpTy<'tcx, Tag>,
19+
arg_op: &OpTy<'tcx, Tag>,
20+
flags_op: &OpTy<'tcx, Tag>,
21+
thread_op: &OpTy<'tcx, Tag>,
22+
) -> InterpResult<'tcx, ThreadId> {
23+
let this = self.eval_context_mut();
24+
25+
if !this.ptr_is_null(this.read_pointer(security_op)?)? {
26+
throw_unsup_format!("non-null `lpThreadAttributes` in `CreateThread`")
27+
}
28+
29+
// stacksize is ignored, but still needs to be a valid usize
30+
let _ = this.read_scalar(stacksize_op)?.to_machine_usize(this)?;
31+
32+
if this.read_scalar(flags_op)?.to_u32()? != 0 {
33+
throw_unsup_format!("non-zero `dwCreationFlags` in `CreateThread`")
34+
}
35+
36+
let thread =
37+
if this.ptr_is_null(this.read_pointer(thread_op)?)? { None } else { Some(thread_op) };
38+
39+
this.start_thread(
40+
thread,
41+
start_op,
42+
Abi::System { unwind: false },
43+
arg_op,
44+
this.layout_of(this.tcx.types.u32)?,
45+
)
46+
}
47+
1148
fn WaitForSingleObject(
1249
&mut self,
1350
handle: &OpTy<'tcx, Tag>,

0 commit comments

Comments
 (0)