GitShow/BurntSushi/winapi-util
BurntSushi

winapi-util

Safe wrappers for various Windows specific APIs.

by BurntSushi
Star on GitHubFork

Rust

75 stars21 forks7 contributorsQuiet · 10mo agoSince 2018Unlicense

Meet the team

See all 7 on GitHub →
BurntSushi
BurntSushi29 contributions
ChrisDenton
ChrisDenton1 contribution
sunfishcode
sunfishcode1 contribution
dtolnay
dtolnay1 contribution
ilai-deutel
ilai-deutel1 contribution
lopopolo
lopopolo1 contribution
taiki-e
taiki-e1 contribution

Languages

View on GitHub →
Rust100%

Commit activity

Last 12 weeks · 0 commits

Full graph →

Community health

2 of 6 standards met

Community profile →
42
✓README✓License○Contributing○Code of Conduct○Issue Template○PR Template

Recent PRs & issues

Quiet · 8 in progress · Last activity 10mo ago
See all on GitHub →
Manishearth
Soundness: Dangling OS Handle Reuse via Unsound Lifetime Escaping in HandleRefOpenIssue

[!NOTE] This finding was identified during an agentic unsafe Rust code review performed by Gemini AI, followed by human review and verification. This is an IO safety issue. I personally am not a huge fan of IO safety being considered the same type of safety as regular safety, but I know there are good reasons for it. The Issue The primary handle abstraction in this crate is the handle pair (owned) and (borrowed). is documented as a borrowed representation of a valid Windows handle. However, contains no lifetime parameter tracking the duration of the borrow (its struct definition holds only references). When safe constructors such as or trait conversions via are invoked on owned I/O objects (, , , etc.), they execute . Inside , is invoked to construct an owned object stored inside . Locations: https://github.com/BurntSushi/winapi-util/blob/803874c57dc1f10ecd42f7c86d9de72f53818432/src/win.rs#L145-L147 https://github.com/BurntSushi/winapi-util/blob/803874c57dc1f10ecd42f7c86d9de72f53818432/src/win.rs#L194-L198 https://github.com/BurntSushi/winapi-util/blob/803874c57dc1f10ecd42f7c86d9de72f53818432/src/win.rs#L206-L210 https://github.com/BurntSushi/winapi-util/blob/803874c57dc1f10ecd42f7c86d9de72f53818432/src/win.rs#L230-L246 Based on the documentation, callers have to uphold: "The caller must ensure that the handle is valid and that nobody else will close it for the lifetime of the returned object." Because is passed by reference , safe code can drop while keeping the returned alive. When drops, its implementation invokes OS . At this point, the object stored inside wraps a closed OS handle, violating the safety contract. If another thread or component concurrently opens a file, pipe, socket, registry key, or IPC mechanism, the Windows kernel may recycle the closed handle value. Safe code calling methods on the escaped (such as , , or ) will perform I/O operations or attribute mutations on an unrelated OS resource, causing unintended I/O corruption, memory safety violations (for example, if the recycled resource is an internal memory mapping or IPC handle), and UB. Minimal Reproduction (Miri) This testcase needs and (I'm surprised that works) Suggested Fix Modern Rust (1.63+) resolves this via RFC 3128 ("I/O Safety"). should either be redesigned to carry a lifetime parameter holding a , or deprecated in favor of standard library . [!NOTE] The full audit report below also contains additional minor findings (such as missing safety comments or undocumented FFI assumptions) that are probably worth fixing as well but not the primary goal of this issue. The audit report has not been human-reviewed, it may contain misleading claims. Full Gemini Codebase Audit Report Appendix Unsafe Rust Review: () Overall Safety Assessment is a small Windows utility crate designed to provide safe wrappers around common Windows system APIs (), centralizing code for operations on console attributes, file information, and system properties. The primary architectural abstraction in the crate is the handle pair (owned) and (borrowed). Under the hood, wraps inside a custom wrapper () whose implementation extracts the and calls , intentionally suppressing OS when the borrowed reference is dropped. While the crate succeeds in offering convenient wrappers for Win32 console and file information APIs, its core abstraction predates Rust 1.63's I/O Safety stabilization (RFC 3128 ). Because is un-lifetimed (), safe constructors and trait conversions from owned I/O objects (, , , etc.) allow borrowed handles to escape the lifetime of their owners. This violates the fundamental safety contract of and introduces a real soundness vulnerability (dangling handle reuse). Furthermore, almost all blocks and functions across , , and lack proof-obligation comments. Critical Findings 1. Unsound Lifetime Escaping in and (Dangling OS Handle Reuse) 🔴 🤦 Severity: 🔴 High Threat Vector: 🤦 Accidental Misuse Bug Type: Locations: () () () (, , ) Description*: is documented as a borrowed representation of a valid Windows handle. However, contains no lifetime parameter tracking the duration of the borrow (i.e., its type contains only references). When is called in safe code, it executes . Inside , is invoked to construct an owned object stored inside . According to authoritative standard library documentation (), callers must uphold a strict safety contract: "The caller must ensure that the handle is valid and that nobody else will close it for the lifetime of the returned object." Because is passed by reference , safe code can drop while keeping the returned alive. When drops, its implementation invokes OS . At this point, the object inside wraps a closed OS handle, violating the safety contract. If another thread or component subsequently opens a file, pipe, registry key, or IPC mechanism, the Windows kernel may recycle the closed handle value. Safe code calling methods on the escaped (such as , , or ) will perform I/O operations or attribute mutations on an unrelated OS resource, causing unintended I/O corruption, memory safety violations (e.g., if the recycled resource is an internal memory mapping or IPC handle), and undefined behavior. Proof of Vulnerability (Safe Code Trigger): Remediation: Modern Rust (1.63+) resolves this via RFC 3128 ("I/O Safety"). should either be redesigned to carry a lifetime parameter holding a , or deprecated in favor of standard library . Fishy Findings 1. Safe Trait Allows Override of 🟡 🤸 Severity: 🟡 Low Threat Vector: 🤸 Deliberate Contortion Bug Type: Location: Description: is a safe trait with a default method . Safe code implementing for a custom type can override to return an arbitrary pointer value (e.g., ). Public safe functions such as , , and call and pass the resulting raw handle directly to Win32 FFI functions. While passing invalid handle values to these specific Win32 query/mode APIs safely fails with at the OS kernel level (avoiding UB), relying on FFI target robustness against arbitrary safe trait overrides without safety comments or making an is a questionable design pattern. 2. Incomplete Safety Contract Documentation on 🟡 🤦 Severity: 🟡 Low Threat Vector: 🤦 Accidental Misuse Bug Type: Location: Description: The documentation for states: "This is unsafe because there is no guarantee that the given raw handle is a valid handle. The caller must ensure this is true before invoking this constructor." However, because wraps the raw handle in , it inherits the safety preconditions of . Specifically, callers must not only guarantee that the handle is currently valid, but also that nobody else will close it for the lifetime of the returned *. Omitting this critical liveness requirement from the docstring misleads callers into thinking they can pass a borrowed raw handle whose owner might close it later. Missing Safety Comments 🔴 Line 21: inside . 🔴 Proposed Proof Comment: Line 39: inside . 🔴 Proposed Proof Comment: 🔴 Line 34: inside . 🔴 Proposed Proof Comment: Line 53: . 🔴 Proposed Proof Comment: Line 70: . 🔴 Proposed Proof Comment: Line 84: . 🔴 Proposed Proof Comment: 🔴 Line 24: (trait impl). 🔴 Proposed Proof Comment: Line 116: inside . 🔴 Proposed Proof Comment: Line 125: . 🔴 Proposed Proof Comment: Line 132: . 🔴 Proposed Proof Comment: Line 139: . 🔴 Proposed Proof Comment: Line 146: inside . 🔴 Proposed Proof Comment: Line 162: Inside . 🔴 Proposed Proof Comment: Line 196: inside . 🔴 Proposed Proof Comment: Line 214: inside . 🔴 Proposed Proof Comment: Line 220: inside . 🔴 Proposed Proof Comment: Line 226: inside . 🔴 Proposed Proof Comment: Line 232: inside . 🔴 Proposed Proof Comment: Line 238: inside . 🔴 Proposed Proof Comment: Line 244: inside . 🔴 Proposed Proof Comment:

