Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ChunkId::new panic with misaligned pointer dereference #275

Open
shinmao opened this issue Jun 13, 2023 · 3 comments
Open

ChunkId::new panic with misaligned pointer dereference #275

shinmao opened this issue Jun 13, 2023 · 3 comments
Labels
bug Something isn't working

Comments

@shinmao
Copy link

shinmao commented Jun 13, 2023

Describe the bug

pub fn new(hash_value: &HashValue, len: u32) -> Self {
let hash = hash_value.as_slice();
let mut id = Self::default();
let chunkid = id.as_mut_slice();
chunkid[0] = 0b_01000000 | (ObjectTypeCode::Chunk.to_u16() as u8) << 4 >> 2;
// chunkid[0] = ObjectTypeCode::Chunk.to_u16() as u8;
unsafe {
*(chunkid[1..5].as_mut_ptr() as *mut u32) = len;
}
chunkid[5..].copy_from_slice(&hash[0..27]);
id
}

No matter how I try to create ChunkId with ChunkId::new, it will panic and show the error: misaligned pointer dereference: address must be a multiple of 0x4 but is 0xaddress.

To Reproduce

fn main() {
    let (chunk_len, chunk_data) = random_mem(1024, 1024);
    let chunk_hash = hash_data(&chunk_data[..]);
    println!("{:?}", chunk_hash);
    let chunkid = ChunkId::new(&chunk_hash, chunk_len as u32);
}

There is no sample code in documentation; therefore, I follow the sample code and test I found in repository.

Expected behavior
I expected to get chunk_id at the last line. I am sure the bug comes from new function because I always could print chunk_hash.

System information

[dependencies]
cyfs-base = "0.6.12"
cyfs-bdt = "0.7.3"
cyfs-lib = "0.8.3"

Here are my dependencies. I used it on ubuntu 20.04 with x86-64.

@shinmao shinmao added the bug Something isn't working label Jun 13, 2023
weiqiushi added a commit that referenced this issue Jun 14, 2023
@weiqiushi
Copy link
Member

I wrote a simple test like yours:

#[test]
    fn chunk2() {
        let mut chunk_data = [0u8;1024*1024];
        let chunk_len = chunk_data.len();
        rand::thread_rng().fill_bytes(&mut chunk_data);
        let chunk_hash = hash_data(&chunk_data);
        println!("{:?}", chunk_hash);
        let chunkid = ChunkId::new(&chunk_hash, chunk_len as u32);
        println!("{:?}", chunkid);
    }

and it run successful and print correct result:

HashValue: 6e9cf3599613cf699b9bb60321f51f74dd2b2b8e15132cb3c395605aedf50a27
ChunkId: "7C8WVHtUCu9ECpJbo5wwV8FBs5gcXeHjTkonE2zWb6rK"
test objects::chunk::test::chunk2 ... ok

I already commit the test at e030188 and you can run it by yourself, use command
cargo test -p cyfs-base objects::chunk -- --nocapture

@shinmao
Copy link
Author

shinmao commented Jun 14, 2023

@weiqiushi I tried to call cyfs_base as library. I copy the code provided above

use rand::RngCore;
use cyfs_base::{hash_data, ChunkId, HashValue};

fn main() {
    let mut chunk_data = [0u8;1024*1024];
    let chunk_len = chunk_data.len();
    rand::thread_rng().fill_bytes(&mut chunk_data);
    let chunk_hash = hash_data(&chunk_data);
    println!("{:?}", chunk_hash);
    let chunkid = ChunkId::new(&chunk_hash, chunk_len as u32);
    println!("{:?}", chunkid);
}

and run with dependencies

cyfs-base = "0.6.12"
rand = "0.7"

it still shows the result

HashValue: fe918b3d3ac6217ab061d3769d0473cd5d9a2ff5e4312c67e94fd19fea7f2c0b
thread 'main' panicked at 'misaligned pointer dereference: address must be a multiple of 0x4 but is 0x7ffdf383be41', /${HOME}/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cyfs-base-0.6.12/src/objects/chunk.rs:229:13

The error message shows that misaligned pointer dereference occurs at this line 229:

unsafe {
*(chunkid[1..5].as_mut_ptr() as *mut u32) = len;
}

I consider the problem here is that casting u8 pointer to u32 pointer causes to the mis-alignment. Hope this information could help solve my error:)

@riking
Copy link

riking commented Jul 11, 2023

You can use ptr::write_unaligned to fix this, BUT that leaves the endian problem present. You should instead use u32::to_le_bytes and copy the bytes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants