Skip to content

Add lint againts invalid runtime symbol definitions#155521

Open
Urgau wants to merge 8 commits into
rust-lang:mainfrom
Urgau:runtime-symbols
Open

Add lint againts invalid runtime symbol definitions#155521
Urgau wants to merge 8 commits into
rust-lang:mainfrom
Urgau:runtime-symbols

Conversation

@Urgau
Copy link
Copy Markdown
Member

@Urgau Urgau commented Apr 19, 2026

View all comments

This PR adds a deny-by-default lint againts invalid runtime symbol definitions, those runtime symbols are assumed and used by core1 and rustc with a specific definition.

We have had multiple reports of users tripping over std symbols (addressed in a future PR):

This PR is a second attempt after #146505, where T-lang had some reservations about a blanket lint that does not check the signature, which is now done with this PR, and about linting of std runtime symbols when std is not linked, which this PR omits by not including any std runtime symbols (for now).

invalid_runtime_symbol_definitions

(deny-by-default)

The invalid_runtime_symbol_definitions lint checks the signature of items whose symbol name is a runtime symbols expected by core.

Example

#[unsafe(no_mangle)]
pub fn memcmp() {} // invalid definition of the `memcmp` runtime symbol
error: invalid definition of the runtime `memcmp` symbol used by the standard library
 --> a.rs:2:1
  |
4 | fn memcmp() {}
  | ^^^^^^^^^^^
  |
  = note: expected `unsafe extern "C" fn(*const c_void, *const c_void, usize) -> i32`
          found    `fn()`
  = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "memcmp")]`, or `#[link_name = "memcmp"]`
  = note: `#[deny(invalid_runtime_symbol_definitions)]` on by default

Explanation

Up-most care is required when defining runtime symbols assumed and used by the standard library. They must follow the C specification, not use any standard-library facility or undefined behavior may occur.

The symbols currently checked are memcpy, memmove, memset, memcmp, bcmp and strlen.

@rustbot labels +I-lang-nominated +T-lang +needs-fcp +A-lints
cc @rust-lang/lang-ops
r? compiler

Footnotes

  1. https://doc.rust-lang.org/core/index.html#how-to-use-the-core-library

@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 19, 2026

These commits modify the Cargo.lock file. Unintentional changes to Cargo.lock can be introduced when switching branches and rebasing PRs.

If this was unintentional then you should revert the changes before this PR is merged.
Otherwise, you can ignore this comment.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Apr 19, 2026
@rustbot rustbot added A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. I-lang-nominated Nominated for discussion during a lang team meeting. needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. T-lang Relevant to the language team labels Apr 19, 2026
@rust-log-analyzer

This comment has been minimized.

@Urgau Urgau force-pushed the runtime-symbols branch from 46b7db0 to d81044c Compare April 19, 2026 16:26
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@Urgau Urgau force-pushed the runtime-symbols branch from 4debba0 to 058c0e4 Compare April 19, 2026 19:43
@rust-log-analyzer

This comment has been minimized.

///
/// ### Explanation
///
/// Up-most care is required when defining runtime symbols assumed and
Copy link
Copy Markdown
Contributor

@PatchMixolydic PatchMixolydic Apr 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:

Suggested change
/// Up-most care is required when defining runtime symbols assumed and
/// Utmost care is required when defining runtime symbols assumed and

View changes since the review

@rust-log-analyzer

This comment has been minimized.

@traviscross traviscross added the P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang label Apr 19, 2026
@rust-log-analyzer

This comment has been minimized.

@Urgau Urgau force-pushed the runtime-symbols branch from 1b7638a to ed313a0 Compare April 20, 2026 06:11
@rust-log-analyzer

This comment has been minimized.

@Urgau Urgau force-pushed the runtime-symbols branch from ed313a0 to 0e3b44e Compare April 20, 2026 06:51
@rustbot

This comment has been minimized.

@traviscross
Copy link
Copy Markdown
Contributor

Thanks @Urgau for adjusting based on the feedback and moving this forward.

@rfcbot fcp merge lang

@traviscross traviscross added the I-lang-radar Items that are on lang's radar and will need eventual work or consideration. label Apr 22, 2026
@traviscross

This comment was marked as duplicate.

@jackh726
Copy link
Copy Markdown
Member

jackh726 commented Apr 22, 2026

Should this also include rust_eh_personality?

@steffahn
Copy link
Copy Markdown
Member

As far as I understood the lang meeting discussion, there was no concern with this PR.

But some opinion that it doesn’t fully replace the previous PR, since some warn-by-default lint more generally applicable (and to actually address the user reports, which were about open and read) might also be desirable. All of this can of course be follow-up work so it shouldn’t block us from getting the lint as in this PR; but it’s be useful to clarify that the user reports (currently mentioned in the OP of this PR) aren’t addressed yet with this PR merged, and in this regard this isn’t a full replacement of #146505.

@scottmcm
Copy link
Copy Markdown
Member

