GithubHelp home page GithubHelp logo

facebookexperimental / reverie Goto Github PK

View Code? Open in Web Editor NEW
523.0 523.0 25.0 1.04 MB

An ergonomic and safe syscall interception framework for Linux.

License: Other

Rust 95.05% Shell 0.10% C 4.60% Assembly 0.15% Python 0.10%

reverie's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

reverie's Issues

Missing license attribution for `gdbstub` derived code

Hey there,

It looks like reverie is using a fork of my gdbstub library without including the appropriate MIT license attribution (as per the license terms here). Based on a quick glance through the code, the forks to be pretty old, but there's nonetheless still some substantial chunks of my original implementation in there...

The relevant code in reverie lives under the following project subdirectory.

https://github.com/facebookexperimental/reverie/tree/15d2f6141137177e8fd292936dd01f63f3535a7f/reverie-ptrace/src/gdbstub


There are many examples of identical code, but one simple one in hex.rs:

/// Decode a GDB dex string into the specified integer.
///
/// GDB hex strings may include "xx", which represent "missing" data. This
/// method simply treats "xx" as 00.
pub fn decode_hex<I>(buf: &[u8]) -> Result<I, GdbHexError>
where
I: FromPrimitive + Zero + CheckedAdd + CheckedMul,
{
if buf.is_empty() {
return Err(GdbHexError::Empty);
}
let radix = I::from_u8(16).ok_or(GdbHexError::InvalidOutput)?;
let mut result = I::zero();
for &digit in buf {
let x = I::from_u8(from_hex(digit).ok_or(GdbHexError::NotAscii)?)
.ok_or(GdbHexError::InvalidOutput)?;
result = result.checked_mul(&radix).ok_or(GdbHexError::Overflow)?;
result = result.checked_add(&x).ok_or(GdbHexError::Overflow)?
}
Ok(result)
}

vs. my implementation at

https://github.com/daniel5151/gdbstub/blob/dev/0.6/src/protocol/common/hex.rs#L11-L36


A more GDB RSP specific one is here:

let end_of_body = bytes
.iter()
.position(|b| *b == b'#')
.ok_or(PacketParseError::MissingChecksum)?;
// Split buffer into body and checksum, note the packet
// starts with a `$'.
let (body, checksum) = bytes.split_at_mut(end_of_body);
let checksum = &checksum[1..][..2]; // skip the '#'
// Validate checksum without leading `$'.
let checksum = decode_hex(checksum).map_err(|_| PacketParseError::MalformedChecksum)?;
let calculated = body.iter().skip(1).fold(0u8, |a, x| a.wrapping_add(*x));
if calculated != checksum {
return Err(PacketParseError::ChecksumMismatched {
checksum,
calculated,
});
}

vs. my implementation at

https://github.com/daniel5151/gdbstub/blob/0.4.5/src/protocol/packet.rs#L38-L56

Panic when tracee calls execve outside of main thread

I hope you don't mind me breaking your program :)

I found that if the tracee calls execve within a thread reverie-ptrace panics.

According to the clone man page (man 2 clone)

          If  any  of the threads in a thread group performs an execve(2),
          then all threads other than the thread group leader  are  termi‐
          nated,  and  the  new  program  is  executed in the thread group
          leader.

The panic happens due to this

[...]
parent tid -1 created child tid 110665, pid 110665, main thread true
parent tid 110665 created child tid 110667, pid 110665, main thread false
[...]
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: InvalidState(Wait(Stopped(Stopped(Pid(110665)), Exec(Pid(110667)))))', ../reverie-ptrace/src/trace/mod.rs:347:54
[...]

From my limited understanding the proper way to handle this situation is discarding all threads of this process and resuming the main thread of the process as the only (new) process. I'm not quite sure if that's even possible in your current architecture.

Also, I realize this is an edge case, you might happily ignore it after all.

For reference, my tracee

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
 
void *myThreadFun(void *vargp)
{
    sleep(0.5);
    char* argument_list[] = {"/bin/sh", NULL};
    execvp(*argument_list, argument_list);
    return NULL;
}
  
int main()
{
    pthread_t thread_id;
    pthread_create(&thread_id, NULL, myThreadFun, NULL);
    while(1) {};
    exit(0);
}

Compile with -lpthread

Please don't include_str! files from another crate in the same workspace

I'm trying to package Hermit for Nixpkgs, but unfortunately I've run into this error while building reverie: rust-lang/cargo#7744

In short, this line:

