Skip to content

Commit

Permalink
Fix CVE-2022-21658 for Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisDenton authored and pietroalbini committed Jan 19, 2022
1 parent 86f7f78 commit 5ab67bf
Show file tree
Hide file tree
Showing 2 changed files with 419 additions and 27 deletions.
124 changes: 114 additions & 10 deletions library/std/src/sys/windows/c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#![cfg_attr(test, allow(dead_code))]
#![unstable(issue = "none", feature = "windows_c")]

use crate::mem;
use crate::os::raw::NonZero_c_ulong;
use crate::os::raw::{c_char, c_int, c_long, c_longlong, c_uint, c_ulong, c_ushort};
use crate::ptr;
Expand Down Expand Up @@ -36,6 +37,7 @@ pub type USHORT = c_ushort;
pub type SIZE_T = usize;
pub type WORD = u16;
pub type CHAR = c_char;
pub type CCHAR = c_char;
pub type ULONG_PTR = usize;
pub type ULONG = c_ulong;
pub type NTSTATUS = LONG;
Expand Down Expand Up @@ -86,16 +88,21 @@ pub const FILE_SHARE_DELETE: DWORD = 0x4;
pub const FILE_SHARE_READ: DWORD = 0x1;
pub const FILE_SHARE_WRITE: DWORD = 0x2;

pub const FILE_OPEN_REPARSE_POINT: ULONG = 0x200000;
pub const OBJ_DONT_REPARSE: ULONG = 0x1000;

pub const CREATE_ALWAYS: DWORD = 2;
pub const CREATE_NEW: DWORD = 1;
pub const OPEN_ALWAYS: DWORD = 4;
pub const OPEN_EXISTING: DWORD = 3;
pub const TRUNCATE_EXISTING: DWORD = 5;

pub const FILE_LIST_DIRECTORY: DWORD = 0x1;
pub const FILE_WRITE_DATA: DWORD = 0x00000002;
pub const FILE_APPEND_DATA: DWORD = 0x00000004;
pub const FILE_WRITE_EA: DWORD = 0x00000010;
pub const FILE_WRITE_ATTRIBUTES: DWORD = 0x00000100;
pub const DELETE: DWORD = 0x10000;
pub const READ_CONTROL: DWORD = 0x00020000;
pub const SYNCHRONIZE: DWORD = 0x00100000;
pub const GENERIC_READ: DWORD = 0x80000000;
Expand Down Expand Up @@ -261,9 +268,61 @@ pub const FD_SETSIZE: usize = 64;
pub const STACK_SIZE_PARAM_IS_A_RESERVATION: DWORD = 0x00010000;

pub const STATUS_SUCCESS: NTSTATUS = 0x00000000;
pub const STATUS_DELETE_PENDING: NTSTATUS = 0xc0000056_u32 as _;
pub const STATUS_INVALID_PARAMETER: NTSTATUS = 0xc000000d_u32 as _;

// Equivalent to the `NT_SUCCESS` C preprocessor macro.
// See: https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/using-ntstatus-values
pub fn nt_success(status: NTSTATUS) -> bool {
status >= 0
}

pub const BCRYPT_USE_SYSTEM_PREFERRED_RNG: DWORD = 0x00000002;

#[repr(C)]
pub struct UNICODE_STRING {
pub Length: u16,
pub MaximumLength: u16,
pub Buffer: *mut u16,
}
impl UNICODE_STRING {
pub fn from_ref(slice: &[u16]) -> Self {
let len = slice.len() * mem::size_of::<u16>();
Self { Length: len as _, MaximumLength: len as _, Buffer: slice.as_ptr() as _ }
}
}
#[repr(C)]
pub struct OBJECT_ATTRIBUTES {
pub Length: ULONG,
pub RootDirectory: HANDLE,
pub ObjectName: *const UNICODE_STRING,
pub Attributes: ULONG,
pub SecurityDescriptor: *mut c_void,
pub SecurityQualityOfService: *mut c_void,
}
impl Default for OBJECT_ATTRIBUTES {
fn default() -> Self {
Self {
Length: mem::size_of::<Self>() as _,
RootDirectory: ptr::null_mut(),
ObjectName: ptr::null_mut(),
Attributes: 0,
SecurityDescriptor: ptr::null_mut(),
SecurityQualityOfService: ptr::null_mut(),
}
}
}
#[repr(C)]
pub struct IO_STATUS_BLOCK {
pub Pointer: *mut c_void,
pub Information: usize,
}
impl Default for IO_STATUS_BLOCK {
fn default() -> Self {
Self { Pointer: ptr::null_mut(), Information: 0 }
}
}

