Skip to content

#[link_section] is unsound on Harvard architectures #76507

Closed

Description

@H2CO3

As pointed out in this thread on URLO, it is possible to read arbitrary memory without unsafe using the link_section attribute on architectures with separate address spaces for code and data.

To cite OP's code:

// Store PROG_BLOB in program space, ".text" would also work
#[link_section = ".progmem"]
static PROG_BLOB: [u8; 128] = [42; 128];

fn main() -> ! {
    let mut serial = /* initialize a serial output */;

    let mut idx = 0;
    loop {
        // This access is illegal, because Rust will emit a normal load
        // instruction, whereas the data is in the program space,
        // requiring a special load instruction.
        let b = PROG_BLOB[idx];

        // Dumping arbitrary RAM data!
        ufmt::uwrite!(&mut serial, "{:?} ", b).void_unwrap();

        idx += 1;
        if idx == BIG_BLOB.len() {
            break
        }
    }
    loop {
        // Just loop forever
    }
}

I expected to see this happen: the code should not compile, as it reads OOB memory.

Instead, this happened: The code compiles and outputs incorrect values, indicating UB.

Activity

  1. Nemo157 commented on Sep 9, 2020

    @Nemo157
    Contributor

    See also #28179 and #72209, maybe this attribute could also be pulled under the unsafe_code lint (even on non-Harvard architectures it seems plausible that there's some way to cause unsoundness with it depending on the default linker scripts?).

  2. added
    I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness
    on Sep 15, 2020
  3. added
    I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
    on Sep 15, 2020
  4. added
    A-linkageArea: linking into static, shared libraries and binaries
    T-langRelevant to the language team
    on Sep 15, 2020
  5. apiraino commented on Sep 16, 2020

    @apiraino
    Contributor

    Assigning P-low as discussed as part of the Prioritization Working Group procedure and removing I-prioritize.

  6. added
    P-lowLow priority
    and removed
    I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
    on Sep 16, 2020
  7. DemiMarie commented on Apr 14, 2022

    @DemiMarie
    Contributor

    I’m pretty sure #[link_section] is unsafe anyway. At a minimum I suspect you can segfault by putting a function in non-executable memory, or break assumptions by putting an (immutable) static with a nonzero value in a section that gets zeroed.

  8. added
    E-needs-mcveCall for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example
    on Oct 11, 2023
  9. geofft commented on Aug 28, 2024

    @geofft
    Contributor

    Now that we have #123757, the 2024 edition will require writing #[link_section] as #[unsafe(link_section)] and it is prohibited under #![forbid(unsafe_code)]. See this playground example. Does that resolve this issue? (There wasn't an expectation that we could get Rust to emit the right load operations, or something, right?)

  10. RalfJung commented on Aug 28, 2024

    @RalfJung
    Member
  11. RalfJung commented on Aug 28, 2024

    @RalfJung
    Member

    Ah, but that's not an I-unsound issue, so maybe let's track adding documentation in #123757 instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-linkageArea: linking into static, shared libraries and binariesC-bugCategory: This is a bug.E-needs-mcveCall for participation: This issue has a repro, but needs a Minimal Complete and Verifiable ExampleI-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-lowLow priorityT-langRelevant to the language team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions