rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
99.21k stars 12.81k forks source link

[rustc] SIGSEGV maximum backtrace depth reached #133772

Open bf opened 2 days ago

bf commented 2 days ago

Code

Use javascript x=10000; out="compile_error!(" + "concat!(".repeat(x) + '"A"' + ")".repeat(x); + ");" to create rust code.

Full code in evil3.rs.txt

compile_error!(concat!(concat!(concat!(concat!(concat!(concat!(concat!(.....)))))));

Meta

rustc --version --verbose:

<version>
rustc 1.83.0 (90b35a623 2024-11-26) (Arch Linux rust 1:1.83.0-1)
binary: rustc
commit-hash: 90b35a6239c3d8bdabc530a6a0816f7ff89a0aaf
commit-date: 2024-11-26
host: x86_64-unknown-linux-gnu
release: 1.83.0
LLVM version: 18.1.8

Error output

error: rustc interrupted by SIGSEGV, printing backtrace

/usr/lib/librustc_driver-37bf60d83001ffbc.so(+0x1373cb9) [0x79575ff73cb9]
/usr/lib/libc.so.6(+0x3d1d0) [0x79575ea4c1d0]
/usr/lib/librustc_driver-37bf60d83001ffbc.so(+0x45e3d38) [0x7957631e3d38]
/usr/lib/librustc_driver-37bf60d83001ffbc.so(+0x45e522e) [0x7957631e522e]
/usr/lib/librustc_driver-37bf60d83001ffbc.so(_RNvMs_Cs1pTYV0gRL8Y_11rustc_lexerNtNtB4_6cursor6Cursor13advance_token+0xadd) [0x7957631e491d]
/usr/lib/librustc_driver-37bf60d83001ffbc.so(+0x3db789d) [0x7957629b789d]
/usr/lib/librustc_driver-37bf60d83001ffbc.so(+0x3e04e6c) [0x795762a04e6c]

### cycle encountered after 7 frames with period 8
/usr/lib/librustc_driver-37bf60d83001ffbc.so(+0x3e05187) [0x795762a05187]
/usr/lib/librustc_driver-37bf60d83001ffbc.so(+0x3e05187) [0x795762a05187]
/usr/lib/librustc_driver-37bf60d83001ffbc.so(+0x3e05187) [0x795762a05187]
/usr/lib/librustc_driver-37bf60d83001ffbc.so(+0x3e05187) [0x795762a05187]
/usr/lib/librustc_driver-37bf60d83001ffbc.so(+0x3e05187) [0x795762a05187]
/usr/lib/librustc_driver-37bf60d83001ffbc.so(+0x3e05187) [0x795762a05187]
/usr/lib/librustc_driver-37bf60d83001ffbc.so(+0x3e05187) [0x795762a05187]
/usr/lib/librustc_driver-37bf60d83001ffbc.so(+0x3e05187) [0x795762a05187]
### recursed 31 times

/usr/lib/librustc_driver-37bf60d83001ffbc.so(+0x3e05187) [0x795762a05187]

note: rustc unexpectedly overflowed its stack! this is a bug
note: maximum backtrace depth reached, frames may have been lost
note: we would appreciate a report at https://github.com/rust-lang/rust
help: you can increase rustc's stack size by setting RUST_MIN_STACK=16777216
note: backtrace dumped due to SIGSEGV! resuming signal
Segmentation fault (core dumped) 
workingjubilee commented 1 day ago

@bf Did you reach this in a practical use-case, or is this purely synthetic?

bf commented 1 day ago

Purely synthetic.

I've been working with rust for a couple of weeks and found some interesting edge cases concerning security risks arising from rustc, rustfmt, rustdoc and macros. Security team said The threat model of the Rust compiler assumes that the source code of the project and all the dependencies being built is fully trusted and asked me to file a bug report for this specific issue in order to improve rustc robustness.

IMO there are several by-design security risks for developers using rust right now. When you build software with rust, you're unknowingly accepting these security risks. The stance of rust security team elegantly avoids these risks by stating they are out of scope because all code is trusted.

I'm currently trying to document these security risks, so they can be explicitly accepted by developers using rust, and maybe nudge the rust security team towards implementing more security controls and fail-safes so rust follows a more defense-in-depth approach.

I have documented how rust users can be exploited by compiling untrusted code with rustc (expected from many other languages, but could be improved with rust), by generating documentation for untrusted code with rustdoc (unexpected, should not happen imo), and of course by running the compiled untrusted code (expected).

But getting all your data stolen by simply formatting code with rustfmt would be both an unexpected finding and the cherry on top, so please let me know if you think this issue is exploitable ;)

I'll be sharing a write-up soon.

jieyouxu commented 1 day ago

@bf I think there's some confusion regarding what "security" we're talking about here.

I've been working with rust for a couple of weeks and found some interesting edge cases concerning security risks arising from rustc, rustfmt, rustdoc and macros. Security team said The threat model of the Rust compiler assumes that the source code of the project and all the dependencies being built is fully trusted and asked me to file a bug report for this specific issue in order to improve rustc robustness.

I can only speak for rustc, but we assume that all source code that you sent to rustc is fully trusted, i.e. vetted by you. Please do not conflate "security" versus robustness against arbitrary inputs that might crash rustc due to resource exhaustion, typically code that users might write or generate.