#![doc = include_str!("../../README.md")]

Is problematic, because Nix vendors each package in the workspace and isolates it from each other. So the build fails because include_str fails because ../../README.md can't be read. I believe this is the only instance of this problem, so fixing this should get things moving

I think an easy mid-way solution would just be to write a docstring for reverie/lib.rs with a small blurb pointing to this repo for more information rather than using include_str directly.

Unsupported processor

I'm attempting to run the noop example, and get this error:

thread 'main' panicked at /home/user/.cargo/git/checkouts/reverie-9a587e40a0d7d3be/8298a77/reverie-ptrace/src/timer.rs:79:16:
Unsupported processor with feature info: FeatureInfo { extended_family_id: 0, extended_model_id: 9, family_id: 6, model_id: 154, stepping_id: 3, brand_index: 0, cflush_cache_line_size: 8, initial_local_apic_id: 8, max_logical_processor_ids: 128, edx_ecx: SSE3 | PCLMULQDQ | DTES64 | MONITOR | DSCPL | VMX | SMX | EIST | TM2 | SSSE3 | FMA | CMPXCHG16B | PDCM | PCID | SSE41 | SSE42 | X2APIC | MOVBE | POPCNT | TSC_DEADLINE | AESNI | XSAVE | OSXSAVE | AVX | F16C | RDRAND | FPU | VME | DE | PSE | TSC | MSR | PAE | MCE | CX8 | APIC | SEP | MTRR | PGE | MCA | CMOV | PAT | PSE36 | CLFSH | DS | ACPI | MMX | FXSR | SSE | SSE2 | SS | HTT | TM | PBE | 0x4800 }
 Full family_model: (6, 154)
stack backtrace:
   0: rust_begin_unwind
             at /rustc/7d3702e472b99be0f5de6608dd87af1df8f99428/library/std/src/panicking.rs:645:5
   1: core::panicking::panic_fmt
             at /rustc/7d3702e472b99be0f5de6608dd87af1df8f99428/library/core/src/panicking.rs:72:14
   2: reverie_ptrace::timer::get_rcb_perf_config
             at /home/user/.cargo/git/checkouts/reverie-9a587e40a0d7d3be/8298a77/reverie-ptrace/src/timer.rs:79:16
   3: reverie_ptrace::timer::TimerImpl::new
             at /home/user/.cargo/git/checkouts/reverie-9a587e40a0d7d3be/8298a77/reverie-ptrace/src/timer.rs:492:30
   4: reverie_ptrace::timer::Timer::new
             at /home/user/.cargo/git/checkouts/reverie-9a587e40a0d7d3be/8298a77/reverie-ptrace/src/timer.rs:170:22
   5: reverie_ptrace::task::TracedTask<L>::new
             at /home/user/.cargo/git/checkouts/reverie-9a587e40a0d7d3be/8298a77/reverie-ptrace/src/task.rs:376:20
   6: reverie_ptrace::tracer::postspawn::{{closure}}
             at /home/user/.cargo/git/checkouts/reverie-9a587e40a0d7d3be/8298a77/reverie-ptrace/src/tracer.rs:329:22
   7: reverie_ptrace::tracer::TracerBuilder<T>::spawn::{{closure}}
             at /home/user/.cargo/git/checkouts/reverie-9a587e40a0d7d3be/8298a77/reverie-ptrace/src/tracer.rs:512:91
   8: intercept::main::{{closure}}
             at /home/user/src/github/foo/intercept/src/main.rs:26:10
   9: tokio::runtime::park::CachedParkThread::block_on::{{closure}}
             at /home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.36.0/src/runtime/park.rs:281:63
  10: tokio::runtime::coop::with_budget
             at /home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.36.0/src/runtime/coop.rs:107:5
  11: tokio::runtime::coop::budget
             at /home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.36.0/src/runtime/coop.rs:73:5
  12: tokio::runtime::park::CachedParkThread::block_on
             at /home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.36.0/src/runtime/park.rs:281:31
  13: tokio::runtime::context::blocking::BlockingRegionGuard::block_on
             at /home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.36.0/src/runtime/context/blocking.rs:66:9
  14: tokio::runtime::scheduler::multi_thread::MultiThread::block_on::{{closure}}
             at /home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.36.0/src/runtime/scheduler/multi_thread/mod.rs:87:13
  15: tokio::runtime::context::runtime::enter_runtime
             at /home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.36.0/src/runtime/context/runtime.rs:65:16
  16: tokio::runtime::scheduler::multi_thread::MultiThread::block_on
             at /home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.36.0/src/runtime/scheduler/multi_thread/mod.rs:86:9
  17: tokio::runtime::runtime::Runtime::block_on
             at /home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.36.0/src/runtime/runtime.rs:350:45
  18: intercept::main
             at /home/user/src/github/foo/intercept/src/main.rs:29:5
  19: core::ops::function::FnOnce::call_once
             at /rustc/7d3702e472b99be0f5de6608dd87af1df8f99428/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Kernel: linux 6.5.13
