All Projects → Technolution → Rustig

Technolution / Rustig

Licence: other
A tool to detect code paths leading to Rust's panic handler

Programming Languages

rust
11053 projects

Projects that are alternatives of or similar to Rustig

Automated-Malware-Analysis-List
My personal Automated Malware Analysis Sandboxes and Services
Stars: ✭ 20 (-86.21%)
Mutual labels:  analysis, elf
Elfparser
Cross Platform ELF analysis
Stars: ✭ 228 (+57.24%)
Mutual labels:  analysis, elf
Tybalt
Training and evaluating a variational autoencoder for pan-cancer gene expression data
Stars: ✭ 126 (-13.1%)
Mutual labels:  analysis
Idaobjctypes
A collection of types & functions definitions useful for Objective-C binaries analysis.
Stars: ✭ 138 (-4.83%)
Mutual labels:  analysis
Spacextract
Extraction and analysis of telemetry from rocket launch webcasts (from SpaceX and RocketLab)
Stars: ✭ 131 (-9.66%)
Mutual labels:  analysis
Django Slick Reporting
Powerful and Efficient reporting engine with Charting capabilities
Stars: ✭ 123 (-15.17%)
Mutual labels:  analysis
Jhtalib
Technical Analysis Library Time-Series
Stars: ✭ 131 (-9.66%)
Mutual labels:  analysis
Lucenenet
Apache Lucene.NET
Stars: ✭ 1,704 (+1075.17%)
Mutual labels:  analysis
Go Ethereum Code Analysis
No description or website provided.
Stars: ✭ 2,032 (+1301.38%)
Mutual labels:  analysis
Opentrack
Head tracking software for MS Windows, Linux, and Apple OSX
Stars: ✭ 1,950 (+1244.83%)
Mutual labels:  linux-app
Openimu
Open Source Analytics & Visualisation Software for Inertial Measurement Units
Stars: ✭ 133 (-8.28%)
Mutual labels:  analysis
Easynmon
jmeter和Loadrunner性能测试过程,通过接口启动/关闭服务器资源监控任务(nmon),并生成html图表!
Stars: ✭ 130 (-10.34%)
Mutual labels:  analysis
Pwninit
pwninit - automate starting binary exploit challenges
Stars: ✭ 127 (-12.41%)
Mutual labels:  elf
Steamtools
🛠「Steam++」是一个开源跨平台的多功能Steam工具箱。
Stars: ✭ 4,458 (+2974.48%)
Mutual labels:  linux-app
Pref
Portable Reverse Engineering Framework
Stars: ✭ 127 (-12.41%)
Mutual labels:  analysis
Elfhooker
兼容Android 32位和64位。基于EFL文件格式Hook的demo,hook了SurfaceFlinger进程的eglSwapBuffers函数,替换为new_eglSwapBuffers
Stars: ✭ 138 (-4.83%)
Mutual labels:  elf
Mwdb Core
Malware repository component for samples & static configuration with REST API interface.
Stars: ✭ 125 (-13.79%)
Mutual labels:  analysis
Reddit Detective
Play detective on Reddit: Discover political disinformation campaigns, secret influencers and more
Stars: ✭ 129 (-11.03%)
Mutual labels:  analysis
Scikit Hep
Metapackage of Scikit-HEP project data analysis packages for Particle Physics.
Stars: ✭ 131 (-9.66%)
Mutual labels:  analysis
Exodus
Painless relocation of Linux binaries–and all of their dependencies–without containers.
Stars: ✭ 2,560 (+1665.52%)
Mutual labels:  elf

Rustig!

This software can be used to check whether your Rust software has any paths leading to the panic handler.

This tool is intended to be used by developers during coding and on CI systems to continuously check for possible panic's.

Code Status

Build Status

The name

The name rustig! comes from the Dutch word rustig. Which translates to 'calm down' or equivalent in English. See it as the opposite of 'panic'. Don't panic!.

Background