My interpretation here: this lint is valuable because the wrong signature for something on the well-known list is clearly and always wrong, so deny makes sense. We should have this lint. (And I'm find expanding to more functions so long as they meet that "definitely incontrovertibly wrong signature for that name that rustc or one of your linked libraries uses" bar. I don't know if we include extern function declarations in rlibs, but if this expanded to a general check that you're not conflicting with other rust libraries that'd also be cool -- not this PR I assume, though.)

Another lint, for "it's very suspicious that you're defining an unmangled open" kinds of things probably also makes sense. That might not be deny though, since it's not as unquestionably wrong. It's a rare case of a rustc lint where I'm plausibly fine with the only mitigation being to allow it, since you could just crate-level-allow it for those very few crates where doing this is intentional because it's trying to implement such things. (Notably if you're trying to define a memcpy you'll need to do extra steps already anyway, IIRC.) But that wouldn't be this PR.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels May 15, 2026
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request May 15, 2026
Add lint againts invalid runtime symbol definitions

This PR adds a deny-by-default lint againts invalid runtime symbol definitions, those runtime symbols are assumed and used by `core`[^1] and `rustc` with a specific definition.

We have had multiple reports of users tripping over `std` symbols (addressed in a future PR):
 - [Why does `#[no_mangle] fn open() {}` make `cargo t` hang?](https://users.rust-lang.org/t/why-does-no-mangle-fn-open-make-cargo-t-hang/103423)
 - [Pointer becomes misaligned in test with `no_mangle`](https://users.rust-lang.org/t/pointer-becomes-misaligned-in-test-with-no-mangle/126580)

This PR is a second attempt after rust-lang#146505, where T-lang had [some reservations](rust-lang#146505 (comment)) about a blanket lint that does not check the signature, which is now done with this PR, and about linting of `std` runtime symbols when std is not linked, which this PR omits by not including any std runtime symbols (for now).

## `invalid_runtime_symbol_definitions`

*(deny-by-default)*

The `invalid_runtime_symbol_definitions` lint checks the signature of items whose symbol name is a runtime symbols expected by `core`.

### Example

```rust,compile_fail
#[unsafe(no_mangle)]
pub fn memcmp() {} // invalid definition of the `memcmp` runtime symbol
```

```text
error: invalid definition of the runtime `memcmp` symbol used by the standard library
 --> a.rs:2:1
  |
4 | fn memcmp() {}
  | ^^^^^^^^^^^
  |
  = note: expected `unsafe extern "C" fn(*const c_void, *const c_void, usize) -> i32`
          found    `fn()`
  = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "memcmp")]`, or `#[link_name = "memcmp"]`
  = note: `#[deny(invalid_runtime_symbol_definitions)]` on by default
```

### Explanation

Up-most care is required when defining runtime symbols assumed and used by the standard library. They must follow the C specification, not use any standard-library facility or undefined behavior may occur.

The symbols currently checked are `memcpy`, `memmove`, `memset`, `memcmp`, `bcmp` and `strlen`.

[^1]: https://doc.rust-lang.org/core/index.html#how-to-use-the-core-library
@JonathanBrouwer
Copy link
Copy Markdown
Contributor

@bors r-
#156595 (comment)

@rust-bors rust-bors Bot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels May 15, 2026
@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented May 15, 2026

This pull request was unapproved.

This PR was contained in a rollup (#156595), which was unapproved.

View changes since this unapproval

@Urgau
Copy link
Copy Markdown
Member Author

Urgau commented May 15, 2026

@bors try jobs=x86_64-gnu-llvm-21-3

@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request May 15, 2026
Add lint againts invalid runtime symbol definitions


try-job: x86_64-gnu-llvm-21-3
@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented May 15, 2026

☀️ Try build successful (CI)
Build commit: 2a5459b (2a5459b18522e33decce2347038b844387a7451c, parent: 88ba7fbe0a6eda36e0adbfd0482856f3784031b9)

@Urgau
Copy link
Copy Markdown
Member Author

Urgau commented May 15, 2026

@bors r=davidtwco

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented May 15, 2026

📌 Commit 1025e4d has been approved by davidtwco

It is now in the queue for this repository.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels May 15, 2026
Zalathar added a commit to Zalathar/rust that referenced this pull request May 15, 2026
Add lint againts invalid runtime symbol definitions

This PR adds a deny-by-default lint againts invalid runtime symbol definitions, those runtime symbols are assumed and used by `core`[^1] and `rustc` with a specific definition.

We have had multiple reports of users tripping over `std` symbols (addressed in a future PR):
 - [Why does `#[no_mangle] fn open() {}` make `cargo t` hang?](https://users.rust-lang.org/t/why-does-no-mangle-fn-open-make-cargo-t-hang/103423)
 - [Pointer becomes misaligned in test with `no_mangle`](https://users.rust-lang.org/t/pointer-becomes-misaligned-in-test-with-no-mangle/126580)

This PR is a second attempt after rust-lang#146505, where T-lang had [some reservations](rust-lang#146505 (comment)) about a blanket lint that does not check the signature, which is now done with this PR, and about linting of `std` runtime symbols when std is not linked, which this PR omits by not including any std runtime symbols (for now).

## `invalid_runtime_symbol_definitions`

*(deny-by-default)*

The `invalid_runtime_symbol_definitions` lint checks the signature of items whose symbol name is a runtime symbols expected by `core`.

### Example

```rust,compile_fail
#[unsafe(no_mangle)]
pub fn memcmp() {} // invalid definition of the `memcmp` runtime symbol
```

```text
error: invalid definition of the runtime `memcmp` symbol used by the standard library
 --> a.rs:2:1
  |
4 | fn memcmp() {}
  | ^^^^^^^^^^^
  |
  = note: expected `unsafe extern "C" fn(*const c_void, *const c_void, usize) -> i32`
          found    `fn()`
  = help: either fix the signature or remove any attributes like `#[unsafe(no_mangle)]`, `#[unsafe(export_name = "memcmp")]`, or `#[link_name = "memcmp"]`
  = note: `#[deny(invalid_runtime_symbol_definitions)]` on by default
```

### Explanation

Up-most care is required when defining runtime symbols assumed and used by the standard library. They must follow the C specification, not use any standard-library facility or undefined behavior may occur.

The symbols currently checked are `memcpy`, `memmove`, `memset`, `memcmp`, `bcmp` and `strlen`.

[^1]: https://doc.rust-lang.org/core/index.html#how-to-use-the-core-library
rust-bors Bot pushed a commit that referenced this pull request May 15, 2026
Rollup of 11 pull requests

Successful merges:

 - #148788 (Unconstrained parameter fix)
 - #153238 (debuginfo: slices are DW_TAG_array_type's)
 - #155521 (Add lint againts invalid runtime symbol definitions)
 - #156319 (Require EIIs to be defined when we compile a rust dylib)
 - #156452 (Implement pinned drop sugar)
 - #156600 (Make const param default test reproduce original ICE)
 - #156493 (actually run the temp_dir doctest)
 - #156556 (Require UTF-8 in `Utf8Pattern::StringPattern`)
 - #156565 (delegation: emit error when self type is not specified and accessed)
 - #156586 (Use DropCtxt::new_block and new_block_with_statements systematically.)
 - #156587 (Correctly handle associated items in rustdoc macro expansion)
@Urgau
Copy link
Copy Markdown
Member Author

Urgau commented May 15, 2026

Failed again in #156610 (comment)
@bors r-

@rust-bors rust-bors Bot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels May 15, 2026
@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented May 15, 2026

This pull request was unapproved.

This PR was contained in a rollup (#156610), which was unapproved.

View changes since this unapproval

@Urgau
Copy link
Copy Markdown
Member Author

Urgau commented May 15, 2026

@bors rollup=never (for next time)

@Urgau
Copy link
Copy Markdown
Member Author

Urgau commented May 15, 2026

@rustbot ping rust-for-linux

Seems like core::ffi::c_char (i8, defined here) is not align with ffi::c_char (u8), causing a mismatch signature for strlen.

Is the mismatch between core and RfL expected? If it's expected, fixing the mismatch seems tricky and time consuming, would a #[allow] be possible?

@rustbot rustbot added the A-rust-for-linux Relevant for the Rust-for-Linux project label May 15, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented May 15, 2026

Hey Rust for Linux group! It looks like something broke the Rust for Linux integration.
Could you try to take a look?
In case it's useful, here are some instructions for tackling these sorts of issues.

cc @rust-lang/rust-for-linux

@nbdd0121
Copy link
Copy Markdown
Member

It is intended, because kernel C code is compiled with -funsigned-char. Could this lint be changed to check for ABI compatibility instead of exact type equivalence?

@Urgau
Copy link
Copy Markdown
Member Author

Urgau commented May 15, 2026

It is intended, because kernel C code is compiled with -funsigned-char

That doesn't really make sense to me, if the C code is compiled with a flag that change the sign of char/c_char, I would think the same thing should be done with Rust.

Could this lint be changed to check for ABI compatibility instead of exact type equivalence?

Not easily, it's using a InferCtxt to check of the function signature against a lang item.

I could probably do some type-system foolery that check against modified function signature that replaces *const u8 by *const i8, but I really don't want to do that unless all other options have been exhausted.

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

Labels

A-compiler-builtins Area: compiler-builtins (https://github.com/rust-lang/compiler-builtins) A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. A-rust-for-linux Relevant for the Rust-for-Linux project disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. I-lang-radar Items that are on lang's radar and will need eventual work or consideration. needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team T-libs Relevant to the library team, which will review and decide on the PR/issue. to-announce Announce this issue on triage meeting

Projects

None yet

Development

Successfully merging this pull request may close these issues.