darfink / region-rs Goto Github PK
View Code? Open in Web Editor NEWA cross-platform virtual memory API written in Rust
Home Page: https://darfink.github.io/region-rs/
License: MIT License
A cross-platform virtual memory API written in Rust
Home Page: https://darfink.github.io/region-rs/
License: MIT License
I'm seeing this failure on armv7hl, aarch64, ppc64le and s390x.
failures:
---- src/protect.rs - protect::protect (line 18) stdout ----
thread 'src/protect.rs - protect::protect (line 18)' panicked at 'test executable failed:
', src/librustdoc/test.rs:332:17
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
failures:
src/protect.rs - protect::protect (line 18)
test result: FAILED. 6 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out
For example, on Linux I see:
% cat /proc/self/maps
5560a8b9d000-5560a8b9f000 r--p 00000000 fd:01 5637877 /usr/bin/cat
5560a8b9f000-5560a8ba4000 r-xp 00002000 fd:01 5637877 /usr/bin/cat
5560a8ba4000-5560a8ba7000 r--p 00007000 fd:01 5637877 /usr/bin/cat
5560a8ba7000-5560a8ba8000 r--p 00009000 fd:01 5637877 /usr/bin/cat
5560a8ba8000-5560a8ba9000 rw-p 0000a000 fd:01 5637877 /usr/bin/cat
5560aa060000-5560aa081000 rw-p 00000000 00:00 0 [heap]
7f650ca00000-7f650cce9000 r--p 00000000 fd:01 5640853 /usr/lib/locale/locale-archive
7f650cd10000-7f650cd35000 rw-p 00000000 00:00 0
7f650cd35000-7f650cd5b000 r--p 00000000 fd:01 5661641 /usr/lib/x86_64-linux-gnu/libc.so.6
7f650cd5b000-7f650ceb0000 r-xp 00026000 fd:01 5661641 /usr/lib/x86_64-linux-gnu/libc.so.6
7f650ceb0000-7f650cf03000 r--p 0017b000 fd:01 5661641 /usr/lib/x86_64-linux-gnu/libc.so.6
7f650cf03000-7f650cf07000 r--p 001ce000 fd:01 5661641 /usr/lib/x86_64-linux-gnu/libc.so.6
7f650cf07000-7f650cf09000 rw-p 001d2000 fd:01 5661641 /usr/lib/x86_64-linux-gnu/libc.so.6
7f650cf09000-7f650cf16000 rw-p 00000000 00:00 0
7f650cf33000-7f650cf35000 rw-p 00000000 00:00 0
7f650cf35000-7f650cf36000 r--p 00000000 fd:01 5661637 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7f650cf36000-7f650cf5b000 r-xp 00001000 fd:01 5661637 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7f650cf5b000-7f650cf65000 r--p 00026000 fd:01 5661637 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7f650cf65000-7f650cf67000 r--p 00030000 fd:01 5661637 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7f650cf67000-7f650cf69000 rw-p 00032000 fd:01 5661637 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7ffd0d8aa000-7ffd0d8cb000 rw-p 00000000 00:00 0 [stack]
7ffd0d9bf000-7ffd0d9c3000 r--p 00000000 00:00 0 [vvar]
7ffd0d9c3000-7ffd0d9c5000 r-xp 00000000 00:00 0 [vdso]
Would be nice if the information right-most column ('/usr/bin/cat', '[heap]', or '[stack]') would be preserved and made available.
While attempting to build wasmtime on OpenBSD 6.6 cargo build --release
fails with the following error:
error[E0425]: cannot find function `get_region` in module `os`
--> /home/j/.cargo/registry/src/github.com-1ecc6299db9ec823/region-2.1.2/src/lib.rs:133:7
|
133 | os::get_region(page::floor(address as usize) as *const u8)
| ^^^^^^^^^^ not found in `os`
I need to protect the content of one segment in memory with its protection flags. So far I managed in this way
unsafe {
region::protect(
ph.p_vaddr as *const u8,
ph.p_memsz.try_into().unwrap(),
flags_to_prot(ph.p_flags),
)
.unwrap();
}
...
fn flags_to_prot(mut flags: u32) -> region::Protection {
let mut prot = region::Protection::NONE;
[4, 2, 1].iter().for_each(|e| {
if flags >= *e {
match e {
4 => prot |= Protection::READ,
2 => prot |= Protection::WRITE,
1 => prot |= Protection::EXECUTE,
_ => prot |= Protection::NONE,
}
flags -= e;
}
});
prot
}
I was wondering why the library doesn't provide any method to turn u32 value into a region::Protection value
Since version 5.10 Linux defines a couple of AArch64-specific access flags - PROT_BTI
for pages guarded by the Branch Target Identification technology and PROT_MTE
for pages to which the Memory Tagging Extension applies. Currently (as of commit 5087445) there is no way to use these attributes with the Protection
struct even via the Protection::from_bits_unchecked()
method because the implementation ignores any unknown values right before the call to mprotect()
, for example.
Given that it's just a mem::forget under the hood, which is otherwise safe to call, and that AFAIK the typical operating system won't even mind if you don't unlock the memory and just do it for you at memory deallocation time, I do not get it.
When I compile vendor v3.0.0 as a dependency of another package, using rustc+cargo 1.63.0, I get this (and have to patch it manually). This is on NetBSD if it matters.
Compiling region v3.0.0
error[E0412]: cannot find type `QueryIter` in module `os`
--> /usr/work/security/rbw/work/vendor/region-3.0.0/src/query.rs:7:24
|
7 | iterator: Option<os::QueryIter>,
| ^^^^^^^^^ not found in `os`
|
help: consider importing this struct
|
1 | use crate::QueryIter;
|
help: if you import `QueryIter`, refer to it directly
|
7 - iterator: Option<os::QueryIter>,
7 + iterator: Option<QueryIter>,
|
error[E0433]: failed to resolve: could not find `QueryIter` in `os`
--> /usr/work/security/rbw/work/vendor/region-3.0.0/src/query.rs:15:9
|
15 | os::QueryIter::new(origin, size).map(|iterator| Self {
| ^^^^^^^^^ not found in `os`
|
help: consider importing this struct
|
1 | use crate::QueryIter;
|
help: if you import `QueryIter`, refer to it directly
|
15 - os::QueryIter::new(origin, size).map(|iterator| Self {
15 + QueryIter::new(origin, size).map(|iterator| Self {
|
Some errors have detailed explanations: E0412, E0433.
For more information about an error, try `rustc --explain E0412`.
error: could not compile `region` due to 2 previous errors
warning: build failed, waiting for other jobs to finish...
*** Error code 101
Stop.
make[1]: stopped in /usr/pkgsrc/security/rbw
First of all: Nice crate and API!
I am trying to use your region
crate in order to efficiently model virtual memory for my virtual machine: https://github.com/Robbepop/runwell
The crate's docs are telling about issues with multiple threads but gave no suggestion in how to operate in that environment properly: https://docs.rs/region/3.0.0/region/#parallelism
For my project I have this thin-wrapper for region::Allocation
:
https://github.com/Robbepop/runwell/blob/master/crates/vmem/src/lib.rs
... and some unit tests on top:
https://github.com/Robbepop/runwell/blob/master/crates/vmem/src/tests.rs
Using cargo test --package runwell_vmem
results in 3 different scenarios:
process didn't exit successfully: `/home/user/projects/runwell/target/debug/deps/runwell_vmem-de3149ae5e1f53dc` (signal: 11, SIGSEGV: invalid memory reference)
thread '<unnamed>' panicked at 'failed to set up alternative stack guard page: Cannot allocate memory (os error 12)', library/std/src/sys/unix/stack_overflow.rs:160:13
0: rust_begin_unwind
at /rustc/bd41e09da334697c0f993b36685cb599061d9faa/library/std/src/panicking.rs:517:5
1: std::panicking::begin_panic_fmt
at /rustc/bd41e09da334697c0f993b36685cb599061d9faa/library/std/src/panicking.rs:460:5
2: std::sys::unix::stack_overflow::imp::get_stackp
at /rustc/bd41e09da334697c0f993b36685cb599061d9faa/library/std/src/sys/unix/stack_overflow.rs:160:13
3: std::sys::unix::stack_overflow::imp::get_stack
at /rustc/bd41e09da334697c0f993b36685cb599061d9faa/library/std/src/sys/unix/stack_overflow.rs:166:32
4: std::sys::unix::stack_overflow::imp::make_handler
at /rustc/bd41e09da334697c0f993b36685cb599061d9faa/library/std/src/sys/unix/stack_overflow.rs:177:21
5: std::sys::unix::stack_overflow::Handler::new
at /rustc/bd41e09da334697c0f993b36685cb599061d9faa/library/std/src/sys/unix/stack_overflow.rs:14:9
6: std::sys::unix::thread::Thread::new::thread_start
at /rustc/bd41e09da334697c0f993b36685cb599061d9faa/library/std/src/sys/unix/thread.rs:104:32
7: start_thread
8: __GI___clone
process didn't exit successfully: `/home/user/projects/runwell/target/debug/deps/runwell_vmem-de3149ae5e1f53dc` (signal: 6, SIGABRT: process abort signal)
Using cargo test --package runwell_vmem -- --test-threads 1
solves the problem. So it is pretty clear that the concurrently running test threads are kinda having conflicts with each other.
From the Rust point of view those tests do not have shared data and yet they compromise each other. I am sure I have some misconception or misunderstanding about the underlying APIs.
I was trying to remove as many of the unit tests to see which minimum subset still triggers the above bugs:
At minimum the grow_to_capacity_works
, grow_works
, read_write_works
unit tests need to be run.
Please help to resolve my misconceptions about this crate and its invariants and ideally help me on track so that I can actually use this nice API of yours. :)
region 3.0.1 is now locking libc
to a specific (and pretty old) version. This broke my build because I have other dependencies (e.g. the sysinfo
crate) that require a newer libc.
First, this is a breaking change and should not have been introduced as a hotfix version.
Besides that, I was wondering if this locking is really necessary. It prevents me from going to region 3.0.1
and I'm stuck on region 3.0.0
because of my other dependencies. I don't need OpenBSD. Can it maybe be locked on OpenBSD only but not on other platforms?
Currently guarded regions on Windows are represented as a Region
, where protection
is equal to the guarded region's underlying protection, and guarded
set to true
.
This might be confusing, since library users may only check for protection & Protection::READ
or is_readable()
, and thereafter assume the memory region is accessible.
Is it more ergonomic to discard the underlying protection of guarded pages, and merely set protection
to Protection::NONE
whilst also retaining the guarded
boolean flag?
This would mean that information is lost, but would most likely result in fewer surprises for the user.
---- tests::query_code stdout ----
thread 'tests::query_code' panicked at 'assertion failed: `(left == right)`
left: `Read`,
right: `Read | Execute | ReadExecute`', src/lib.rs:211:7
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
Let me know what other information you need.
Thanks!
I was reviewing the changes between versions 2 and 3 and noticed that the unlock
function was changed from unsafe
to safe:
Since it operates on a raw pointer, and potentially unlocks memory that it doesn't own (in the Rust ownership sense), should it still be unsafe
?
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.