Skip to content

Commit cbb5dfc

Browse files
committed
Fix CAP representation for prctl
1 parent e5b793b commit cbb5dfc

File tree

1 file changed

+44
-16
lines changed

1 file changed

+44
-16
lines changed

src/thread/prctl.rs

+44-16
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use crate::backend::prctl::syscalls;
2121
use crate::ffi::CString;
2222
use crate::ffi::{c_int, c_uint, c_void, CStr};
2323
use crate::io;
24+
use crate::io::Errno;
2425
use crate::pid::Pid;
2526
use 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]
466467
pub 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

476478
const 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]
487489
pub 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]
695698
pub 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

700716
const 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

Comments
 (0)