Skip to content

Add missing module flags for -Zfunction-return=thunk-extern#130824

Merged
bors merged 1 commit into
rust-lang:masterfrom
Darksonn:fix-function-return
Oct 8, 2024
Merged

Add missing module flags for -Zfunction-return=thunk-extern#130824
bors merged 1 commit into
rust-lang:masterfrom
Darksonn:fix-function-return

Conversation

@Darksonn
Copy link
Copy Markdown
Member

This fixes a bug in the -Zfunction-return=thunk-extern flag. The flag needs to be passed onto LLVM to ensure that functions such as asan.module_ctor and asan.module_dtor that are created internally in LLVM have the mitigation applied to them.

This was originally discovered in the Linux kernel.

Original flag PR: #116892
PR for similar issue: #129373
Tracking issue: #116853

cc @ojeda
r? @wesleywiser

@Darksonn
Copy link
Copy Markdown
Member Author

Click to see output with and without PR

Without this PR:

aliceryhl@aliceryhl-l:~/rust-for-linux$ rustc --version --verbose
rustc 1.81.0 (eeb90cda1 2024-09-04)
binary: rustc
commit-hash: eeb90cda1969383f56a2637cbd3037bdf598841c
commit-date: 2024-09-04
host: x86_64-unknown-linux-gnu
release: 1.81.0
LLVM version: 18.1.7

aliceryhl@aliceryhl-l:~/rust-for-linux$ make LLVM=1 O=~/lout 
make[1]: Entering directory '/home/aliceryhl/lout'
  SYNC    include/config/auto.conf.cmd
  GEN     Makefile
  GEN     Makefile
  CALL    /home/aliceryhl/rust-for-linux/scripts/checksyscalls.sh
  DESCEND objtool
  INSTALL libsubcmd_headers
  RUSTC L rust/core.o
rust/core.o: warning: objtool: asan.module_ctor+0x13: 'naked' return found in MITIGATION_RETHUNK build
rust/core.o: warning: objtool: asan.module_dtor+0x13: 'naked' return found in MITIGATION_RETHUNK build
  EXPORTS rust/exports_core_generated.h
  RUSTC P rust/libmacros.so
  RUSTC L rust/compiler_builtins.o
rust/compiler_builtins.o: warning: objtool: asan.module_ctor+0x0: 'naked' return found in MITIGATION_RETHUNK build
  RUSTC L rust/alloc.o
rust/alloc.o: warning: objtool: asan.module_ctor+0x13: 'naked' return found in MITIGATION_RETHUNK build
rust/alloc.o: warning: objtool: asan.module_dtor+0x13: 'naked' return found in MITIGATION_RETHUNK build
  EXPORTS rust/exports_alloc_generated.h
  RUSTC L rust/bindings.o
rust/bindings.o: warning: objtool: asan.module_ctor+0x0: 'naked' return found in MITIGATION_RETHUNK build
  EXPORTS rust/exports_bindings_generated.h
  RUSTC L rust/build_error.o
  RUSTC L rust/uapi.o
rust/uapi.o: warning: objtool: asan.module_ctor+0x0: 'naked' return found in MITIGATION_RETHUNK build
  RUSTC L rust/kernel.o
rust/kernel.o: warning: objtool: asan.module_ctor+0x13: 'naked' return found in MITIGATION_RETHUNK build
rust/kernel.o: warning: objtool: asan.module_dtor+0x13: 'naked' return found in MITIGATION_RETHUNK build
  EXPORTS rust/exports_kernel_generated.h
  CC      rust/exports.o
  AR      rust/built-in.a
  RUSTC     samples/rust/rust_print.o
