Giter Site home page Giter Site logo

darfink / region-rs Goto Github PK

View Code? Open in Web Editor NEW
109.0 5.0 22.0 3.99 MB

A cross-platform virtual memory API written in Rust

Home Page: https://darfink.github.io/region-rs/

License: MIT License

Rust 100.00%
memory-region virtualprotect mprotect virtualquery mlock

region-rs's People

Contributors

arshia001 avatar darfink avatar devnexen avatar fry avatar ignatenkobrain avatar jclulow avatar sunfishcode avatar valpackett avatar

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

region-rs's Issues

protect::protect fails on non-x86 architectures

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

Please make the name/description of the region available

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.

Feature Request: Add support for OpenBSD

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`

cumbersome when region::protect deals with Elf64_Phdr.p_flags

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

Support for AArch64- and Linux-specific protection attributes

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.

Why is LockGuard::release unsafe?

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.

`QueryIter` not found in `os`

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

Question: How to use this in multi-threaded environment?

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:

  • It works! (80%)
  • Bug 1: Invalid Memory Reference (~15%)
  process didn't exit successfully: `/home/user/projects/runwell/target/debug/deps/runwell_vmem-de3149ae5e1f53dc` (signal: 11, SIGSEGV: invalid memory reference)
  • Bug 2: Cannot Allocate Memory (~5%)
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. :)

Locking libc version makes it incompatible

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?

How to handle PAGE_GUARD on Windows?

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.

query_code test fails on Fedora Rawhide

---- 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!

Why is `unlock` safe?

I was reviewing the changes between versions 2 and 3 and noticed that the unlock function was changed from unsafe to safe:

02a1d48

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?

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.