diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 475be63..5b76f60 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -156,6 +156,33 @@ jobs: - name: Check run: cargo +${{ matrix.toolchain }} check --target ${{ matrix.target }} + check-mach2: + name: Check (mach2 ${{ matrix.mach2 }}) + runs-on: macos-latest + strategy: + fail-fast: false + matrix: + # The oldest and newest versions accepted by the `mach2` requirement + mach2: ["0.4.3", "0.7.0"] + + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + targets: aarch64-apple-ios + + - name: Pin mach2 + run: cargo update -p mach2 --precise ${{ matrix.mach2 }} + + - name: Test + run: cargo test -- --test-threads=1 + + - name: Check iOS + run: cargo check --target aarch64-apple-ios --all-targets + check-hurd: name: Check (x86_64-unknown-hurd-gnu) runs-on: ubuntu-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index e319e71..0722c8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Changed + +- Widened the `mach2` requirement from 0.4 to `>=0.4.2, <0.8` (macOS & iOS), + allowing dependents to share a single `mach2` version. +- Depend on `libc` & `mach2` without their default (`std`) features. + +### Fixed + +- Resolved Clippy `ptr_as_ptr` violations on FreeBSD, NetBSD & Windows. + ## [4.0.0] - 2026-08-07 ### Added diff --git a/Cargo.toml b/Cargo.toml index 261a3a2..0922588 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,10 +21,10 @@ std = ["bitflags/std"] [dependencies] bitflags = { version = "2.6", default-features = false } -libc = "0.2.172" +libc = { version = "0.2.172", default-features = false } [target."cfg(any(target_os = \"macos\", target_os = \"ios\"))".dependencies] -mach2 = "0.4.2" +mach2 = { version = ">=0.4.2, <0.8", default-features = false } [target.'cfg(windows)'.dependencies.windows-sys] # Accept a range so dependents can unify on a single windows-sys version. diff --git a/src/allocation.rs b/src/allocation.rs index fb54551..ff213ae 100644 --- a/src/allocation.rs +++ b/src/allocation.rs @@ -250,18 +250,24 @@ mod tests { let buffers = (0..8) .map(|_| alloc(1, Protection::READ_WRITE)) .collect::>>()?; - let start = alloc(1, Protection::READ_WRITE)?; + // Tests run concurrently, so another thread may map memory at the freed + // address before it is queried. Retry to rule out such a race. + let mut query = Ok(crate::Region::default()); + for _ in 0..16 { + let start = alloc(1, Protection::READ_WRITE)?; + let base = start.as_ptr::<()>(); + drop(start); - let base = start.as_ptr::<()>(); - drop(start); + query = crate::query(base); + if matches!(query, Err(Error::UnmappedRegion)) { + return Ok(()); + } + } - let query = crate::query(base); - assert!( - matches!(query, Err(Error::UnmappedRegion)), + panic!( "expected unmapped region after free, got {query:?}; retained {} buffers", buffers.len() ); - Ok(()) } #[test] diff --git a/src/lib.rs b/src/lib.rs index ac4abad..6006336 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -467,7 +467,7 @@ mod tests { ) }; assert_eq!(address, page_address); - page_address = unsafe { (address as *mut u8).add(page::size()) }.cast(); + page_address = unsafe { address.cast::().add(page::size()) }.cast(); } AllocatedPages(allocation_base.cast(), total_size) diff --git a/src/os/freebsd.rs b/src/os/freebsd.rs index 0dcc8d9..ecb979f 100644 --- a/src/os/freebsd.rs +++ b/src/os/freebsd.rs @@ -1,5 +1,4 @@ use crate::{Error, Protection, Region, Result}; -use core::ffi::c_void; use core::ptr; use libc::{ KVME_PROT_EXEC, KVME_PROT_READ, KVME_PROT_WRITE, KVME_TYPE_DEFAULT, c_int, free, getpid, @@ -46,7 +45,7 @@ impl Iterator for QueryIter { // Since the struct size is given in the struct, it can be used future-proof // (the definition is not required to be updated when new fields are added). let offset = unsafe { self.vmmap_index * (*self.vmmap).kve_structsize as usize }; - let entry = unsafe { &*((self.vmmap as *const c_void).add(offset) as *const kinfo_vmentry) }; + let entry = unsafe { &*self.vmmap.cast::().add(offset).cast::() }; self.vmmap_index += 1; Some(Ok(Region { @@ -61,7 +60,7 @@ impl Iterator for QueryIter { impl Drop for QueryIter { fn drop(&mut self) { - unsafe { free(self.vmmap as *mut c_void) } + unsafe { free(self.vmmap.cast()) } } } diff --git a/src/os/netbsd.rs b/src/os/netbsd.rs index c3e215e..1b2f946 100644 --- a/src/os/netbsd.rs +++ b/src/os/netbsd.rs @@ -1,5 +1,5 @@ use crate::{Error, Protection, Region, Result}; -use core::ffi::{c_char, c_int, c_void}; +use core::ffi::{c_char, c_int}; use core::ptr; use libc::{free, getpid, pid_t}; @@ -41,7 +41,7 @@ impl Iterator for QueryIter { } let offset = self.vmmap_index * core::mem::size_of::(); - let entry = unsafe { &*((self.vmmap as *const c_void).add(offset) as *const kinfo_vmentry) }; + let entry = unsafe { &*self.vmmap.cast::().add(offset).cast::() }; self.vmmap_index += 1; Some(Ok(Region { @@ -57,7 +57,7 @@ impl Iterator for QueryIter { impl Drop for QueryIter { fn drop(&mut self) { - unsafe { free(self.vmmap as *mut c_void) } + unsafe { free(self.vmmap.cast()) } } }