samples/rust/rust_print.o: warning: objtool: asan.module_ctor+0x13: 'naked' return found in MITIGATION_RETHUNK build
samples/rust/rust_print.o: warning: objtool: asan.module_dtor+0x13: 'naked' return found in MITIGATION_RETHUNK build
  AR      samples/rust/built-in.a
  AR      samples/built-in.a
  AR      built-in.a
  AR      vmlinux.a
  LD      vmlinux.o
  OBJCOPY modules.builtin.modinfo
  GEN     modules.builtin
  MODPOST vmlinux.symvers
  UPD     include/generated/utsversion.h
  CC      init/version-timestamp.o
  LD      vmlinux
  NM      System.map
  SORTTAB vmlinux
  VOFFSET arch/x86/boot/compressed/../voffset.h
  CC      arch/x86/boot/compressed/misc.o
  OBJCOPY arch/x86/boot/compressed/vmlinux.bin
  GZIP    arch/x86/boot/compressed/vmlinux.bin.gz
  MKPIGGY arch/x86/boot/compressed/piggy.S
  AS      arch/x86/boot/compressed/piggy.o
  LD      arch/x86/boot/compressed/vmlinux
  ZOFFSET arch/x86/boot/zoffset.h
  AS      arch/x86/boot/header.o
  CC      arch/x86/boot/version.o
  LD      arch/x86/boot/setup.elf
  OBJCOPY arch/x86/boot/setup.bin
  OBJCOPY arch/x86/boot/vmlinux.bin
  BUILD   arch/x86/boot/bzImage
Kernel: arch/x86/boot/bzImage is ready  (#5)
make[1]: Leaving directory '/home/aliceryhl/lout'

With this PR:

aliceryhl@aliceryhl-l:~/rust-for-linux$ rustc --version --verbose
rustc 1.83.0-dev
binary: rustc
commit-hash: unknown
commit-date: unknown
host: x86_64-unknown-linux-gnu
release: 1.83.0-dev
LLVM version: 19.1.0

aliceryhl@aliceryhl-l:~/rust-for-linux$ make LLVM=1 O=~/lout 
make[1]: Entering directory '/home/aliceryhl/lout'
  SYNC    include/config/auto.conf.cmd
  GEN     Makefile
  GEN     Makefile
  CALL    /home/aliceryhl/rust-for-linux/scripts/checksyscalls.sh
  DESCEND objtool
  INSTALL libsubcmd_headers
  RUSTC L rust/core.o
  EXPORTS rust/exports_core_generated.h
  RUSTC P rust/libmacros.so
  RUSTC L rust/compiler_builtins.o
  RUSTC L rust/alloc.o
  EXPORTS rust/exports_alloc_generated.h
  RUSTC L rust/bindings.o
  EXPORTS rust/exports_bindings_generated.h
  RUSTC L rust/build_error.o
  RUSTC L rust/uapi.o
  RUSTC L rust/kernel.o
  EXPORTS rust/exports_kernel_generated.h
  CC      rust/exports.o
  AR      rust/built-in.a
  RUSTC     samples/rust/rust_print.o
  AR      samples/rust/built-in.a
  AR      samples/built-in.a
  AR      built-in.a
  AR      vmlinux.a
  LD      vmlinux.o
  OBJCOPY modules.builtin.modinfo
  GEN     modules.builtin
  MODPOST vmlinux.symvers
  UPD     include/generated/utsversion.h
  CC      init/version-timestamp.o
  LD      vmlinux
  NM      System.map
  SORTTAB vmlinux
  VOFFSET arch/x86/boot/compressed/../voffset.h
  CC      arch/x86/boot/compressed/misc.o
  OBJCOPY arch/x86/boot/compressed/vmlinux.bin
  GZIP    arch/x86/boot/compressed/vmlinux.bin.gz
  MKPIGGY arch/x86/boot/compressed/piggy.S
  AS      arch/x86/boot/compressed/piggy.o
  LD      arch/x86/boot/compressed/vmlinux
  ZOFFSET arch/x86/boot/zoffset.h
  AS      arch/x86/boot/header.o
  CC      arch/x86/boot/version.o
  LD      arch/x86/boot/setup.elf
  OBJCOPY arch/x86/boot/setup.bin
  OBJCOPY arch/x86/boot/vmlinux.bin
  BUILD   arch/x86/boot/bzImage
Kernel: arch/x86/boot/bzImage is ready  (#6)
make[1]: Leaving directory '/home/aliceryhl/lout'

@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. labels Sep 25, 2024
Copy link
Copy Markdown
Contributor

@ojeda ojeda left a comment

Choose a reason for hiding this comment

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

Looks good to me -- thanks for fixing this!

Comment thread tests/codegen/function-return.rs Outdated
Comment thread compiler/rustc_codegen_llvm/src/context.rs Outdated
@ojeda
Copy link
Copy Markdown
Contributor

ojeda commented Sep 25, 2024

@rustbot label A-rust-for-linux

@rustbot rustbot added the A-rust-for-linux Relevant for the Rust-for-Linux project label Sep 25, 2024
ojeda pushed a commit to ojeda/linux that referenced this pull request Sep 26, 2024
When enabling both KASAN and RETHUNK, objtool emits the following
warnings:

    rust/core.o: warning: objtool: asan.module_ctor+0x13: 'naked' return found in MITIGATION_RETHUNK build
    rust/core.o: warning: objtool: asan.module_dtor+0x13: 'naked' return found in MITIGATION_RETHUNK build

This is caused by the -Zfunction-return=thunk-extern flag in rustc not
informing LLVM about the mitigation at the module level (it does so at
the function level only currently, which covers most cases, but both
are required), which means that the KASAN functions asan.module_ctor
and asan.module_dtor are generated without the rethunk mitigation.

The other mitigations that we enabled for Rust (SLS, RETPOLINE) do not
have the same bug, as they're being applied through the target-feature
functionality instead.

This is being fixed for rustc 1.83.0, so update Kconfig to reject this
configuration on older compilers.

Link: rust-lang/rust#130824
Fixes: d786855 ("x86/rust: support MITIGATION_RETHUNK")
Reported-by: Miguel Ojeda <ojeda@kernel.org>
Closes: https://lore.kernel.org/all/CANiq72myZL4_poCMuNFevtpYYc0V0embjSuKb7y=C+m3vVA_8g@mail.gmail.com/
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Link: https://lore.kernel.org/r/20240926093849.1192264-1-aliceryhl@google.com
[ Reworded to add the details mentioned in the list. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
@wesleywiser
Copy link
Copy Markdown
Member

Thanks @Darksonn and @ojeda!

@bors r+ rollup

@bors
Copy link
Copy Markdown
Collaborator

bors commented Oct 7, 2024

📌 Commit 540e41f has been approved by wesleywiser

It is now in the queue for this repository.

@bors bors 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-review Status: Awaiting review from the assignee but also interested parties. labels Oct 7, 2024
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request Oct 7, 2024
…sleywiser

Add missing module flags for `-Zfunction-return=thunk-extern`

This fixes a bug in the `-Zfunction-return=thunk-extern` flag. The flag needs to be passed onto LLVM to ensure that functions such as `asan.module_ctor` and `asan.module_dtor` that are created internally in LLVM have the mitigation applied to them.

This was originally discovered [in the Linux kernel](https://lore.kernel.org/all/CANiq72myZL4_poCMuNFevtpYYc0V0embjSuKb7y=C+m3vVA_8g@mail.gmail.com/).

Original flag PR: rust-lang#116892
PR for similar issue: rust-lang#129373
Tracking issue: rust-lang#116853

cc `@ojeda`
r? `@wesleywiser`
bors added a commit to rust-lang-ci/rust that referenced this pull request Oct 7, 2024
…llaumeGomez

Rollup of 4 pull requests

Successful merges:

 - rust-lang#130824 (Add missing module flags for `-Zfunction-return=thunk-extern`)
 - rust-lang#131170 (Fix `target_vendor` in non-IDF Xtensa ESP32 targets)
 - rust-lang#131369 (Update books)
 - rust-lang#131370 (rustdoc: improve `<wbr>`-insertion for SCREAMING_CAMEL_CASE)

r? `@ghost`
`@rustbot` modify labels: rollup
bors added a commit to rust-lang-ci/rust that referenced this pull request Oct 8, 2024
Rollup of 7 pull requests

Successful merges:

 - rust-lang#130824 (Add missing module flags for `-Zfunction-return=thunk-extern`)
 - rust-lang#131170 (Fix `target_vendor` in non-IDF Xtensa ESP32 targets)
 - rust-lang#131355 (Add tests for some old fixed issues)
 - rust-lang#131369 (Update books)
 - rust-lang#131370 (rustdoc: improve `<wbr>`-insertion for SCREAMING_CAMEL_CASE)
 - rust-lang#131379 (Fix utf8-bom test)
 - rust-lang#131385 (Un-vacation myself)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 4d63896 into rust-lang:master Oct 8, 2024
@rustbot rustbot added this to the 1.83.0 milestone Oct 8, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Oct 8, 2024
Rollup merge of rust-lang#130824 - Darksonn:fix-function-return, r=wesleywiser

Add missing module flags for `-Zfunction-return=thunk-extern`

This fixes a bug in the `-Zfunction-return=thunk-extern` flag. The flag needs to be passed onto LLVM to ensure that functions such as `asan.module_ctor` and `asan.module_dtor` that are created internally in LLVM have the mitigation applied to them.

This was originally discovered [in the Linux kernel](https://lore.kernel.org/all/CANiq72myZL4_poCMuNFevtpYYc0V0embjSuKb7y=C+m3vVA_8g@mail.gmail.com/).

Original flag PR: rust-lang#116892
PR for similar issue: rust-lang#129373
Tracking issue: rust-lang#116853

cc ``@ojeda``
r? ``@wesleywiser``
@Darksonn Darksonn deleted the fix-function-return branch October 8, 2024 19:08
LorenzoBianconi pushed a commit to LorenzoBianconi/linux-pinctrl that referenced this pull request Nov 3, 2024
When enabling both KASAN and RETHUNK, objtool emits the following
warnings:

    rust/core.o: warning: objtool: asan.module_ctor+0x13: 'naked' return found in MITIGATION_RETHUNK build
    rust/core.o: warning: objtool: asan.module_dtor+0x13: 'naked' return found in MITIGATION_RETHUNK build

This is caused by the -Zfunction-return=thunk-extern flag in rustc not
informing LLVM about the mitigation at the module level (it does so at
the function level only currently, which covers most cases, but both
are required), which means that the KASAN functions asan.module_ctor
and asan.module_dtor are generated without the rethunk mitigation.

The other mitigations that we enabled for Rust (SLS, RETPOLINE) do not
have the same bug, as they're being applied through the target-feature
functionality instead.

This is being fixed for rustc 1.83.0, so update Kconfig to reject this
configuration on older compilers.

Link: rust-lang/rust#130824
Fixes: d786855 ("x86/rust: support MITIGATION_RETHUNK")
Reported-by: Miguel Ojeda <ojeda@kernel.org>
Closes: https://lore.kernel.org/all/CANiq72myZL4_poCMuNFevtpYYc0V0embjSuKb7y=C+m3vVA_8g@mail.gmail.com/
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Link: https://lore.kernel.org/r/20240926093849.1192264-1-aliceryhl@google.com
[ Reworded to add the details mentioned in the list. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request May 27, 2026
…nethercote

Add uwtable annotation to modules when required

When unwind tables are enabled with `-Cforce-unwind-tables=y`, Rust will annotate all functions with the `uwtable` annotation. However, this annotation is missing on modules, which leads to incorrect unwind tables being generated by LLVM for constructors (such as `asan.module_ctor`).

This was discovered because it leads to a crash in Linux when KASAN and dynamic shadow call stack are both enabled. In this scenario, the kernel uses the unwind tables to locate the `paciasp` and `autiasp` instructions in each function and patches the machine code at boot to use the shadow call stack instructions instead. However, LLVM's AArch64PointerAuth pass emits DWARF info for `paciasp` whenever `-g` is passed, but only emits DWARF info for `autiasp` when the `uwtable` attribute is present. Since the `uwtable` annotation is missing for modules, the relevant directives are generated for only the `autiasp` instruction in `asan.module_ctor`, and not for the `paciasp` instruction. This causes the kernel's dynamic SCS logic to patch the prolouge of `asan.module_ctor`, but not the epilogue. This leads to a crash as the shadow call stack becomes unbalanced.

The fact that LLVM doesn't use the same condition for whether to emit DWARF information for both instructions may be a separate bug in LLVM.

Relevant issue: llvm/llvm-project#188234

AI assistance was used to determine the root cause of this crash from the observed symptoms, and to write the tests. Also thanks to @samitolvanen and @maurer for debugging this issue.

Similar to this previous PR of mine: rust-lang#130824
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request May 27, 2026
…nethercote

Add uwtable annotation to modules when required

When unwind tables are enabled with `-Cforce-unwind-tables=y`, Rust will annotate all functions with the `uwtable` annotation. However, this annotation is missing on modules, which leads to incorrect unwind tables being generated by LLVM for constructors (such as `asan.module_ctor`).

This was discovered because it leads to a crash in Linux when KASAN and dynamic shadow call stack are both enabled. In this scenario, the kernel uses the unwind tables to locate the `paciasp` and `autiasp` instructions in each function and patches the machine code at boot to use the shadow call stack instructions instead. However, LLVM's AArch64PointerAuth pass emits DWARF info for `paciasp` whenever `-g` is passed, but only emits DWARF info for `autiasp` when the `uwtable` attribute is present. Since the `uwtable` annotation is missing for modules, the relevant directives are generated for only the `autiasp` instruction in `asan.module_ctor`, and not for the `paciasp` instruction. This causes the kernel's dynamic SCS logic to patch the prolouge of `asan.module_ctor`, but not the epilogue. This leads to a crash as the shadow call stack becomes unbalanced.

The fact that LLVM doesn't use the same condition for whether to emit DWARF information for both instructions may be a separate bug in LLVM.

Relevant issue: llvm/llvm-project#188234

AI assistance was used to determine the root cause of this crash from the observed symptoms, and to write the tests. Also thanks to @samitolvanen and @maurer for debugging this issue.

Similar to this previous PR of mine: rust-lang#130824
pull Bot pushed a commit to xtqqczze/rust-lang-miri that referenced this pull request May 28, 2026
Add uwtable annotation to modules when required

When unwind tables are enabled with `-Cforce-unwind-tables=y`, Rust will annotate all functions with the `uwtable` annotation. However, this annotation is missing on modules, which leads to incorrect unwind tables being generated by LLVM for constructors (such as `asan.module_ctor`).

This was discovered because it leads to a crash in Linux when KASAN and dynamic shadow call stack are both enabled. In this scenario, the kernel uses the unwind tables to locate the `paciasp` and `autiasp` instructions in each function and patches the machine code at boot to use the shadow call stack instructions instead. However, LLVM's AArch64PointerAuth pass emits DWARF info for `paciasp` whenever `-g` is passed, but only emits DWARF info for `autiasp` when the `uwtable` attribute is present. Since the `uwtable` annotation is missing for modules, the relevant directives are generated for only the `autiasp` instruction in `asan.module_ctor`, and not for the `paciasp` instruction. This causes the kernel's dynamic SCS logic to patch the prolouge of `asan.module_ctor`, but not the epilogue. This leads to a crash as the shadow call stack becomes unbalanced.

The fact that LLVM doesn't use the same condition for whether to emit DWARF information for both instructions may be a separate bug in LLVM.

Relevant issue: llvm/llvm-project#188234

AI assistance was used to determine the root cause of this crash from the observed symptoms, and to write the tests. Also thanks to @samitolvanen and @maurer for debugging this issue.

Similar to this previous PR of mine: rust-lang/rust#130824
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-rust-for-linux Relevant for the Rust-for-Linux project S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants