@@ -21,6 +21,7 @@ use crate::backend::prctl::syscalls;
2121use crate :: ffi:: CString ;
2222use crate :: ffi:: { c_int, c_uint, c_void, CStr } ;
2323use crate :: io;
24+ use crate :: io:: Errno ;
2425use crate :: pid:: Pid ;
2526use crate :: prctl:: {
2627 prctl_1arg, prctl_2args, prctl_3args, prctl_get_at_arg2_optional, PointerAuthenticationKeys ,
@@ -464,13 +465,14 @@ impl CompatCapability for CapabilitySet {
464465/// [`prctl(PR_CAPBSET_READ,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
465466#[ inline]
466467pub fn capability_is_in_bounding_set ( capability : impl CompatCapability ) -> io:: Result < bool > {
467- unsafe {
468- prctl_2args (
469- PR_CAPBSET_READ ,
470- capability. as_capability_set ( private:: Token ) . bits ( ) as usize as * mut _ ,
471- )
468+ let capset = capability. as_capability_set ( private:: Token ) . bits ( ) ;
469+ if capset. count_ones ( ) != 1 {
470+ return Err ( Errno :: INVAL ) ;
472471 }
473- . map ( |r| r != 0 )
472+ let cap = capset. trailing_zeros ( ) ;
473+
474+ // as *mut _ should be ptr::without_provenance_mut but our MSRV does not allow it.
475+ unsafe { prctl_2args ( PR_CAPBSET_READ , cap as usize as * mut _ ) } . map ( |r| r != 0 )
474476}
475477
476478const PR_CAPBSET_DROP : c_int = 24 ;
@@ -485,13 +487,14 @@ const PR_CAPBSET_DROP: c_int = 24;
485487/// [`prctl(PR_CAPBSET_DROP,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
486488#[ inline]
487489pub fn remove_capability_from_bounding_set ( capability : impl CompatCapability ) -> io:: Result < ( ) > {
488- unsafe {
489- prctl_2args (
490- PR_CAPBSET_DROP ,
491- capability. as_capability_set ( private:: Token ) . bits ( ) as usize as * mut _ ,
492- )
490+ let capset = capability. as_capability_set ( private:: Token ) . bits ( ) ;
491+ if capset. count_ones ( ) != 1 {
492+ return Err ( Errno :: INVAL ) ;
493493 }
494- . map ( |_r| ( ) )
494+ let cap = capset. trailing_zeros ( ) ;
495+
496+ // as *mut _ should be ptr::without_provenance_mut but our MSRV does not allow it.
497+ unsafe { prctl_2args ( PR_CAPBSET_DROP , cap as usize as * mut _ ) } . map ( |_r| ( ) )
495498}
496499
497500//
@@ -693,8 +696,21 @@ const PR_CAP_AMBIENT_IS_SET: usize = 1;
693696/// [`prctl(PR_CAP_AMBIENT,PR_CAP_AMBIENT_IS_SET,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
694697#[ inline]
695698pub fn capability_is_in_ambient_set ( capability : impl CompatCapability ) -> io:: Result < bool > {
696- let cap = capability. as_capability_set ( private:: Token ) . bits ( ) as usize as * mut _ ;
697- unsafe { prctl_3args ( PR_CAP_AMBIENT , PR_CAP_AMBIENT_IS_SET as * mut _ , cap) } . map ( |r| r != 0 )
699+ let capset = capability. as_capability_set ( private:: Token ) . bits ( ) ;
700+ if capset. count_ones ( ) != 1 {
701+ return Err ( Errno :: INVAL ) ;
702+ }
703+ let cap = capset. trailing_zeros ( ) ;
704+
705+ unsafe {
706+ prctl_3args (
707+ PR_CAP_AMBIENT ,
708+ PR_CAP_AMBIENT_IS_SET as * mut _ ,
709+ // as *mut _ should be ptr::without_provenance_mut but our MSRV does not allow it.
710+ cap as usize as * mut _ ,
711+ )
712+ }
713+ . map ( |r| r != 0 )
698714}
699715
700716const PR_CAP_AMBIENT_CLEAR_ALL : usize = 4 ;
@@ -729,9 +745,21 @@ pub fn configure_capability_in_ambient_set(
729745 } else {
730746 PR_CAP_AMBIENT_LOWER
731747 } ;
732- let cap = capability. as_capability_set ( private:: Token ) . bits ( ) as usize as * mut _ ;
748+ let capset = capability. as_capability_set ( private:: Token ) . bits ( ) ;
749+ if capset. count_ones ( ) != 1 {
750+ return Err ( Errno :: INVAL ) ;
751+ }
752+ let cap = capset. trailing_zeros ( ) ;
733753
734- unsafe { prctl_3args ( PR_CAP_AMBIENT , sub_operation as * mut _ , cap) } . map ( |_r| ( ) )
754+ unsafe {
755+ prctl_3args (
756+ PR_CAP_AMBIENT ,
757+ sub_operation as * mut _ ,
758+ // as *mut _ should be ptr::without_provenance_mut but our MSRV does not allow it.
759+ cap as usize as * mut _ ,
760+ )
761+ }
762+ . map ( |_r| ( ) )
735763}
736764
737765//
0 commit comments