-
Notifications
You must be signed in to change notification settings - Fork 59
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
Safer FFI string slice handling #441
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #441 +/- ##
==========================================
- Coverage 78.16% 78.08% -0.08%
==========================================
Files 55 55
Lines 11594 11605 +11
Branches 11594 11605 +11
==========================================
Hits 9062 9062
- Misses 2032 2043 +11
Partials 500 500 ☔ View full report in Codecov by Sentry. |
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 string slice stuff seems great.
I wonder about the warn!
s rather than panics. We don't (currently) have a good way over FFI to enable logging, so it's likely that those logs will go nowhere and we'll just get unexpected behavior.
Crash an burn at least indicates you did something wrong, although breaking the engine isn't great.
It seems like we should just change the functions to return Update: Tracked as #446. I'll revert those changes from this PR. |
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.
lgtm assuming we revert the warn
s for now.
Good catch, I thought I had already done that! |
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.
lgtm!
What changes are proposed in this pull request?
It is easy to create a use-after-free condition when creating kernel string slices from rust strings -- the raw pointers have no lifetime tracking that would allow the compiler to help. Thus, code like this would compile and produce a use-after-free at runtime:
The temporary
String
is freed as soon asKernelStringSlice::from
returns, and the resultingKernelStringSlice
is already invalid beforeexpects_string_slice
receives it. More pernicious cases may not involve any syntactically obvious borrowing:At that point, it's 100% up to the human to recognize the danger and avoid it by materializing the temporary string.
We can't "just" add an explicit lifetime parameter to
KernelStringSlice
, because lifetimes are meaningless when crossing the FFI boundary. Instead, we define a newkernel_string_slice
macro, which only accepts identifiers as input:How does it work? Named inputs are guaranteed to at least live long enough to create the slice; any dangerous situations must arise from the subsequent use of that slice, such as returning it from the function or code block that owns the source memory (which results in a move that could over-extend the slice lifetime).
Note: There is nothing magical about the macro. It merely enforces the discipline that the input be named, which allows the compiler to verify all lifetimes leading up to the macro invocation.
While we're at it -- add an
impl TryFromStringSlice for &str
, which supports the common case where the caller doesn't need an owned string.This PR affects the following public APIs
Removed the (very dangerous)
impl From
forKernelStringSlice
, and added anunsafe
constructor instead. Also restrict both the constructor and the macro to crate visibility for now. We can consider a public export if/when the need arises.How was this change tested?
Refactor. Compilation + existing tests cover it.