Skip to content

Commit 5ab67bf

Browse files
ChrisDentonpietroalbini
authored andcommitted
Fix CVE-2022-21658 for Windows
1 parent 86f7f78 commit 5ab67bf

File tree

2 files changed

+419
-27
lines changed

2 files changed

+419
-27
lines changed

library/std/src/sys/windows/c.rs

+114-10
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#![cfg_attr(test, allow(dead_code))]
55
#![unstable(issue = "none", feature = "windows_c")]
66

7+
use crate::mem;
78
use crate::os::raw::NonZero_c_ulong;
89
use crate::os::raw::{c_char, c_int, c_long, c_longlong, c_uint, c_ulong, c_ushort};
910
use crate::ptr;
@@ -36,6 +37,7 @@ pub type USHORT = c_ushort;
3637
pub type SIZE_T = usize;
3738
pub type WORD = u16;
3839
pub type CHAR = c_char;
40+
pub type CCHAR = c_char;
3941
pub type ULONG_PTR = usize;
4042
pub type ULONG = c_ulong;
4143
pub type NTSTATUS = LONG;
@@ -86,16 +88,21 @@ pub const FILE_SHARE_DELETE: DWORD = 0x4;
8688
pub const FILE_SHARE_READ: DWORD = 0x1;
8789
pub const FILE_SHARE_WRITE: DWORD = 0x2;
8890

91+
pub const FILE_OPEN_REPARSE_POINT: ULONG = 0x200000;
92+
pub const OBJ_DONT_REPARSE: ULONG = 0x1000;
93+
8994
pub const CREATE_ALWAYS: DWORD = 2;
9095
pub const CREATE_NEW: DWORD = 1;
9196
pub const OPEN_ALWAYS: DWORD = 4;
9297
pub const OPEN_EXISTING: DWORD = 3;
9398
pub const TRUNCATE_EXISTING: DWORD = 5;
9499

100+
pub const FILE_LIST_DIRECTORY: DWORD = 0x1;
95101
pub const FILE_WRITE_DATA: DWORD = 0x00000002;
96102
pub const FILE_APPEND_DATA: DWORD = 0x00000004;
97103
pub const FILE_WRITE_EA: DWORD = 0x00000010;
98104
pub const FILE_WRITE_ATTRIBUTES: DWORD = 0x00000100;
105+
pub const DELETE: DWORD = 0x10000;
99106
pub const READ_CONTROL: DWORD = 0x00020000;
100107
pub const SYNCHRONIZE: DWORD = 0x00100000;
101108
pub const GENERIC_READ: DWORD = 0x80000000;
@@ -261,9 +268,61 @@ pub const FD_SETSIZE: usize = 64;
261268
pub const STACK_SIZE_PARAM_IS_A_RESERVATION: DWORD = 0x00010000;
262269

263270
pub const STATUS_SUCCESS: NTSTATUS = 0x00000000;
271+
pub const STATUS_DELETE_PENDING: NTSTATUS = 0xc0000056_u32 as _;
272+
pub const STATUS_INVALID_PARAMETER: NTSTATUS = 0xc000000d_u32 as _;
273+
274+
// Equivalent to the `NT_SUCCESS` C preprocessor macro.
275+
// See: https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/using-ntstatus-values
276+
pub fn nt_success(status: NTSTATUS) -> bool {
277+
status >= 0
278+
}
264279

265280
pub const BCRYPT_USE_SYSTEM_PREFERRED_RNG: DWORD = 0x00000002;
266281