Processor: 12th Gen Intel(R) Core(TM) i7-12700H

Any thoughts on the cause?

Possibly similar: #13

PTrace AMD support

I tried run this on two Zen AMD machines, it appears the timer code does not work and I couldn't find a way to disable it (i don't need precise timing)

I investigated and found the following:

  • Apparently fn check_for_zen_speclockmap() contains an error for modern rust asm!(). I found it's x-adding a value as reference. I was able to fix this, it correctly returns an error now if the Zen workaround is not applied and returns Ok if the workaround is applied (it appears however, that the lock counter is already increased simply by whatever rust compiles to
  • My devices are not in the magic number lists, I added the numbers which i believe are right, but I don't really know the intrinsics here.

My patch

diff --git a/reverie-ptrace/src/timer.rs b/reverie-ptrace/src/timer.rs
index 09b3ef3..1353f17 100644
--- a/reverie-ptrace/src/timer.rs
+++ b/reverie-ptrace/src/timer.rs
@@ -100,6 +100,8 @@ pub(crate) fn get_rcb_perf_config() -> u64 {
         (0x06, 0x8E) | (0x06, 0x9E) => 0x5101c4,                // Intel Kabylake
         (0x06, 0xA5) | (0x06, 0xA6) => 0x5101c4,                // Intel Cometlake
         (0x06, 141) => 0x5101c4, // Intel Alder Lake (e.g. i7-11800H laptop)
+        (0x1f, 0x8) => 0x5100d1, // AMD Zen, Pinnacle Ridge
+        (0x23, 0x50) => 0x5100d1, // AMD Zen, Cezanne
         oth => panic!(
             "Unsupported processor with feature info: {:?}\n Full family_model: {:?}",
             fi, oth
diff --git a/reverie-ptrace/src/validation.rs b/reverie-ptrace/src/validation.rs
index 17f828a..eceeb0d 100644
--- a/reverie-ptrace/src/validation.rs
+++ b/reverie-ptrace/src/validation.rs
@@ -347,6 +347,7 @@ fn is_amd_zen(cpu_feature: FeatureInfo) -> bool {
         (cpu_type, ext_family_id),
         (
             0x00f10 // Naples, Whitehaven, Summit Ridge, Snowy Owl (Zen), Milan (Zen 3) (UNTESTED)
+            | 0x01780 // Pinnacle Ridge (Zen)
             | 0x10f10 // Raven Ridge, Great Horned Owl (Zen) (UNTESTED)
             | 0x10f80 // Banded Kestrel (Zen), Picasso (Zen+) (UNTESTED)
             | 0x20f00 // Dali (Zen) (UNTESTED)
@@ -358,7 +359,8 @@ fn is_amd_zen(cpu_feature: FeatureInfo) -> bool {
             0x8 | 0xa
         ) | (
             0x20f10 // Vermeer (Zen 3)
-            | 0x50f00, // Cezanne (Zen 3)
+            | 0x50f00 // Cezanne (Zen 3)
+            | 0x51e00, // Cezanne (Zen 3), mobile?
             0xa
         )
     )
@@ -407,12 +409,12 @@ fn check_for_zen_speclockmap() -> Result<(), PmuValidationError> {
     // A lock add is known to increase the perf counter we're looking at.
     #[cfg(not(feature = "llvm_asm"))]
     unsafe {
-        let _prev: usize;
+        let mut _prev: *mut usize;
         core::arch::asm!(
             "lock",
-            "xadd [{}], {}",
+            "add [{}], {}",
+            inout(reg) &to_add => _prev,
             in(reg) val,
-            inout(reg) to_add => _prev,
         )
     }
  

When running cargo test, some tests spuriosly seem to hang, i've observed container::tests::pin_affinity_to_all_cores to hang sometimes, whereas in other runs it would finish ok, but container::tests::return_value would hang always. The hangs got less frequent when i ran them sequentially (-j 1) and in release mode, but I think this is unrelated.

Hope this helps!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.