@@ -105,12 +105,31 @@ pub fn open_readonly(path: &[u8]) -> Result<libc::c_int, Error> {
105
105
/// Thin wrapper around the `getrandom()` Linux system call
106
106
#[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
107
107
pub fn getrandom_syscall ( buf : & mut [ MaybeUninit < u8 > ] ) -> libc:: ssize_t {
108
- unsafe {
109
- libc:: syscall (
110
- libc:: SYS_getrandom ,
111
- buf. as_mut_ptr ( ) . cast :: < core:: ffi:: c_void > ( ) ,
112
- buf. len ( ) ,
113
- 0 ,
114
- ) as libc:: ssize_t
115
- }
108
+ // Rust requires object to be smaller than `isize::MAX` bytes, so there is
109
+ // no real truncation here, even when running
110
+ debug_assert ! ( buf. len( ) <= isize :: MAX . unsigned_abs( ) ) ;
111
+
112
+ // TODO: Add support for x32 and similar ABIs?
113
+
114
+ // pointers can be passed to libc::syscall.
115
+ const _: ( ) = assert ! (
116
+ core:: mem:: size_of:: <libc:: c_long>( ) == core:: mem:: size_of:: <* mut core:: ffi:: c_void>( )
117
+ ) ;
118
+ let ptr = buf. as_mut_ptr ( ) . cast :: < core:: ffi:: c_void > ( ) ;
119
+
120
+ // usize values can be passed to libc::syscall.
121
+ const _: ( ) =
122
+ assert ! ( core:: mem:: size_of:: <libc:: c_long>( ) == core:: mem:: size_of:: <libc:: ssize_t>( ) ) ;
123
+ let len: usize = buf. len ( ) ;
124
+
125
+ const ZERO : libc:: c_ulong = 0 ;
126
+
127
+ let res: libc:: c_long = unsafe { libc:: syscall ( libc:: SYS_getrandom , ptr, len, ZERO ) } ;
128
+
129
+ // c_long to ssize_t conversion is lossless.
130
+ const _: ( ) =
131
+ assert ! ( core:: mem:: size_of:: <libc:: c_long>( ) == core:: mem:: size_of:: <libc:: ssize_t>( ) ) ;
132
+ #[ allow( clippy:: cast_possible_truncation) ]
133
+ let res = res as libc:: ssize_t ;
134
+ res
116
135
}
0 commit comments