Skip to content

Commit 8365df9

Browse files
authored
Rollup merge of #158522 - Urgau:runtime-symbols-posix, r=chenyukang
Lint against invalid POSIX symbol definitions This PR extends the `invalid_runtime_symbol_definitions` and `suspicious_runtime_symbol_definitions` lints to lint againts the following POSIX symbols: - I/O: `open`, `read`, `write`, `close` - Alloc: `malloc`, `realloc`, `free` - Program: `exit` This is meant to address the multiple reports of users tripping over `std` symbols: - [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) Those symbols are defined in `std`, so as long as the `std` crate is imported (and we are on a UNIX-like target) we lint on those symbols. Follow up to #155521
2 parents 7347c6d + 676a82f commit 8365df9

27 files changed

Lines changed: 353 additions & 32 deletions

compiler/rustc_hir/src/lang_items.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,14 @@ language_item_table! {
461461
MemCmp, sym::memcmp_fn, memcmp_fn, Target::ForeignFn, GenericRequirement::None;
462462
Bcmp, sym::bcmp_fn, bcmp_fn, Target::ForeignFn, GenericRequirement::None;
463463
StrLen, sym::strlen_fn, strlen_fn, Target::ForeignFn, GenericRequirement::None;
464+
Open, sym::open_fn, open_fn, Target::ForeignFn, GenericRequirement::None;
465+
Read, sym::read_fn, read_fn, Target::ForeignFn, GenericRequirement::None;
466+
Write, sym::write_fn, write_fn, Target::ForeignFn, GenericRequirement::None;
467+
Close, sym::close_fn, close_fn, Target::ForeignFn, GenericRequirement::None;
468+
Malloc, sym::malloc_fn, malloc_fn, Target::ForeignFn, GenericRequirement::None;
469+
Realloc, sym::realloc_fn, realloc_fn, Target::ForeignFn, GenericRequirement::None;
470+
Free, sym::free_fn, free_fn, Target::ForeignFn, GenericRequirement::None;
471+
Exit, sym::exit_fn, exit_fn, Target::ForeignFn, GenericRequirement::None;
464472
}
465473

466474
/// The requirement imposed on the generics of a lang item

compiler/rustc_hir/src/weak_lang_items.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,12 @@ weak_only_lang_items! {
4545
MemCmp,
4646
Bcmp,
4747
StrLen,
48+
Open,
49+
Read,
50+
Write,
51+
Close,
52+
Malloc,
53+
Realloc,
54+
Free,
55+
Exit,
4856
}

compiler/rustc_lint/src/runtime_symbols.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::{LateContext, LateLintPass, LintContext};
1111