#[repr(C)]
#[cfg(not(target_pointer_width = "64"))]
pub struct WSADATA {
Expand Down Expand Up @@ -353,9 +412,43 @@ pub enum FILE_INFO_BY_HANDLE_CLASS {
FileIdInfo = 18, // 0x12
FileIdExtdDirectoryInfo = 19, // 0x13
FileIdExtdDirectoryRestartInfo = 20, // 0x14
FileDispositionInfoEx = 21, // 0x15, Windows 10 version 1607
MaximumFileInfoByHandlesClass,
}

#[repr(C)]
pub struct FILE_DISPOSITION_INFO {
pub DeleteFile: BOOLEAN,
}

pub const FILE_DISPOSITION_DELETE: DWORD = 0x1;
pub const FILE_DISPOSITION_POSIX_SEMANTICS: DWORD = 0x2;
pub const FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE: DWORD = 0x10;

#[repr(C)]
pub struct FILE_DISPOSITION_INFO_EX {
pub Flags: DWORD,
}

#[repr(C)]
#[derive(Default)]
pub struct FILE_ID_BOTH_DIR_INFO {
pub NextEntryOffset: DWORD,
pub FileIndex: DWORD,
pub CreationTime: LARGE_INTEGER,
pub LastAccessTime: LARGE_INTEGER,
pub LastWriteTime: LARGE_INTEGER,
pub ChangeTime: LARGE_INTEGER,
pub EndOfFile: LARGE_INTEGER,
pub AllocationSize: LARGE_INTEGER,
pub FileAttributes: DWORD,
pub FileNameLength: DWORD,
pub EaSize: DWORD,
pub ShortNameLength: CCHAR,
pub ShortName: [WCHAR; 12],
pub FileId: LARGE_INTEGER,
pub FileName: [WCHAR; 1],
}
#[repr(C)]
pub struct FILE_BASIC_INFO {
pub CreationTime: LARGE_INTEGER,
Expand Down Expand Up @@ -750,16 +843,6 @@ if #[cfg(target_vendor = "uwp")] {
pub DeletePending: BOOLEAN,
pub Directory: BOOLEAN,
}

#[link(name = "kernel32")]
extern "system" {
pub fn GetFileInformationByHandleEx(
hFile: HANDLE,
fileInfoClass: FILE_INFO_BY_HANDLE_CLASS,
lpFileInformation: LPVOID,
dwBufferSize: DWORD,
) -> BOOL;
}
}
}

Expand Down Expand Up @@ -949,6 +1032,12 @@ extern "system" {
cchFilePath: DWORD,
dwFlags: DWORD,
) -> DWORD;
pub fn GetFileInformationByHandleEx(
hFile: HANDLE,
fileInfoClass: FILE_INFO_BY_HANDLE_CLASS,
lpFileInformation: LPVOID,
dwBufferSize: DWORD,
) -> BOOL;
pub fn SetFileInformationByHandle(
hFile: HANDLE,
FileInformationClass: FILE_INFO_BY_HANDLE_CLASS,
Expand Down Expand Up @@ -1139,6 +1228,21 @@ compat_fn! {

compat_fn! {
"ntdll":
pub fn NtOpenFile(
FileHandle: *mut HANDLE,
DesiredAccess: ACCESS_MASK,
ObjectAttributes: *const OBJECT_ATTRIBUTES,
IoStatusBlock: *mut IO_STATUS_BLOCK,
ShareAccess: ULONG,
OpenOptions: ULONG
) -> NTSTATUS {
panic!("`NtOpenFile` not available");
}
pub fn RtlNtStatusToDosError(
Status: NTSTATUS
) -> ULONG {
panic!("`RtlNtStatusToDosError` not available");
}
pub fn NtCreateKeyedEvent(
KeyedEventHandle: LPHANDLE,
DesiredAccess: ACCESS_MASK,
Expand Down
Loading

0 comments on commit 5ab67bf

Please sign in to comment.