-
Notifications
You must be signed in to change notification settings - Fork 65
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
Bug report: Unsoundness in FfiSlice::as_slice #304
Comments
Considering this is a Unsound problem and published to crates.io, I suggest reprot it to RustSec. |
Lines 21 to 26 in e5a0c89
Feel free to re-open this issue if you are able to demonstrate unsoundness using |
If it isn't a public api, maybe mark it as pub(crate) would be more appropriate. Currently, I'm scanning unsoundness problem the pub api of crates.io. this is just my suggestion for reference only. |
We can't make it as |
Same problem for swift-bridge/src/std_bridge/string.rs Line 29 in 225380e
|
FYI: Using A better solution would involve restricting direct access to the struct fields and enforcing stricter encapsulation. The fields start and len should be made private, and all interactions with them should be mediated through safe, well-defined APIs. For instance, providing a constructor that performs validation before creating an instance of FfiSlice ensures that invalid pointers or lengths cannot be passed. Additionally, functions like as_slice should include runtime checks to confirm that the fields are in a valid state before proceeding. For example, the function could return an Option or Result to gracefully handle cases where the pointer is null or the length is zero. Another robust approach would be to mark FfiSlice as an unsafe struct, explicitly signaling that its use requires careful handling and a deep understanding of the safety guarantees. This would place the responsibility on the developer to ensure that the struct is used correctly, but it would also discourage casual misuse by requiring any operations involving FfiSlice to be enclosed in an unsafe block. This strategy makes it clear that the onus of maintaining safety lies with the user of the struct. Thank you for your contribution to the maintenance of this project. These are just my personal opinions for security concern :) |
There is no reason for a user to use the If a user finds the undocumented We cannot prevent an advanced user from creating an let null_slice = (std::ptr::null::<u32>(), 100);
let null_slice: FfiSlice<u32> = unsafe { std::mem::transmute(null_slice) }; If a user is willing to use our undocumented APIs then we will trust that they'd be just as willing to construct the type using
Instead, we will continue to rely on our test suite to ensure that Keeping the |
If there is a This would satisfy the need for macros to access it, as well as document the hazards in a way that nobody can claim unsoundness. |
Description
The current implementation of the FfiSlice struct introduces potential undefined behavior (UB) due to the lack of safety guarantees when public fields are directly passed to an unsafe API (std::slice::from_raw_parts).
swift-bridge/src/lib.rs
Line 48 in 225380e
My PoC:
Cargo.toml:
main.rs:
Result:
Root Cause
The root cause of the issue is that the FfiSlice struct exposes its fields (start and len) as pub, allowing external code to manipulate them without enforcing the invariants required by std::slice::from_raw_parts. Since as_slice directly uses these fields in an unsafe block, any incorrect or invalid input will propagate into the unsafe API, leading to UB.
Proposed Solution
To address this issue, I propose the following changes:
Change start and len to private fields (pub(crate) or fully private) to prevent arbitrary external modifications.
Introduce a constructor function that validates the pointer and length before creating an instance of FfiSlice.
for example:
The text was updated successfully, but these errors were encountered: