Skip to content

Segmentation fault due to a wrongly mapped page after NRE by bootstraping the runtime with rust under linux #115438

Open
@Wartori54

Description

@Wartori54

Description

On GNU/Linux, when using a simple rust script to launch a .NET application by loading the hostfxr library from a .NET 8/9 stock runtime a segmentation fault occurs shortly after the managed application tries to access a null object. It fails in ExecuteHandlerOnCustomStack, after the sigsegv_handler successfully gets called, while trying to read from a mapped page with no read, write or execute permissions set.
Strangely enough this behaviour does not appear when using a C++ script instead, doing the exact same loading process of course.

Reproduction Steps

The following zip file contains the reproduction setup for this issue (nativehostingtest.zip):

  • Download a .NET runtime from the official sources, .NET 8.0.15 runtime for x64 for Linux was used for testing (I have reproduced this issue with the .NET 9.0.4 runtime as well).
  • Extract it in the runtime directory, make sure the contents are directly there, the dotnet executable from the runtime should end up in nativehostingtest/runtime/dotnet for reference.
  • Go in the dotnet_app directory and build the C# project in debug mode, this in necessary since the paths for the files are hard-coded for reliability reasons.
  • Go in the rusthost directory and build the source with cargo build, run the binary in target/debug/rusthost.
  • Go in the cpphost directory, and build the source with {g++/clang++} -o nativehost nativehost.cpp, and run the binary.

Expected behavior

Both scripts (C++ and rust) nicely exit after a NRE happens in managed code, with an stacktrace and an Aborted exit code.

Actual behavior

Under rust, the managed app will print to console, and exit with a Segmentation Fault shortly after.

Under C++, the managed binary does print to console and it nicely exits with an stack trace and an Aborted exit code.

Regression?

This also does not seem to occur at all under .NET 7.0.20 or earlier.

Known Workarounds

None.

As pointed in here the following, combined with the removal of rust's sig_handler, is enough to fix the issue:

let mut altstack: stack_t = mem::zeroed();
altstack.ss_flags = SS_DISABLE;
sigaltstack(&altstack, ptr::null_mut());

Configuration

Tested with .NET runtime 8.0.15 and 9.0.4, under GNU/Linux from EndeavourOS.
x64 processor (i5-1235U), kernel: 6.14.4-arch1-2 x86_64.

This issue seemed to not occur in a Debian-based system and another EndeavourOS system. Further details from those systems are unfortunately unknown to me currently.

Other information

Rust does register a SIGSEGV handler in its runtime, the provided sample does remove such handler to make sure it is not interfering, keeping it does not alter the issue's behaviour.

Here's a core dump of the crash too: coredump.tar.gz.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions