rust-lang / rust-lang/rust-clippy
`unsafe { ffi(generic_bytes.as_ref().as_ptr(), generic_bytes.as_ref().len()) }` trusts `AsRef` impl
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 13.5k
- Forks
- 2.2k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 32
Description
What it does
Consider the example below. example() is (very likely, depending on ffi()) unsound. The problem is that user-provided AsRef implementations could use interior mutability, so that the two .as_ref() calls unexpectedly return different slices.
fn example(bytes: impl AsRef<[u8]>) {
unsafe {
ffi(bytes.as_ref().as_ptr(), bytes.as_ref().len())
}
}
#[derive(Default)]
struct Evil {
toggle: AtomicUsize,
}
impl AsRef<[u8]> for Evil {
fn as_ref(&self) -> &[u8] {
if self.toggle.fetch_xor(1, Ordering::Relaxed) == 0 {
b"hi"
} else {
b"there"
}
}
}
To be fair, the example is quite contrived, and AsRef is intended for cheap reference to reference conversions, so that real-world implementations with interior mutability are unlikely to exist.
Lint Name
trusted_asref
Category
correctness, suspicious
Advantage
Checking examples found via https://github.com/search?q=language%3Arust+as_ref%28%29.as_ptr%28%29&type=code, this appears to be a common soundness issue.
Drawbacks
There may be false positives, as we cannot know what ffi() actually does.
Example
fn example(bytes: impl AsRef<[u8]>) {
unsafe {
ffi(bytes.as_ref().as_ptr(), bytes.as_ref().len())
}
}
Could be written as:
fn example(bytes: impl AsRef<[u8]>) {
let bytes = bytes.as_ref();
unsafe {
ffi(bytes.as_ptr(), bytes.len())
}
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by searching the repository for the trusted_asref lint name and existing lint examples or tests. Use the issue's two Rust examples to define the reported pattern and the single-binding form that should avoid it, then add coverage showing the intended behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- devtools, tooling
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100