CYFS icon indicating copy to clipboard operation
CYFS copied to clipboard

`ChunkId::new` panic with misaligned pointer dereference

Open shinmao opened this issue 1 year ago • 3 comments

Describe the bug https://github.com/buckyos/CYFS/blob/9eaf33f280f060814d18e182c42aa6867f70e0a0/src/component/cyfs-base/src/objects/chunk.rs#L221-L233 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 avatar Jun 13 '23 20:06 shinmao

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 e0301888 and you can run it by yourself, use command cargo test -p cyfs-base objects::chunk -- --nocapture

weiqiushi avatar Jun 14 '23 04:06 weiqiushi

@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: https://github.com/buckyos/CYFS/blob/e030188895096fd8d91d48753877729f4d37dd24/src/component/cyfs-base/src/objects/chunk.rs#L228-L230 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:)

shinmao avatar Jun 14 '23 16:06 shinmao

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.

riking avatar Jul 11 '23 15:07 riking