mirror of
https://github.com/hexagonal-sun/moss-kernel.git
synced 2026-05-04 14:10:04 -04:00
Merge pull request #153 from arihant2math/prctl-updates
Implement more of prctl
This commit is contained in:
@@ -145,10 +145,18 @@ impl Capabilities {
|
||||
self.ambient
|
||||
}
|
||||
|
||||
pub fn ambient_mut(&mut self) -> &mut CapabilitiesFlags {
|
||||
&mut self.ambient
|
||||
}
|
||||
|
||||
pub fn bounding(&self) -> CapabilitiesFlags {
|
||||
self.bounding
|
||||
}
|
||||
|
||||
pub fn bounding_mut(&mut self) -> &mut CapabilitiesFlags {
|
||||
&mut self.bounding
|
||||
}
|
||||
|
||||
/// Checks if a capability is effective, as in if it can be used.
|
||||
pub fn is_capable(&self, cap: CapabilitiesFlags) -> bool {
|
||||
self.effective.contains(cap)
|
||||
|
||||
@@ -471,7 +471,7 @@ pub async fn handle_syscall() {
|
||||
0xa0 => sys_uname(TUA::from_value(arg1 as _)).await,
|
||||
0xa3 => Err(KernelError::InvalidValue),
|
||||
0xa6 => sys_umask(arg1 as _).map_err(|e| match e {}),
|
||||
0xa7 => sys_prctl(arg1 as _, arg2).await,
|
||||
0xa7 => sys_prctl(arg1 as _, arg2, arg3).await,
|
||||
0xa9 => sys_gettimeofday(TUA::from_value(arg1 as _), TUA::from_value(arg2 as _)).await,
|
||||
0xac => sys_getpid().map_err(|e| match e {}),
|
||||
0xad => sys_getppid().map_err(|e| match e {}),
|
||||
|
||||
@@ -2,23 +2,55 @@ use crate::memory::uaccess::copy_to_user_slice;
|
||||
use crate::memory::uaccess::cstr::UserCStr;
|
||||
use crate::process::Comm;
|
||||
use crate::sched::current::current_task_shared;
|
||||
use bitflags::Flags;
|
||||
use core::ffi::c_char;
|
||||
use libkernel::error::{KernelError, Result};
|
||||
use libkernel::memory::address::TUA;
|
||||
use libkernel::proc::caps::CapabilitiesFlags;
|
||||
|
||||
const PR_CAPBSET_READ: i32 = 23;
|
||||
const PR_CAPBSET_DROP: i32 = 24;
|
||||
const PR_SET_NAME: i32 = 15;
|
||||
const PR_GET_NAME: i32 = 16;
|
||||
const CAP_MAX: usize = 40;
|
||||
const PR_GET_SECUREBITS: i32 = 27;
|
||||
const PR_GET_NO_NEW_PRIVS: i32 = 39;
|
||||
const PR_CAP_AMBIENT: i32 = 47;
|
||||
|
||||
fn pr_read_capset(what: usize) -> Result<usize> {
|
||||
// Validate the argument
|
||||
if what > CAP_MAX {
|
||||
return Err(KernelError::InvalidValue);
|
||||
#[derive(Debug)]
|
||||
enum AmbientCapOp {
|
||||
IsSet = 1,
|
||||
Raise = 2,
|
||||
Lower = 3,
|
||||
ClearAll = 4,
|
||||
}
|
||||
|
||||
impl TryFrom<u64> for AmbientCapOp {
|
||||
type Error = KernelError;
|
||||
|
||||
fn try_from(value: u64) -> Result<Self> {
|
||||
match value {
|
||||
1 => Ok(AmbientCapOp::IsSet),
|
||||
2 => Ok(AmbientCapOp::Raise),
|
||||
3 => Ok(AmbientCapOp::Lower),
|
||||
4 => Ok(AmbientCapOp::ClearAll),
|
||||
_ => Err(KernelError::InvalidValue),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Assume we have *all* the capabilities.
|
||||
Ok(1)
|
||||
fn pr_read_capbset(what: usize) -> Result<usize> {
|
||||
let what = CapabilitiesFlags::from_bits(1u64 << what).ok_or(KernelError::InvalidValue)?;
|
||||
let task = current_task_shared();
|
||||
let creds = task.creds.lock_save_irq();
|
||||
Ok(creds.caps.bounding().contains(what) as _)
|
||||
}
|
||||
|
||||
async fn pr_drop_capbset(what: usize) -> Result<usize> {
|
||||
let what = CapabilitiesFlags::from_bits(1u64 << what).ok_or(KernelError::InvalidValue)?;
|
||||
let task = current_task_shared();
|
||||
let mut creds = task.creds.lock_save_irq();
|
||||
creds.caps.bounding_mut().remove(what);
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
async fn pr_get_name(str: TUA<c_char>) -> Result<usize> {
|
||||
@@ -36,11 +68,42 @@ async fn pr_set_name(str: TUA<c_char>) -> Result<usize> {
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
pub async fn sys_prctl(op: i32, arg1: u64) -> Result<usize> {
|
||||
async fn pr_cap_ambient(op: u64, arg1: u64) -> Result<usize> {
|
||||
let op = AmbientCapOp::try_from(op)?;
|
||||
let task = current_task_shared();
|
||||
match op {
|
||||
AmbientCapOp::ClearAll => {
|
||||
let mut creds = task.creds.lock_save_irq();
|
||||
creds.caps.ambient_mut().clear();
|
||||
Ok(0)
|
||||
}
|
||||
AmbientCapOp::IsSet => {
|
||||
let what =
|
||||
CapabilitiesFlags::from_bits(1u64 << arg1).ok_or(KernelError::InvalidValue)?;
|
||||
let creds = task.creds.lock_save_irq();
|
||||
let is_set = creds.caps.ambient().contains(what);
|
||||
Ok(is_set as _)
|
||||
}
|
||||
AmbientCapOp::Lower => {
|
||||
let what =
|
||||
CapabilitiesFlags::from_bits(1u64 << arg1).ok_or(KernelError::InvalidValue)?;
|
||||
let mut creds = task.creds.lock_save_irq();
|
||||
creds.caps.ambient_mut().remove(what);
|
||||
Ok(0)
|
||||
}
|
||||
op => todo!("prctl PR_CAP_AMBIENT op: {:?}", op),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn sys_prctl(op: i32, arg1: u64, arg2: u64) -> Result<usize> {
|
||||
match op {
|
||||
PR_SET_NAME => pr_set_name(TUA::from_value(arg1 as usize)).await,
|
||||
PR_GET_NAME => pr_get_name(TUA::from_value(arg1 as usize)).await,
|
||||
PR_CAPBSET_READ => pr_read_capset(arg1 as usize),
|
||||
PR_CAPBSET_READ => pr_read_capbset(arg1 as usize),
|
||||
PR_CAPBSET_DROP => pr_drop_capbset(arg1 as usize).await,
|
||||
PR_GET_SECUREBITS => Ok(0),
|
||||
PR_GET_NO_NEW_PRIVS => Ok(0),
|
||||
PR_CAP_AMBIENT => pr_cap_ambient(arg1, arg2).await,
|
||||
_ => todo!("prctl op: {}", op),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user