282+
#[repr(C)]
283+
pub struct UNICODE_STRING {
284+
pub Length: u16,
285+
pub MaximumLength: u16,
286+
pub Buffer: *mut u16,
287+
}
288+
impl UNICODE_STRING {
289+
pub fn from_ref(slice: &[u16]) -> Self {
290+
let len = slice.len() * mem::size_of::<u16>();
291+
Self { Length: len as _, MaximumLength: len as _, Buffer: slice.as_ptr() as _ }
292+
}
293+
}
294+
#[repr(C)]
295+
pub struct OBJECT_ATTRIBUTES {
296+
pub Length: ULONG,
297+
pub RootDirectory: HANDLE,
298+
pub ObjectName: *const UNICODE_STRING,
299+
pub Attributes: ULONG,
300+
pub SecurityDescriptor: *mut c_void,
301+
pub SecurityQualityOfService: *mut c_void,
302+
}
303+
impl Default for OBJECT_ATTRIBUTES {
304+
fn default() -> Self {
305+
Self {
306+
Length: mem::size_of::<Self>() as _,
307+
RootDirectory: ptr::null_mut(),
308+
ObjectName: ptr::null_mut(),
309+
Attributes: 0,
310+
SecurityDescriptor: ptr::null_mut(),
311+
SecurityQualityOfService: ptr::null_mut(),
312+
}
313+
}
314+
}
315+
#[repr(C)]
316+
pub struct IO_STATUS_BLOCK {
317+
pub Pointer: *mut c_void,
318+
pub Information: usize,
319+
}
320+
impl Default for IO_STATUS_BLOCK {
321+
fn default() -> Self {
322+
Self { Pointer: ptr::null_mut(), Information: 0 }
323+
}
324+
}
325+
267326
#[repr(C)]
268327
#[cfg(not(target_pointer_width = "64"))]
269328
pub struct WSADATA {
@@ -353,9 +412,43 @@ pub enum FILE_INFO_BY_HANDLE_CLASS {
353412
FileIdInfo = 18, // 0x12
354413
FileIdExtdDirectoryInfo = 19, // 0x13
355414
FileIdExtdDirectoryRestartInfo = 20, // 0x14
415+
FileDispositionInfoEx = 21, // 0x15, Windows 10 version 1607
356416
MaximumFileInfoByHandlesClass,
357417
}
358418

419+
#[repr(C)]
420+
pub struct FILE_DISPOSITION_INFO {
421+
pub DeleteFile: BOOLEAN,
422+
}
423+
424+
pub const FILE_DISPOSITION_DELETE: DWORD = 0x1;
425+
pub const FILE_DISPOSITION_POSIX_SEMANTICS: DWORD = 0x2;
426+
pub const FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE: DWORD = 0x10;
427+
428+
#[repr(C)]
429+
pub struct FILE_DISPOSITION_INFO_EX {
430+
pub Flags: DWORD,
431+
}
432+
433+
#[repr(C)]
434+
#[derive(Default)]
435+
pub struct FILE_ID_BOTH_DIR_INFO {
436+
pub NextEntryOffset: DWORD,
437+
pub FileIndex: DWORD,
438+
pub CreationTime: LARGE_INTEGER,
439+
pub LastAccessTime: LARGE_INTEGER,
440+
pub LastWriteTime: LARGE_INTEGER,
441+
pub ChangeTime: LARGE_INTEGER,
442+
pub EndOfFile: LARGE_INTEGER,
443+
pub AllocationSize: LARGE_INTEGER,
444+
pub FileAttributes: DWORD,
445+
pub FileNameLength: DWORD,
446+
pub EaSize: DWORD,
447+
pub ShortNameLength: CCHAR,
448+
pub ShortName: [WCHAR; 12],
449+
pub FileId: LARGE_INTEGER,
450+
pub FileName: [WCHAR; 1],
451+
}
359452
#[repr(C)]
360453
pub struct FILE_BASIC_INFO {
361454
pub CreationTime: LARGE_INTEGER,
@@ -750,16 +843,6 @@ if #[cfg(target_vendor = "uwp")] {
750843
pub DeletePending: BOOLEAN,
751844
pub Directory: BOOLEAN,
752845
}
753-
754-
#[link(name = "kernel32")]
755-
extern "system" {
756-
pub fn GetFileInformationByHandleEx(
757-
hFile: HANDLE,
758-
fileInfoClass: FILE_INFO_BY_HANDLE_CLASS,
759-
lpFileInformation: LPVOID,
760-
dwBufferSize: DWORD,
761-
) -> BOOL;
762-
}
763846
}
764847
}
765848

@@ -949,6 +1032,12 @@ extern "system" {
9491032
cchFilePath: DWORD,
9501033
dwFlags: DWORD,
9511034
) -> DWORD;
1035+
pub fn GetFileInformationByHandleEx(
1036+
hFile: HANDLE,
1037+
fileInfoClass: FILE_INFO_BY_HANDLE_CLASS,
1038+
lpFileInformation: LPVOID,
1039+
dwBufferSize: DWORD,
1040+
) -> BOOL;
9521041
pub fn SetFileInformationByHandle(
9531042
hFile: HANDLE,
9541043
FileInformationClass: FILE_INFO_BY_HANDLE_CLASS,
@@ -1139,6 +1228,21 @@ compat_fn! {
11391228

11401229
compat_fn! {
11411230
"ntdll":
1231+
pub fn NtOpenFile(
1232+
FileHandle: *mut HANDLE,
1233+
DesiredAccess: ACCESS_MASK,
1234+
ObjectAttributes: *const OBJECT_ATTRIBUTES,
1235+
IoStatusBlock: *mut IO_STATUS_BLOCK,
1236+
ShareAccess: ULONG,
1237+
OpenOptions: ULONG
1238+
) -> NTSTATUS {
1239+
panic!("`NtOpenFile` not available");
1240+
}
1241+
pub fn RtlNtStatusToDosError(
1242+
Status: NTSTATUS
1243+
) -> ULONG {
1244+
panic!("`RtlNtStatusToDosError` not available");
1245+
}
11421246
pub fn NtCreateKeyedEvent(
11431247
KeyedEventHandle: LPHANDLE,
11441248
DesiredAccess: ACCESS_MASK,

0 commit comments

Comments
 (0)