An ergonomic and safe syscall interception framework for Linux.
Find a file
David Tolnay ce519e0af4 Update to version 1.4.38-nightly from nightly-2022-03-28
Summary:
The changes from the old "rustfmt 2.x" branch, which we upgraded to in D23569308, have since been merged into the master branch of rustfmt under the flag `version = "Two"`. Fixes like needed for https://fb.workplace.com/groups/learningrust/posts/545143730235002 now only land to master; there is no separate 2.x branch in development. This diff pulls in the newest version of rustfmt so that we can handle any new syntax and pick up fixes to rustfmt issues that we report or contribute.

The tools/third-party/rustfmt changes in this diff are generated by:

```
$ echo nightly-2022-03-28 > tools/third-party/rustfmt/.rustfmt-version
$ tools/third-party/rustfmt/rustfmt-upgrade
```

Reviewed By: zertosh

Differential Revision: D35234535

fbshipit-source-id: c79454fa918cf052312418dd271404e85bf872b2
2022-03-29 20:18:21 -07:00
.github/workflows Initial commit 2021-12-29 16:14:27 -08:00
assets Initial commit 2021-12-29 16:14:27 -08:00
reverie rust: update libc from 0.2.117 to 0.2.121 2022-03-23 10:00:47 -07:00
reverie-examples Bump nix crate from 0.22 => 0.23 2022-03-22 09:26:52 -07:00
reverie-process Add Command::prepend_args 2022-03-29 18:41:29 -07:00
reverie-ptrace rust: update libc from 0.2.117 to 0.2.121 2022-03-23 10:00:47 -07:00
reverie-syscalls rust: update libc from 0.2.117 to 0.2.121 2022-03-23 10:00:47 -07:00
reverie-util rust: update libc from 0.2.117 to 0.2.121 2022-03-23 10:00:47 -07:00
tests Prepare for rustfmt upgrade 7/13 2022-03-29 18:56:43 -07:00
.gitignore Initial commit 2021-12-29 16:14:27 -08:00
Cargo.toml Initial commit 2021-12-29 16:14:27 -08:00
CHANGELOG.md Initial commit 2021-12-29 16:14:27 -08:00
CODE_OF_CONDUCT.md Initial commit 2021-12-29 16:14:27 -08:00
CONTRIBUTING.md Initial commit 2021-12-29 16:14:27 -08:00
LICENSE Initial commit 2021-12-29 16:14:27 -08:00
README.md Center diagram in the README 2022-01-04 18:14:12 -08:00
rust-toolchain.toml Initial commit 2021-12-29 16:14:27 -08:00
rustfmt.toml Update to version 1.4.38-nightly from nightly-2022-03-28 2022-03-29 20:18:21 -07:00

Reverie

Reverie is a user space system-call interception framework for x86-64 Linux. It can be used to intercept, modify, or elide a syscall before the kernel executes it. In essence, Reverie sits at the boundary between user space and kernel space.

Some potential use cases include:

  • Observability tools, like strace.
  • Failure injection to test error handling logic.
  • Manipulating scheduling decisions to expose concurrency bugs.

See the reverie-examples directory for examples of tools that can be built with this library.

Features

  • Ergonomic syscall handling. It is easy to modify syscall arguments or return values, inject multiple syscalls, or suppress the syscall entirely.
  • Async-await usage allows blocking syscalls to be handled without blocking other guest threads.
  • Can intercept CPUID and RDTSC instructions.
  • Typed syscalls. Every syscall has a wrapper to make it easier to access pointer values. This also enables strace-like pretty-printing for free.
  • Avoid intercepting syscalls we don't care about. For example, if we only care about sys_open, we can avoid paying the cost of intercepting other syscalls.
  • Can act as a GDB server. This allows connection via the GDB client where you can step through the process that is being traced by Reverie.

Terminology and Background

Clients of the Reverie library write tools. A tool runs a shell command creating a guest process tree, comprised of multiple guest threads and processes, in an instrumented manner. Each Reverie tool is written as a set of callbacks (i.e. handlers), which are invoked each time a guest thread encounters a trappable event such as a system call or inbound signal. The tool can stipulate exactly which events streams it subscribes to. The tool itself is stateful, maintaining state between consecutive invocations.

Usage

Currently, there is only the reverie-ptrace backend which uses ptrace to intercept syscalls. Copy one of the example tools to a new Rust project (e.g. cargo init). Youll see that it depends both on the general reverie crate for the API and on the specific backend implementation crate, reverie_ptrace.

Performance

Since ptrace adds significant overhead when the guest has a syscall-heavy workload, Reverie will add similarly-significant overhead. The slowdown depends on how many syscalls are being performed and are intercepted by the tool.

The primary way you can improve performance with the current implementation is to implement the subscriptions callback, specifying a minimal set of syscalls that are actually required by your tool.

Overall architecture

When implementing a Reverie tool, there are three main components of the tool to consider:

  • The process-level state,
  • the thread-level state, and
  • the global state (which is shared among all processes and threads in the traced process tree).

This separation of process-, thread-, and global-state is meant to provide an abstraction that allows future Reverie backends to be used without requiring the tool to be rewritten.

Architecture Diagram

Process State

Whenever a new process is spawned (i.e., when fork or clone is called by the guest), a new instance of the process state struct is created and managed by the Reverie backend.

Thread State

When a syscall is intercepted, it is always associated with the thread that called it.

Global State

The global state is accessed via RPC messages. Since a future Reverie backend may use in-guest syscall interception, the syscall handler code may not be running in the same address space. Thus, all shared state is communicated via RPC messages. (There is, however, currently only a single ptrace-based backend where all tracer code is in the same address space.)

Future Plans

  • Add a more performant backend. The rough goal is to have handlers executing in the guest with close to regular functional call overhead. Global state and its methods will still be centralized, but the RPC/IPC mechanism between guest & the centralized tool process will become much more efficient.

Contributing

Contributions are welcome! Please see the CONTRIBUTING.md file for guidance.

License

Reverie is BSD 2-Clause licensed as found in the LICENSE file.