Skip to content

Commit 1079461

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

File tree

1 file changed

+41
-16
lines changed

1 file changed

+41
-16
lines changed

src/thread/prctl.rs

Lines changed: 41 additions & 16 deletions
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+
let cap = capset.trailing_zeros();
470+
if capset.leading_zeros() + cap + 1 != u64::BITS {
471+
return Err(Errno::INVAL);
472472
}
473-
.map(|r| r != 0)
473+
474+
unsafe { prctl_2args(PR_CAPBSET_READ, ptr::without_provenance_mut(cap as usize)) }
475+
.map(|r| r != 0)
474476
}
475477

476478
const PR_CAPBSET_DROP: c_int = 24;
@@ -485,13 +487,13 @@ 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+
let cap = capset.trailing_zeros();
492+
if capset.leading_zeros() + cap + 1 != u64::BITS {
493+
return Err(Errno::INVAL);
493494
}
494-
.map(|_r| ())
495+
496+
unsafe { prctl_2args(PR_CAPBSET_DROP, ptr::without_provenance_mut(cap as usize)) }.map(|_r| ())
495497
}
496498

497499
//
@@ -693,8 +695,20 @@ const PR_CAP_AMBIENT_IS_SET: usize = 1;
693695
/// [`prctl(PR_CAP_AMBIENT,PR_CAP_AMBIENT_IS_SET,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
694696
#[inline]
695697
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)
698+
let capset = capability.as_capability_set(private::Token).bits();
699+
let cap = capset.trailing_zeros();
700+
if capset.leading_zeros() + cap + 1 != u64::BITS {
701+
return Err(Errno::INVAL);
702+
}
703+
704+
unsafe {
705+
prctl_3args(
706+
PR_CAP_AMBIENT,
707+
PR_CAP_AMBIENT_IS_SET as *mut _,
708+
ptr::without_provenance_mut(cap as usize),
709+
)
710+
}
711+
.map(|r| r != 0)
698712
}
699713

700714
const PR_CAP_AMBIENT_CLEAR_ALL: usize = 4;
@@ -729,9 +743,20 @@ pub fn configure_capability_in_ambient_set(
729743
} else {
730744
PR_CAP_AMBIENT_LOWER
731745
};
732-
let cap = capability.as_capability_set(private::Token).bits() as usize as *mut _;
746+
let capset = capability.as_capability_set(private::Token).bits();
747+
let cap = capset.trailing_zeros();
748+
if capset.leading_zeros() + cap + 1 != u64::BITS {
749+
return Err(Errno::INVAL);
750+
}
733751

734-
unsafe { prctl_3args(PR_CAP_AMBIENT, sub_operation as *mut _, cap) }.map(|_r| ())
752+
unsafe {
753+
prctl_3args(
754+
PR_CAP_AMBIENT,
755+
sub_operation as *mut _,
756+
ptr::without_provenance_mut(cap as usize),
757+
)
758+
}
759+
.map(|_r| ())
735760
}
736761

737762
//

0 commit comments

Comments
 (0)