For resource exhaustion crashes, we typically prioritize them or triage them according to how likely/feasible is it for a regular user to write similar code "organically". In this provided pure synthetic example, it involves nesting concat! 10000 times and the example was synthetically generated. This is not a pattern that typical users will likely run into. On the other hand, if the compiler crashes from resource exhaustion e.g. from just 1000 macro calls in a row, then we would consider that a higher priority issue and something users are more likely to write "organically".

IMO there are several by-design security risks for developers using rust right now. When you build software with rust, you're unknowingly accepting these security risks. The stance of rust security team elegantly avoids these risks by stating they are out of scope because all code is trusted.

I'm currently trying to document these security risks, so they can be explicitly accepted by developers using rust, and maybe nudge the rust security team towards implementing more security controls and fail-safes so rust follows a more defense-in-depth approach.

I think this is explicitly a non-goal for rustc and we assume "all code is trusted" with regards to the input as you stated. If you wish to discuss security concerns, please file a separate dedicated issue or discuss with @/rust-lang/security.

I have documented how rust users can be exploited by compiling untrusted code with rustc (expected from many other languages, but could be improved with rust), by generating documentation for untrusted code with rustdoc (unexpected, should not happen imo), and of course by running the compiled untrusted code (expected).

If you are compiling untrusted code with rustc, I think you have bigger security problems than rustc possibly crashing, i.e. doing that in the first place.

EDIT: to add, the build might be sandboxed, but that concern is delegated to you.

But getting all your data stolen by simply formatting code with rustfmt would be both an unexpected finding and the cherry on top, so please let me know if you think this issue is exploitable ;)

This is simply not a threat model that we consider, AFAIK.

workingjubilee commented 1 day ago

@bf A stack overflow does not, itself, constitute an exploit, as the term is commonly defined in security research[^0].

If you are familiar with security research involving languages that are compiled to machine code, you must know this? I would hope you would have read the error message and recognized that this hit a signal handler that responds to the quite-intentional page fault caused by hitting the stack protector[^1]. I would hope that if you are familiar enough to be able to confidently make claims about security concerns and exploits, it would not need additional explanation... but perhaps it is missing something in the diagnostic? I am happy to amend it, if so, but it would have to be a small addition, as it already uses a lot of vertical space and I don't think we can fully explain "what is a page fault, anyways?" within that.

Otherwise, I am not sure from where you have derived the idea that, by putting in an amount of code that induces resource exhaustion, you have reached an exploit. As a batch program, rustc is not even expected to be particularly resilient to resource exhaustion, unlike e.g. a web server, where such might be a reasonable expectation? We can make rustc resilient more resilient to inputs, but that might compromise other desirable qualities like speed of compilation, or simply divert work from more important things, like making it easier to write safe code with rustc (so that other programs that rustc compiles are more secure by design). Eventually, all programs will run out of memory if they are given a sufficiently ridiculous task, and the errors are rarely pretty.

All these considerations happen in addition to the detail that jieyouxu already described regarding the trustedness of certain inputs.

[^0]: It is possible that the stack overflow could be argued to be a software flaw or even vulnerability, but an exploit is the usage of that flaw or vulnerability to subvert a system. [^1]: Pages that are deliberately mapped in such a way that access to them, especially write access, will cause a fault, that usually gets translated to SIGSEGV on POSIX systems.

bf commented 1 day ago

If you are familiar with security research involving languages that are compiled to machine code, you must know this?

Unfortunately I'm not good with machine code & exploiting overflows, which is why I asked. Thanks for confirming that the SIGSEGV is not exploitable @workingjubilee.

This is simply not a threat model that we consider, AFAIK.

I understand this, and I think it is an artificial blind spot in rust security posture.

I have gathered my thoughts on rust security at https://github.com/bf/rust-security-problems and will create new reports for the most glaring issues. Then the issues and your decision will be documented.

saethlin commented 1 day ago

cc @rust-lang/security just in case you're interested. I can't tell if OP was trying to address you.

jieyouxu commented 1 day ago

Triage: let's keep this issue focused on the resource exhaustion stack overflow from the code sample itself and open separate issues for the security concerns.

theemathas commented 1 day ago

You might be interested in reading the discussion in https://github.com/rust-lang/rfcs/issues/1515

workingjubilee commented 1 day ago

Then the unfamiliarity is understandable. I am happy to try to answer some questions you may have regarding such.

A stack overflow is a segfault. Almost all such segfaults are very hypothetically exploitable: you have to find a way to bypass the protection. However, as mentioned, you are running headfirst into the exact wall that is designed to prevent things from getting worse, and you are doing the exact thing that would normally cause you to run into that wall. It's rather like intentionally running a command that can reformat your hard drive, and then not even reporting that your hard drive was formatted, but that a window popped up to ask for your password before you destroyed your access to your computer's data. Yes, that little popup was supposed to be there.

To say "I found an exploit" implies something more like "I found a way to run the command that reformats my hard drive without hitting the password check". That would transgress a security boundary. Here, you are starting on the other side of the airtight hatchway, so there are quite a lot of interesting things you can do by running a program that can read and write to the filesystem.