-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: fix soundness hole in Handle
API
#998
Conversation
// Wraps a borrowed Windows [`HANDLE`]. | ||
pub fn new_borrowed(handle: HANDLE) -> Self { | ||
// SAFETY: It’s safe to wrap a non-owning Handle as we’ll not call `CloseHandle` on it. | ||
unsafe { Self::new(handle, false) } | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When we know that the handle is not owned in a static way, we can use the safe function new_borrowed
which never causes any UB.
pub fn new(handle: HANDLE, owned: bool) -> Self { | ||
// Wraps a Windows [`HANDLE`]. | ||
// | ||
// # Safety | ||
// | ||
// When `owned` is `true`: | ||
// | ||
// - `handle` is a valid handle to an open object. | ||
// - `handle` is not a pseudohandle. | ||
// - The caller is actually responsible for freeing the `HANDLE` when the value goes out of scope. | ||
// | ||
// When `owned` is `false`: no outstanding precondition. | ||
pub unsafe fn new(handle: HANDLE, owned: bool) -> Self { | ||
Self { raw: handle, owned } | ||
} | ||
|
||
// Wraps an owned Windows [`HANDLE`]. | ||
// | ||
// # Safety | ||
// | ||
// - `handle` is a valid handle to an open object. | ||
// - `handle` is not a pseudohandle. | ||
// - The caller is actually responsible for freeing the `HANDLE` when the value goes out of scope. | ||
pub unsafe fn new_owned(handle: HANDLE) -> Self { | ||
// SAFETY: Same preconditions as the called function. | ||
unsafe { Self::new(handle, true) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Drop
implementation is assuming we constructed the Handle
object in a sane way to call CloseHandle
, but there is no way for us to verify that the handle is actually owned outside of the callsite. Conceptually, calling Handle::new_owned(handle)
or Handle::new(handle, true)
is like calling the unsafe function CloseHandle
and thus must inherits its safety preconditions.
83bf8da
to
7b2f5c5
Compare
The API of
Handle
inwin-api-wrappers
is allowing UB without unsafe code. I adjusted the API to fix the hole.Note that this PR is not fixing any vulnerability or bug per se. It only fixes the unsound safe API that we are using correctly in this repository only.
cc @kbouchard-dev