Software written in Rust has a panic handler. When the panic handler is called the current thread will be terminated (or the process will be exited, determined by rustc's build flag 'panic'). Certain conditions in Rust software trigger this panic handler. Accessing an array out of bounds is an example of such a trigger.

This tool will analyze the ELF executable, generate a callgraph from the debug info in the executable, and report the paths leading from your code to the panic handler.

History

The idea for this tool was born while we were on some code for Cortex-M processors. Using objdump and grep you can easily prove that there is no panic! in the code, because the optimizer has removed those functions from the resulting binary. For non #[no_std] targets the optimizer cannot remove them because the binary is statically linked to the Rust standard library which contains those functions. We wanted this tool to be able to prove the abscence of paths to panic! in Rust binaries that contain the standard library. See the Results section to see why this turned out to be not so easy.

Who

This tool was written by four students from Delft University doing their Bachelor End Project at Technolution in the Netherlands. The initial idea was provided by Erwin Gribnau who mentored this project on behalf of Technolution. On behalf of Delft University, this project was mentored by Robbert Krebbers.

Their thesis about this project can be found in the repo at Delft University: link.

Installing the latest version from source

You can use cargo to install our binary directly from the sources in the Git-repository:

cargo install --git https://github.com/Technolution/rustig rustig

Using the tool

The tool accepts various command line flags and options:

Options

  • --binary (-b): The path of the binary to analyze, relative to the present working directory. This should be an executable in ELF format. The executable should be compiled for x86 or x86_64 architectures, with debug information enabled.

  • --config: Path to a configuration file, relative to the present working directory. Defaults to 'rustig.toml'. If the default file does not exist, no configuration file is used. However, if this argument is passed explicitly, but the file does not exist, the tool will exit with an error. Currently, this file is only used for whitelisting, which is explained in the section on whitelisting.

  • --crates (-c): Option to mark crates as analysis target (more on analysis target in the how it works section). By default, the crate in which the main function is defined is used as analysis target.

  • --callgraph (-g): Option to dump the callgraph in dot format. It takes one or more of 2 values:

    • full: Writes the full call graph, without metadata, to 'rdp-callgraph-{projectname}-full.dot'
    • filtered: Writes the call graph containing only the nodes that lead to a panic, with metadata, to 'rdp-callgraph-{projectname}-filtered.dot'

Flags

  • --full-crate-analysis (-f): Analyses all functions in the analysis target, instead of only the main function. (More about this flag in the in the section on whitelisting).
  • --silent (-s): Print no output to stdout.
  • --verbose (-v): Print detailed panic traces to stdout.

Exit codes

  • 0: No errors during execution, and no panic traces found.
  • 1: No errors during execution, but panic traces were found.
  • 101: Internal error during execution.

How it works

Internally, the tool builds a call graph from the binary. (This call graph can be dumped with the --callgraph flag). After that the tool wil print all calls from a function in the same crate as the main function (or the crates given by the --crates flag) to a function outside this crate that might lead to a panic!.

Whitelisting

It is possible to whitelist functions. When a function is whitelisted, traces that would contain that function are ignored.

Whitelisting can be done in the configuration file. An example, to whitelist formatting, could be:

whitelisted_functions = [
  {
    function_name = "fmt::format",
    crate_name = "stdlib",
    crate_version="1.26.2",
    strict = true
  }
]

The whitelisted functions are defined in an array with key whitelisted_functions. The objects in the array contain the following fields:

  • function_name (required): The name of the function to whitelist. This name may be prepended with an arbitrary number of namespaces. However, partial namespaces are not accepted. For example, if a function has name core::fmt::format, the names format, fmt::format and core::fmt::format would match, but ormat or mt::format would not.
  • crate_name: (required) The name of the crate the function is defined in. When executing the tool, this is usually printed between brackets in the output.
  • crate_version: (optional) The version of the crate the function is defined in. If another version of the crate is detected, the function will not be whitelisted.
  • strict: (optional) If true, crates for which the name matches, but the version could not be determined, are not matched. If false, the crate will be matched. The default is false.

Full crate analysis

Normally, when function foo is whitelisted, only traces through functions that are called via foo only will be ignored. This behaviour can be disabled by setting the --full-crate-analysis flag.

For example, for the following function trace: crate::main -> crate::whitelisted_function -> crate::foo -> std::panic::panic no trace would be reported by default. When the --full-crate-analysis flag is set, a trace (crate::foo -> std::panic::panic) would be reported.

Limitations

For dynamic invocations this tool makes assumptions. The assumption made is that when the address of a trait implementation is loaded using the Load Effective Address call, all functions in that trait are considered used. All paths leading to panic! from one of those functions (whether actually used or not) will be reported.

Currently, the tool is only able to build callgraphs for x86_64 ELF binaries. The reason for this limitation is that building the callgraph requires reading the assembly and finding jump/call instructions (like callq and lea). This algorithm is currently only implemented for x86 instruction sets.

Results

As a test case for this tool some well-known crates from the Rust community were used. The results are shown below:

Crate Lines of Code Number of panic paths
Servo 219806 50881
cargo 25892 9439
cargo-make 8243 1195
cargo-edit 671 237

The output of the tool in your terminal is overwhelming considering the numbers of paths shown. To reduce the output the whitelisting option is used. Using whitelisting you can drill down on the results showing only the paths you care about.

Again, for some well-known crates this is performed, the results are shown below:

In this table, the column Total denotes all the panic traces in the program. In the column Project specific, we whitelisted some functions that were explicitly meant to panic if something went wrong in the setup or teardown phase. In the subsequent columns Format, Allocation and Indexing, we disabled traces for string formatting, memory allocation and array indexing respectively. We whitelisted these because, based on our experience, they are very unlikely to panic . These whitelists are added on top of the project-specific whitelists. In the All column, we combined all of these whitelisting configurations. The traces in this output did not have a cause that was easiy to identify, and would require more investigation. In the last two columns, we identified how many of the traces in the All column were caused by an unwrap or by use of the panic macro itself.

Crate Total Project specific Format Allocation Indexing All Unwrap Direct
cargo 9439 7782 4833 5514 6758 2238 738 49
cargo-make 1195 1136 695 697 1030 148 71 8
cargo-add 388 283 201 209 236 95 17 4
cargo-rm 126 108 64 91 97 37 5 0
cargo-upgrade 415 298 204 231 267 112 16 2

Based on these results, we tried to estimate the impact of this output. It turned out that many panics were difficult to trigger, since they are very environment-specific. However, in the cargo-make project, we were able to trigger two panics after trying for just half an hour. One panic occures when you remove the read permissions for the current user on input files for cargo-make. The other panic occures when such an input file is not formatted correctly. This demonstrates it is possible to find bugs with the tool; however, it certainly requires some effort. We would like to point out, that this particalur bug is not a serious problem for a command-line program. But, when bugs like these can be triggered on applications connected to the Internet, you can execute a denial-of-service attack against such an application.

License

MIT or APACHE-2.0 (see the LICENSE files in the repository).

Developer notes

To test this tool a series of binaries is generated (in test_subjects and test_subjects_stable_rustc). The binaries in the latter directory are generated using a specific version of the Rust compiler. See build.rs in test_common for details.

Warning for RLS users

If you use the Rust Language Server (i.e. Visual Studio Code with Rust plugin), the generated binary is overwritten by a version compiled with the default compiler settings. This will cause some tests to fail!

The tests that are known to fail in that case are: parse::test::test_example_binary_debug_abbrev and callgraph::test::test_call_graph_creation.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].