facebookexperimental / reverie Goto Github PK
View Code? Open in Web Editor NEWAn ergonomic and safe syscall interception framework for Linux.
License: Other
An ergonomic and safe syscall interception framework for Linux.
License: Other
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.
There are many examples of identical code, but one simple one in hex.rs:
reverie/reverie-ptrace/src/gdbstub/hex.rs
Lines 265 to 288 in 15d2f61
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:
reverie/reverie-ptrace/src/gdbstub/packet.rs
Lines 54 to 72 in 15d2f61
vs. my implementation at
https://github.com/daniel5151/gdbstub/blob/0.4.5/src/protocol/packet.rs#L38-L56
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
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:
Line 9 in dba0b5b
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.
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
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:
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 toMy 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!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.