diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5fe8ae8e8d..5a3a02c707 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,6 +44,32 @@ jobs: - name: before_cache_script run: rm -rf $CARGO_HOME/registry/index + macos-aarch64: + runs-on: macos-14 + env: + TARGET: aarch64-apple-darwin + steps: + - name: checkout + uses: actions/checkout@v4 + + - name: setup Rust + uses: dtolnay/rust-toolchain@master + with: + toolchain: '${{ env.MSRV }}' + components: clippy + + - name: build + uses: ./.github/actions/build + with: + TARGET: "${{ env.TARGET }}" + + - name: test + uses: ./.github/actions/test + with: + TARGET: "${{ env.TARGET }}" + + - name: before_cache_script + run: rm -rf $CARGO_HOME/registry/index # Use cross for QEMU-based testing # cross needs to execute Docker, GitHub Action already has it installed diff --git a/changelog/2311.fixed.md b/changelog/2311.fixed.md new file mode 100644 index 0000000000..c1b4013f05 --- /dev/null +++ b/changelog/2311.fixed.md @@ -0,0 +1 @@ +Fixed `::unistd::Group::members` using read_unaligned to avoid crash on misaligned pointers diff --git a/src/unistd.rs b/src/unistd.rs index 3d98a0efe8..ce2d42455a 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -3476,18 +3476,17 @@ impl Group { let mut ret = Vec::new(); for i in 0.. { - let u = unsafe { mem.offset(i) }; - if unsafe { (*u).is_null() } { + let u = unsafe { mem.offset(i).read_unaligned() }; + if u.is_null() { break; } else { - let s = unsafe {CStr::from_ptr(*u).to_string_lossy().into_owned()}; + let s = unsafe {CStr::from_ptr(u).to_string_lossy().into_owned()}; ret.push(s); } } ret } - /// # Safety /// /// If `f` writes to its `*mut *mut libc::group` parameter, then it must diff --git a/test/test_unistd.rs b/test/test_unistd.rs index 56dc59e720..aa2e5e56d7 100644 --- a/test/test_unistd.rs +++ b/test/test_unistd.rs @@ -1372,3 +1372,14 @@ fn test_eaccess_file_exists() { eaccess(&path, AccessFlags::R_OK | AccessFlags::W_OK) .expect("assertion failed"); } + +#[test] +#[cfg(bsd)] +fn test_group_from() { + let group = Group::from_name("wheel").unwrap().unwrap(); + assert!(group.name == "wheel"); + let group_id = group.gid; + let group = Group::from_gid(group_id).unwrap().unwrap(); + assert_eq!(group.gid, group_id); + assert_eq!(group.name, "wheel"); +}