rust-lang / rust-lang/rust

`slice::element_offset` can produce false positives via current operational semantics

Open
#161,376 13 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-raw-pointers C-bug T-lang T-libs T-opsem
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

As of https://github.com/rust-lang/rust/pull/126770

https://github.com/rust-lang/rust/blob/d6080a1e2f79a051eeba6ca543672a7ea3d3f8cf/library/core/src/slice/mod.rs#L4573-L4584

the element_offset method is implemented by comparing the addresses of two pointers. For elements within the same allocation, this has the correct behaviour, however address equality and ordering between independent allocations have no guarantees via LLVM and I expect the intended rust opsem. For example, we want to be able to alias immutable allocations with the same data, and we want to be able to elide mallocs that are detected to not escape a scope, and the compiler invents addresses for the objects in that malloc: This is capable of producing pointers to independent live allocations with the same address.

With pointer comparison defined to ignore provenance, it cannot observe this distinction so can give a false positive, identifying an arbitrary element in a slice as having the "same address" as a pointer in a different allocation.

An example of a false positive would be

fn foo(x: &[u32]) -> &u32 {
    assert!(x.len() > 0);
    x.element_offset(&10).unwrap()
}
// it is legitimate to transform this into 
fn foo(x: &[u32]) -> &u32 {
    assert!(x.len() > 0);
    // decide that the address of the temporary is == x.as_ptr().addr(), and simplify
    &x[0]
}

(edit for clarification: I'm not aware of rust's semantics here, I just know that in the past llvm has had independent allocations be incomparable in this way, and while talking with nia we found a series of examples of llvm treating them as such)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with library/core/src/slice/mod.rs around lines 4573-4584 and the linked pull request 126770. Investigate the Rust operational-semantics and LLVM pointer-comparison assumptions described in the issue, especially for independent allocations. Done means reaching a clear decision on whether element_offset can produce false positives and defining the required semantic or implementation change.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.