Manishearth · 2d ago
joshtriplett
Avoid using a version range for windows-sys; causes non-deterministic version resolutionOpenPR

Cargo's version resolver doesn't handle version ranges like this very well, resulting in non-deterministic flip-flopping of versions. https://github.com/rust-lang/cargo/issues/9029 https://github.com/rust-lang/cargo/issues/5529 https://rust-lang.zulipchat.com/#narrow/channel/246057-t-cargo/topic/Cargo.2Elock.20non-deterministically.20flipflopping/with/520024108

joshtriplett · 2mo ago
ChrisDenton
Use windows-bindgenOpenPR

This PR adds a small utility that generates all bindings listed in a text file. Any future additions or removals merely need to edit that file and run the utility. I also added a CI job to check that bindings have been correctly generated and committed.

ChrisDenton · 2mo ago

Recent fixes

View closed PRs →
taiki-e
cargo: support windows-sys 0.61MergedPR
taiki-e · 10mo ago
lopopolo
Support windows-sys v0.60.0MergedPR

Following the same pattern as #19. I'm not sure if you want tests that do for all of the various semver incompatible versions in this range NOTE: I didn't run tests, I just made this change from the GitHub web UI; sorry about that. It looks like this repo has CI but maybe it didn't run on this PR.

lopopolo · 10mo ago
ChrisDenton
Update windows-sys to version 0.59.0MergedPR

Changes in this release include making the type match rust's std type (i.e. instead of ). If it's ok with you, I've used a range dependency so that it is less likely that multiple versions of appear in someone's dependency tree. According to the stats, the last 3 versions (0.48.0. 0.52.0 and 0.59.0) account for most uses of . I have tested that these versions work. This shouldn't need to be updated often. The last release (0.52.0) was 9 months ago.

ChrisDenton · 1y ago
Structured data for AI agents

Repository: BurntSushi/winapi-util. Description: Safe wrappers for various Windows specific APIs. Stars: 75, Forks: 21. Primary language: Rust. Languages: Rust (100%). License: Unlicense. Open PRs: 8, open issues: 2. Last activity: 10mo ago. Community health: 42%. Top contributors: BurntSushi, ChrisDenton, sunfishcode, dtolnay, ilai-deutel, lopopolo, taiki-e.

·@ofershap

Replace github.com with gitshow.dev