Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-24.04, windows-2022]
toolchain: [nightly, beta, stable, "1.63"]
toolchain: [nightly, beta, stable, "1.85"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, we should extract MSRV from the rust-version field instead of manually providing it.

# Only Test macOS on stable to reduce macOS CI jobs
include:
# aarch64-apple-darwin.
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- `RawOsError` type alias [#739]

### Changes
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
### Changes
### Changed

- Use Edition 2024 and MSRV 1.85 [#749]

[#739]: https://github.com/rust-random/getrandom/pull/739
[#749]: https://github.com/rust-random/getrandom/pull/749

## [0.3.4] - 2025-10-14

Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[package]
name = "getrandom"
version = "0.3.4"
edition = "2021"
rust-version = "1.63" # Sync tests.yml and README.md.
edition = "2024"
rust-version = "1.85" # Sync tests.yml and README.md.
authors = ["The Rand Project Developers"]
license = "MIT OR Apache-2.0"
description = "A small cross-platform library for retrieving random data from system source"
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ Next, you need to define an `extern` function with the following signature:
```rust
use getrandom::Error;

#[no_mangle]
#[unsafe(no_mangle)]
unsafe extern "Rust" fn __getrandom_v03_custom(
dest: *mut u8,
len: usize,
Expand Down Expand Up @@ -189,7 +189,7 @@ fn my_entropy_source(buf: &mut [u8]) -> Result<(), getrandom::Error> {
Ok(())
}

#[no_mangle]
#[unsafe(no_mangle)]
unsafe extern "Rust" fn __getrandom_v03_custom(
dest: *mut u8,
len: usize,
Expand Down Expand Up @@ -302,7 +302,7 @@ RUSTFLAGS="-Zsanitizer=memory" cargo test -Zbuild-std --target=x86_64-unknown-li

## Minimum Supported Rust Version

This crate requires Rust 1.63 or later.
This crate requires Rust 1.85 or later.

## License

Expand Down
2 changes: 1 addition & 1 deletion benches/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
extern crate test;

use std::{
mem::{size_of, MaybeUninit},
mem::{MaybeUninit, size_of},
slice,
};

Expand Down
2 changes: 1 addition & 1 deletion nopanic_check/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "nopanic_check"
description = "Helper crate for checking that getrandom implementation does not contain potential panics"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false

[workspace]
Expand Down
4 changes: 2 additions & 2 deletions nopanic_check/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ fn panic(_info: &core::panic::PanicInfo) -> ! {
unsafe { panic_nonexistent() }
}

#[no_mangle]
#[unsafe(no_mangle)]
pub extern "C" fn getrandom_wrapper(buf_ptr: *mut u8, buf_len: usize) -> u32 {
let buf = unsafe { core::slice::from_raw_parts_mut(buf_ptr.cast(), buf_len) };
let res = getrandom::fill_uninit(buf).map(|_| ());
unsafe { core::mem::transmute(res) }
}

#[cfg(getrandom_backend = "custom")]
#[no_mangle]
#[unsafe(no_mangle)]
unsafe extern "Rust" fn __getrandom_v03_custom(
dest: *mut u8,
len: usize,
Expand Down
2 changes: 1 addition & 1 deletion src/backends/custom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub use crate::util::{inner_u32, inner_u64};

#[inline]
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
extern "Rust" {
unsafe extern "Rust" {
fn __getrandom_v03_custom(dest: *mut u8, len: usize) -> Result<(), Error>;
}
unsafe { __getrandom_v03_custom(dest.as_mut_ptr().cast(), dest.len()) }
Expand Down
2 changes: 1 addition & 1 deletion src/backends/efi_rng.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use crate::Error;
use core::{
mem::MaybeUninit,
ptr::{self, null_mut, NonNull},
ptr::{self, NonNull, null_mut},
sync::atomic::{AtomicPtr, Ordering::Relaxed},
};
use r_efi::{
Expand Down
2 changes: 1 addition & 1 deletion src/backends/linux_android_with_fallback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use super::{sanitizer, use_file};
use crate::Error;
use core::{
ffi::c_void,
mem::{transmute, MaybeUninit},
mem::{MaybeUninit, transmute},
ptr::NonNull,
sync::atomic::{AtomicPtr, Ordering},
};
Expand Down
142 changes: 78 additions & 64 deletions src/backends/linux_raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,95 +20,109 @@ unsafe fn getrandom_syscall(buf: *mut u8, buflen: usize, flags: u32) -> isize {
// Theoretically, we could detect thumb mode in the build script, but several
// register moves are cheap enough compared to the syscall cost, so we do not
// bother with it.
core::arch::asm!(
"mov {tmp}, r7",
// TODO(MSRV-1.82): replace with `nr = const __NR_getrandom,`
"mov r7, #384",
"svc 0",
"mov r7, {tmp}",
tmp = out(reg) _,
inlateout("r0") buf => r0,
in("r1") buflen,
in("r2") flags,
options(nostack, preserves_flags)
);
unsafe {
core::arch::asm!(
"mov {tmp}, r7",
// TODO(MSRV-1.82): replace with `nr = const __NR_getrandom,`
"mov r7, #384",
"svc 0",
"mov r7, {tmp}",
tmp = out(reg) _,
inlateout("r0") buf => r0,
in("r1") buflen,
in("r2") flags,
options(nostack, preserves_flags)
);
}
} else if #[cfg(target_arch = "aarch64")] {
// TODO(MSRV-1.78): Also check `any(target_abi = "", target_abi = "ilp32")` above.
// According to the ILP32 patch for the kernel that hasn't yet
// been merged into the mainline, "AARCH64/ILP32 ABI uses standard
// syscall table [...] with the exceptions listed below," where
// getrandom is not mentioned as an exception.
const __NR_getrandom: u32 = 278;
core::arch::asm!(
"svc 0",
in("x8") __NR_getrandom,
inlateout("x0") buf => r0,
in("x1") buflen,
in("x2") flags,
options(nostack, preserves_flags)
);
unsafe {
core::arch::asm!(
"svc 0",
in("x8") __NR_getrandom,
inlateout("x0") buf => r0,
in("x1") buflen,
in("x2") flags,
options(nostack, preserves_flags)
);
}
} else if #[cfg(target_arch = "loongarch64")] {
// TODO(MSRV-1.78): Also check `any(target_abi = "", target_abi = "ilp32")` above.
const __NR_getrandom: u32 = 278;
core::arch::asm!(
"syscall 0",
in("$a7") __NR_getrandom,
inlateout("$a0") buf => r0,
in("$a1") buflen,
in("$a2") flags,
options(nostack, preserves_flags)
);
unsafe {
core::arch::asm!(
"syscall 0",
in("$a7") __NR_getrandom,
inlateout("$a0") buf => r0,
in("$a1") buflen,
in("$a2") flags,
options(nostack, preserves_flags)
);
}
} else if #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] {
const __NR_getrandom: u32 = 278;
core::arch::asm!(
"ecall",
in("a7") __NR_getrandom,
inlateout("a0") buf => r0,
in("a1") buflen,
in("a2") flags,
options(nostack, preserves_flags)
);
unsafe {
core::arch::asm!(
"ecall",
in("a7") __NR_getrandom,
inlateout("a0") buf => r0,
in("a1") buflen,
in("a2") flags,
options(nostack, preserves_flags)
);
}
} else if #[cfg(target_arch = "s390x")] {
const __NR_getrandom: u32 = 349;
core::arch::asm!(
"svc 0",
in("r1") __NR_getrandom,
inlateout("r2") buf => r0,
in("r3") buflen,
in("r4") flags,
options(nostack, preserves_flags)
);
unsafe {
core::arch::asm!(
"svc 0",
in("r1") __NR_getrandom,
inlateout("r2") buf => r0,
in("r3") buflen,
in("r4") flags,
options(nostack, preserves_flags)
);
}
} else if #[cfg(target_arch = "x86")] {
const __NR_getrandom: u32 = 355;
// `int 0x80` is famously slow, but implementing vDSO is too complex
// and `sysenter`/`syscall` have their own portability issues,
// so we use the simple "legacy" way of doing syscalls.
core::arch::asm!(
"int $$0x80",
in("eax") __NR_getrandom,
in("ebx") buf,
in("ecx") buflen,
in("edx") flags,
lateout("eax") r0,
options(nostack, preserves_flags)
);
unsafe {
core::arch::asm!(
"int $$0x80",
in("eax") __NR_getrandom,
in("ebx") buf,
in("ecx") buflen,
in("edx") flags,
lateout("eax") r0,
options(nostack, preserves_flags)
);
}
} else if #[cfg(target_arch = "x86_64")] {
// TODO(MSRV-1.78): Add `any(target_abi = "", target_abi = "x32")` above.
const __X32_SYSCALL_BIT: u32 = 0x40000000;
const OFFSET: u32 = if cfg!(target_pointer_width = "32") { __X32_SYSCALL_BIT } else { 0 };
const __NR_getrandom: u32 = OFFSET + 318;

core::arch::asm!(
"syscall",
in("rax") __NR_getrandom,
in("rdi") buf,
in("rsi") buflen,
in("rdx") flags,
lateout("rax") r0,
lateout("rcx") _,
lateout("r11") _,
options(nostack, preserves_flags)
);
unsafe {
core::arch::asm!(
"syscall",
in("rax") __NR_getrandom,
in("rdi") buf,
in("rsi") buflen,
in("rdx") flags,
lateout("rax") r0,
lateout("rcx") _,
lateout("r11") _,
options(nostack, preserves_flags)
);
}
} else {
compile_error!("`linux_raw` backend does not support this target arch");
}
Expand Down
4 changes: 2 additions & 2 deletions src/backends/rdrand.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! RDRAND backend for x86(-64) targets
use crate::{util::slice_as_uninit, Error};
use core::mem::{size_of, MaybeUninit};
use crate::{Error, util::slice_as_uninit};
use core::mem::{MaybeUninit, size_of};

#[path = "../lazy.rs"]
mod lazy;
Expand Down
18 changes: 10 additions & 8 deletions src/backends/rndr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
//! Arm Architecture Reference Manual for A-profile architecture:
//! ARM DDI 0487K.a, ID032224, D23.2.147 RNDR, Random Number
use crate::{
util::{slice_as_uninit, truncate},
Error,
util::{slice_as_uninit, truncate},
};
use core::arch::asm;
use core::mem::{size_of, MaybeUninit};
use core::mem::{MaybeUninit, size_of};

#[cfg(not(target_arch = "aarch64"))]
compile_error!("the `rndr` backend can be enabled only for AArch64 targets!");
Expand All @@ -27,12 +27,14 @@ unsafe fn rndr() -> Option<u64> {
let mut nzcv: u64;

// AArch64 RNDR register is accessible by s3_3_c2_c4_0
asm!(
"mrs {x}, RNDR",
"mrs {nzcv}, NZCV",
x = out(reg) x,
nzcv = out(reg) nzcv,
);
unsafe {
asm!(
"mrs {x}, RNDR",
"mrs {nzcv}, NZCV",
x = out(reg) x,
nzcv = out(reg) nzcv,
);
}

// If the hardware returns a genuine random number, PSTATE.NZCV is set to 0b0000
if nzcv == 0 {
Expand Down
2 changes: 1 addition & 1 deletion src/backends/use_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ mod sync {

#[cfg(any(target_os = "android", target_os = "linux"))]
mod sync {
use super::{open_readonly, util_libc::last_os_error, Error, FD, FD_ONGOING_INIT};
use super::{Error, FD, FD_ONGOING_INIT, open_readonly, util_libc::last_os_error};

/// Wait for atomic `FD` to change value from `FD_ONGOING_INIT` to something else.
///
Expand Down
2 changes: 1 addition & 1 deletion src/util_libc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ cfg_if! {
if #[cfg(target_os = "vxworks")] {
use libc::errnoGet as get_errno;
} else {
unsafe fn get_errno() -> libc::c_int { *errno_location() }
unsafe fn get_errno() -> libc::c_int { unsafe { *errno_location() }}
}
}

Expand Down
7 changes: 4 additions & 3 deletions tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,8 @@ mod custom {
// This implementation uses current timestamp as a PRNG seed.
//
// WARNING: this custom implementation is for testing purposes ONLY!
#[no_mangle]

#[unsafe(no_mangle)]
unsafe extern "Rust" fn __getrandom_v03_custom(dest: *mut u8, len: usize) -> Result<(), Error> {
use std::time::{SystemTime, UNIX_EPOCH};

Expand All @@ -275,13 +276,13 @@ mod custom {
let mut rng = Xoshiro128PlusPlus::new(ts.as_nanos() as u64);
for i in 0..len / 4 {
let val = rng.next_u32();
core::ptr::write_unaligned(dest_u32.add(i), val);
unsafe { core::ptr::write_unaligned(dest_u32.add(i), val) };
}
if len % 4 != 0 {
let start = 4 * (len / 4);
for i in start..len {
let val = rng.next_u32();
core::ptr::write_unaligned(dest.add(i), val as u8);
unsafe { core::ptr::write_unaligned(dest.add(i), val as u8) };
}
}
Ok(())
Expand Down
Loading