Potential unsoundness
Nugine opened this issue · 8 comments
There is no guarantee that the safety requirements are met here.
https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety
async-rdma/src/memory_region/local.rs
Lines 15 to 19 in 97fad33
async-rdma/src/memory_region/local.rs
Lines 34 to 38 in 97fad33
Alignment mismatch
#[test]
fn align_check() {
use std::mem::align_of;
assert_eq!(align_of::<Gid>(), align_of::<ibv_gid>());
}
running 1 test
thread 'gid::align_check' panicked at 'assertion failed: `(left == right)`
left: `1`,
right: `8`', src/gid.rs:68:5
Lines 45 to 63 in 9a32a81
There is no guarantee that the safety requirements are met here.
https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety
async-rdma/src/memory_region/local.rs
Lines 15 to 19 in 97fad33
async-rdma/src/memory_region/local.rs
Lines 34 to 38 in 97fad33
These two trait are crate pub traits, the usage is limited in the crates, so the discussion boundry is limited.
Safety cares the following points:
- The memory is aligned properly and the memory region is available for read. The alignment of
u8
is natrually met, and the read permission is garanteed in all the implementations. - The content is properly initialized, for
u8
type the requirement is meaningless, any value is valid. - The mutation property is considered, we can only get one mutable reference. The property is guarded by the Rust compiler.
- The length of the memory region should not exceed
isize::MAX
. We're not checking it correctly. It's a good catch
Alignment mismatch
#[test] fn align_check() { use std::mem::align_of; assert_eq!(align_of::<Gid>(), align_of::<ibv_gid>()); }running 1 test thread 'gid::align_check' panicked at 'assertion failed: `(left == right)` left: `1`, right: `8`', src/gid.rs:68:5
Lines 45 to 63 in 9a32a81
It's a good catch. We'll add more alignment constrain on Gid
struct.
These two trait are crate pub traits, the usage is limited in the crates,
The traits are parts of the public api in v0.2.0. They should be marked as sealed traits or unsafe traits.
https://docs.rs/async-rdma/0.2.0/async_rdma/index.html#traits
The content is properly initialized, for u8 type the requirement is meaningless, any value is valid.
The trait itself can not ensure this. Even raw bytes must be initialized before reading.
Example:
Click Tools
-> Miri
, it reports undefined behavior.
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=5d09005a17d00ab33ff9d86ce8844de6
Related comment: #49 (comment)
the memory region is available for read
The as_ptr
method in the trait does not ensure that the returned pointer is valid.
I think we should mark the trait as sealed traits, so that they can't be implemented by the users.
For u8
type initialization means setting zero, which is inefficient for a large memory block. Let's provide two types of APIs, one for fast and unsafe requirements, the other for zeroed and safe requirements.
Todo:
- mark the traits sealed
- provide two apis, safe and unsafe one.
- change
Gid
alignment.
What about sealed unsafe traits?
Yes of course, if it contains unsafe interface, it's unsafe.
Exporting uninitialized memory
#49 (comment)
async-rdma/src/mr_allocator.rs
Lines 108 to 132 in ab99fa3