Skip to content

Commit a16280c

Browse files
committed
Add duplicate handle test + make null lpTargetHandle an abort, not an unsupported.
1 parent d0a9d59 commit a16280c

File tree

2 files changed

+46
-9
lines changed

2 files changed

+46
-9
lines changed

src/shims/windows/handle.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
285285
}
286286

287287
if this.ptr_is_null(target_handle_ptr)? {
288-
throw_unsup_format!(
289-
"`DuplicateHandle` `lpTargetHandle` parameter is null, which is unsupported"
290-
);
288+
throw_machine_stop!(TerminationInfo::Abort(
289+
"`DuplicateHandle` `lpTargetHandle` parameter must not be null, as otherwise the \
290+
newly created handle is leaked"
291+
.to_string()
292+
));
291293
}
292294

293295
if options != this.eval_windows("c", "DUPLICATE_SAME_ACCESS") {

tests/pass-dep/shims/windows-fs.rs

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@
22
//@compile-flags: -Zmiri-disable-isolation
33
#![allow(nonstandard_style)]
44

5-
use std::io::{ErrorKind, Read, Write};
5+
use std::io::{ErrorKind, Read, Seek, SeekFrom, Write};
66
use std::os::windows::ffi::OsStrExt;
7-
use std::os::windows::io::AsRawHandle;
7+
use std::os::windows::io::{AsRawHandle, FromRawHandle};
88
use std::path::Path;
9-
use std::{fs, ptr};
9+
use std::{fs, mem, ptr};
1010

1111
#[path = "../../utils/mod.rs"]
1212
mod utils;
1313

1414
use windows_sys::Wdk::Storage::FileSystem::{NtReadFile, NtWriteFile};
1515
use windows_sys::Win32::Foundation::{
16-
CloseHandle, ERROR_ACCESS_DENIED, ERROR_ALREADY_EXISTS, ERROR_IO_DEVICE, GENERIC_READ,
17-
GENERIC_WRITE, GetLastError, RtlNtStatusToDosError, STATUS_ACCESS_DENIED,
18-
STATUS_IO_DEVICE_ERROR, STATUS_SUCCESS, SetLastError,
16+
CloseHandle, DUPLICATE_SAME_ACCESS, DuplicateHandle, ERROR_ACCESS_DENIED, ERROR_ALREADY_EXISTS,
17+
ERROR_IO_DEVICE, FALSE, GENERIC_READ, GENERIC_WRITE, GetLastError, RtlNtStatusToDosError,
18+
STATUS_ACCESS_DENIED, STATUS_IO_DEVICE_ERROR, STATUS_SUCCESS, SetLastError,
1919
};
2020
use windows_sys::Win32::Storage::FileSystem::{
2121
BY_HANDLE_FILE_INFORMATION, CREATE_ALWAYS, CREATE_NEW, CreateFileW, DeleteFileW,
@@ -24,6 +24,7 @@ use windows_sys::Win32::Storage::FileSystem::{
2424
FILE_SHARE_WRITE, GetFileInformationByHandle, OPEN_ALWAYS, OPEN_EXISTING, SetFilePointerEx,
2525
};
2626
use windows_sys::Win32::System::IO::IO_STATUS_BLOCK;
27+
use windows_sys::Win32::System::Threading::GetCurrentProcess;
2728

2829
fn main() {
2930
unsafe {
@@ -36,6 +37,7 @@ fn main() {
3637
test_ntstatus_to_dos();
3738
test_file_read_write();
3839
test_file_seek();
40+
test_dup_handle();
3941
}
4042
}
4143

@@ -273,6 +275,39 @@ unsafe fn test_file_read_write() {
273275
assert_eq!(GetLastError(), 1234);
274276
}
275277

278+
unsafe fn test_dup_handle() {
279+
let temp = utils::tmp().join("test_dup.txt");
280+
281+
let mut file1 = fs::File::options().read(true).write(true).create(true).open(&temp).unwrap();
282+
283+
file1.write_all(b"Hello, World!\n").unwrap();
284+
file1.seek(SeekFrom::Start(0)).unwrap();
285+
286+
let first_handle = file1.as_raw_handle();
287+
288+
let cur_proc = GetCurrentProcess();
289+
let mut second_handle = mem::zeroed();
290+
let res = DuplicateHandle(
291+
cur_proc,
292+
first_handle,
293+
cur_proc,
294+
&mut second_handle,
295+
0,
296+
FALSE,
297+
DUPLICATE_SAME_ACCESS,
298+
);
299+
assert!(res != 0);
300+
301+
let mut buf1 = [0; 5];
302+
file1.read(&mut buf1).unwrap();
303+
assert_eq!(&buf1, b"Hello");
304+
305+
let mut file2 = fs::File::from_raw_handle(second_handle);
306+
let mut buf2 = [0; 5];
307+
file2.read(&mut buf2).unwrap();
308+
assert_eq!(&buf2, b", Wor");
309+
}
310+
276311
unsafe fn test_file_seek() {
277312
let temp = utils::tmp().join("test_file_seek.txt");
278313
let mut file = fs::File::options().create(true).write(true).read(true).open(&temp).unwrap();

0 commit comments

Comments
 (0)