1212
declare_lint! {
1313
/// The `invalid_runtime_symbol_definitions` lint checks the signature of items whose
14-
/// symbol name is a runtime symbol expected by `core` differs significantly from the
14+
/// symbol name is a runtime symbol expected by `core` or `std` differs significantly from the
1515
/// expected signature (like mismatch ABI, mismatch C variadics, mismatch argument count,
1616
/// missing return type, ...).
1717
///
@@ -31,7 +31,8 @@ declare_lint! {
3131
/// standard-library facility or undefined behavior may occur.
3232
///
3333
/// The symbols currently checked are `memcpy`, `memmove`, `memset`, `memcmp`,
34-
/// `bcmp` and `strlen`.
34+
/// `bcmp`, `strlen`, as well as the following POSIX symbols: `open`, `read`, `write`
35+
/// `close`, `malloc`, `realloc`, `free` and `exit`.
3536
///
3637
/// [^1]: https://doc.rust-lang.org/core/index.html#how-to-use-the-core-library
3738
pub INVALID_RUNTIME_SYMBOL_DEFINITIONS,
@@ -41,7 +42,7 @@ declare_lint! {
4142

4243
declare_lint! {
4344
/// The `suspicious_runtime_symbol_definitions` lint checks the signature of items whose
44-
/// symbol name is a runtime symbol expected by `core`.
45+
/// symbol name is a runtime symbol expected by `core` or `std`.
4546
///
4647
/// ### Example
4748
///
@@ -61,7 +62,8 @@ declare_lint! {
6162
/// standard-library facility or undefined behavior may occur.
6263
///
6364
/// The symbols currently checked are `memcpy`, `memmove`, `memset`, `memcmp`,
64-
/// `bcmp` and `strlen`.
65+
/// `bcmp`, `strlen`, as well as the following POSIX symbols: `open`, `read`, `write`
66+
/// `close`, `malloc`, `realloc`, `free` and `exit`.
6567
///
6668
/// [^1]: https://doc.rust-lang.org/core/index.html#how-to-use-the-core-library
6769
pub SUSPICIOUS_RUNTIME_SYMBOL_DEFINITIONS,
@@ -72,12 +74,22 @@ declare_lint! {
7274
declare_lint_pass!(RuntimeSymbols => [INVALID_RUNTIME_SYMBOL_DEFINITIONS, SUSPICIOUS_RUNTIME_SYMBOL_DEFINITIONS]);
7375

7476
static EXPECTED_SYMBOLS: &[ExpectedSymbol] = &[
77+
// `core` symbols
7578
ExpectedSymbol { symbol: "memcpy", lang: LanguageItems::memcpy_fn },
7679
ExpectedSymbol { symbol: "memmove", lang: LanguageItems::memmove_fn },
7780
ExpectedSymbol { symbol: "memset", lang: LanguageItems::memset_fn },
7881
ExpectedSymbol { symbol: "memcmp", lang: LanguageItems::memcmp_fn },
7982
ExpectedSymbol { symbol: "bcmp", lang: LanguageItems::bcmp_fn },
8083
ExpectedSymbol { symbol: "strlen", lang: LanguageItems::strlen_fn },
84+
// POSIX symbols
85+
ExpectedSymbol { symbol: "open", lang: LanguageItems::open_fn },
86+
ExpectedSymbol { symbol: "read", lang: LanguageItems::read_fn },
87+
ExpectedSymbol { symbol: "write", lang: LanguageItems::write_fn },
88+
ExpectedSymbol { symbol: "close", lang: LanguageItems::close_fn },
89+
ExpectedSymbol { symbol: "malloc", lang: LanguageItems::malloc_fn },
90+
ExpectedSymbol { symbol: "realloc", lang: LanguageItems::realloc_fn },
91+
ExpectedSymbol { symbol: "free", lang: LanguageItems::free_fn },
92+
ExpectedSymbol { symbol: "exit", lang: LanguageItems::exit_fn },
8193
];
8294

8395
#[derive(Copy, Clone, Debug)]

compiler/rustc_span/src/symbol.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,7 @@ symbols! {
616616
clone_closures,
617617
clone_fn,
618618
clone_from,
619+
close_fn,
619620
closure,
620621
closure_lifetime_binder,
621622
closure_to_fn_coercion,
@@ -901,6 +902,7 @@ symbols! {
901902
exhaustive_integer_patterns,
902903
exhaustive_patterns,
903904
existential_type,
905+
exit_fn,
904906
exp2f16,
905907
exp2f32,
906908
exp2f64,
@@ -1012,6 +1014,7 @@ symbols! {
10121014
format_unsafe_arg,
10131015
fp,
10141016
framework,
1017+
free_fn,
10151018
freeze,
10161019
freeze_impls,
10171020
freg,
@@ -1254,6 +1257,7 @@ symbols! {
12541257
macro_vis_matcher,
12551258
macros_in_extern,
12561259
main,
1260+
malloc_fn,
12571261
managed_boxes,
12581262
manually_drop,
12591263
map,
@@ -1479,6 +1483,7 @@ symbols! {
14791483
on_unmatched_args,
14801484
opaque,
14811485
opaque_module_name_placeholder: "<opaque>",
1486+
open_fn,
14821487
ops,
14831488
opt_out_copy,
14841489
optimize,
@@ -1663,9 +1668,11 @@ symbols! {
16631668
raw_identifiers,
16641669
raw_ref_op,
16651670
re_rebalance_coherence,
1671+
read_fn,
16661672
read_via_copy,
16671673
readonly,
16681674
realloc,
1675+
realloc_fn,
16691676
realtime,
16701677
reason,
16711678
reborrow,
@@ -2372,6 +2379,7 @@ symbols! {
23722379
write_box_via_move,
23732380
write_bytes,
23742381
write_fmt,
2382+
write_fn,
23752383
write_macro,
23762384
write_str,
23772385
write_via_move,

library/std/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@
322322
#![feature(borrowed_buf_init)]
323323
#![feature(bstr)]
324324
#![feature(bstr_internals)]
325+
#![feature(c_size_t)]
325326
#![feature(can_vector)]
326327
#![feature(cast_maybe_uninit)]
327328
#![feature(char_internals)]

library/std/src/sys/alloc/unix.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,25 @@ use super::{MIN_ALIGN, realloc_fallback};
22
use crate::alloc::Layout;
33
use crate::ptr;
44

5+
// Used by rustc for checking the definitions of other function with the same symbol names
6+
//
7+
// See the `invalid_runtime_symbols_definitions` lint.
8+
#[cfg(not(test))]
9+
mod runtime_symbols {
10+
use core::ffi::{c_size_t, c_void};
11+
12+
unsafe extern "C" {
13+
#[lang = "malloc_fn"]
14+
fn malloc(size: c_size_t) -> *mut c_void;
15+
16+
#[lang = "realloc_fn"]
17+
fn realloc(ptr: *mut c_void, size: c_size_t) -> *mut c_void;
18+
19+
#[lang = "free_fn"]
20+
fn free(ptr: *mut c_void);
21+
}
22+
}
23+
524
#[inline]
625
pub unsafe fn alloc(layout: Layout) -> *mut u8 {
726
// jemalloc provides alignment less than MIN_ALIGN for small allocations.

library/std/src/sys/exit.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,25 @@ cfg_select! {
6868
}
6969
}
7070

71+
#[cfg(not(test))]
72+
cfg_select! {
73+
any(
74+
target_family = "unix",
75+
target_os = "wasi",
76+
) => {
77+
// Used by rustc for checking the definitions of other function with the same symbol names
78+
//
79+
// See the `invalid_runtime_symbols_definitions` lint.
80+
mod runtime_symbols {
81+
unsafe extern "C" {
82+
#[lang = "exit_fn"]
83+
fn exit(status: core::ffi::c_int) -> !;
84+
}
85+
}
86+
}
87+
_ => {}
88+
}
89+
7190
pub fn exit(code: i32) -> ! {
7291
cfg_select! {
7392
target_os = "hermit" => {

library/std/src/sys/fs/unix.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,28 @@ use crate::sys::weak::weak;
102102
use crate::sys::{AsInner, AsInnerMut, FromInner, IntoInner, cvt, cvt_r};
103103
use crate::{mem, ptr};
104104

105+
// Used by rustc for checking the definitions of other function with the same symbol names
106+
//
107+
// See the `invalid_runtime_symbols_definitions` lint.
108+
#[cfg(not(test))]
109+
mod runtime_symbols {
110+
use core::ffi::{c_char, c_int, c_size_t, c_ssize_t, c_void};
111+
112+
unsafe extern "C" {
113+
#[lang = "open_fn"]
114+
fn open(pathname: *const c_char, flags: c_int, ...) -> c_int;
115+
116+
#[lang = "read_fn"]
117+
fn read(fd: c_int, buf: *mut c_void, count: c_size_t) -> c_ssize_t;
118+
119+
#[lang = "write_fn"]
120+
fn write(fd: c_int, buf: *const c_void, count: c_size_t) -> c_ssize_t;
121+
122+
#[lang = "close_fn"]
123+
fn close(fd: c_int) -> c_int;
124+
}
125+
}
126+
105127
pub struct File(FileDesc);
106128

107129
// FIXME: This should be available on Linux with all `target_env`.

src/tools/miri/tests/fail/function_calls/check_arg_abi.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![allow(invalid_runtime_symbol_definitions)]
2+
13
fn main() {
24
extern "Rust" {
35
fn malloc(size: usize) -> *mut std::ffi::c_void;

src/tools/miri/tests/fail/function_calls/check_arg_count_too_few_args.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![allow(invalid_runtime_symbol_definitions)]
2+
13
fn main() {
24
extern "C" {
35
fn malloc() -> *mut std::ffi::c_void;

0 commit comments

Comments
 (0)