Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactors regmgr_call and privileges #663

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/kernel/src/regmgr/command.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use super::RegError;

#[repr(u32)]
pub(super) enum RegMgrCommand<'a> {
SetInt(&'a SetIntArg) = 0x18,
Unk1(&'a Unk1Arg) = 0x19,
}
impl RegMgrCommand<'_> {
pub fn try_from_raw_parts(cmd: u32, arg: *const u8) -> Result<Self, RegError> {
SuchAFuriousDeath marked this conversation as resolved.
Show resolved Hide resolved
match cmd {
0x18 => Ok(RegMgrCommand::SetInt(unsafe { &*(arg as *const _) })),
0x19 => Ok(RegMgrCommand::Unk1(unsafe { &*(arg as *const _) })),
0x27 | 0x40.. => Err(RegError::V800d0219),
v => todo!("RegMgrCommand({v})"),
}
}
}

#[repr(C)]
pub(super) struct SetIntArg {
pub v1: u64,
pub v2: u32,
pub value: i32,
}

#[repr(C)]
pub(super) struct Unk1Arg {
pub v1: u64,
pub v2: u32,
}
42 changes: 26 additions & 16 deletions src/kernel/src/regmgr/mod.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
pub use self::key::*;

use self::command::*;
use crate::errno::EINVAL;
use crate::process::VThread;
use crate::syscalls::{SysErr, SysIn, SysOut, Syscalls};
use crate::ucred::Ucred;
use crate::ucred::{Privilege, Ucred};
use crate::{info, warn};
use std::fmt::{Display, Formatter};
use std::num::NonZeroI32;
use std::ptr::read;
use std::sync::Arc;
use thiserror::Error;

pub use self::key::*;

mod command;
mod key;

/// An implementation of PS4 registry manager.
Expand All @@ -33,7 +34,10 @@ impl RegMgr {
let req: *const u8 = i.args[3].into();
let reqlen: usize = i.args[4].into();

// TODO: Check the result of priv_check(td, 682).
let td = VThread::current().unwrap();

td.cred().priv_check(Privilege::SCE682)?;

if buf.is_null() {
todo!("regmgr_call with buf = null");
}
Expand All @@ -46,13 +50,21 @@ impl RegMgr {
todo!("regmgr_call with reqlen > 2048");
}

let command = match RegMgrCommand::try_from_raw_parts(op, req) {
Ok(v) => v,
Err(e) => {
warn!(e, "regmgr_call({op}) failed");
unsafe { *buf = e.code() };
return Ok(SysOut::ZERO);
}
};

// Execute the operation.
let td = VThread::current().unwrap();
let r = match op {
0x18 => {
let v1 = unsafe { read::<u64>(req as _) };
let v2 = unsafe { read::<u32>(req.add(8) as _) };
let value = unsafe { read::<i32>(req.add(12) as _) };
let r = match command {
RegMgrCommand::SetInt(arg) => {
let v1 = arg.v1;
let v2 = arg.v2;
let value = arg.value;

info!(
"Attempting to set registry with v1: {}, v2: {}, value: {}.",
Expand All @@ -64,15 +76,13 @@ impl RegMgr {
self.set_int(k, value)
})
}
0x19 => {
let v1 = unsafe { read::<u64>(req as _) };
let v2 = unsafe { read::<u32>(req.add(8) as _) };
RegMgrCommand::Unk1(arg) => {
let v1 = arg.v1;
let v2 = arg.v2;

self.decode_key(v1, v2, td.cred(), 1)
.and_then(|k| todo!("regmgr_call({op}) with matched key = {k}"))
}
0x27 | 0x40.. => Err(RegError::V800d0219),
v => todo!("regmgr_call({v})"),
};

// Write the result.
Expand Down
1 change: 1 addition & 0 deletions src/kernel/src/ucred/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ impl Ucred {
Privilege::MAXFILES
| Privilege::PROC_SETLOGIN
| Privilege::SCE680
| Privilege::SCE682
| Privilege::SCE683
| Privilege::SCE686 => self.is_system(),
v => todo!("priv_check_cred(cred, {v})"),
Expand Down
56 changes: 30 additions & 26 deletions src/kernel/src/ucred/privilege.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,37 @@ use std::fmt::{Display, Formatter};
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct Privilege(i32);

impl Privilege {
pub const MAXFILES: Self = Self(3);
pub const PROC_SETLOGIN: Self = Self(161);
pub const VFS_READ: Self = Self(310);
pub const VFS_WRITE: Self = Self(311);
pub const VFS_ADMIN: Self = Self(312);
pub const VFS_EXEC: Self = Self(313);
pub const VFS_LOOKUP: Self = Self(314);
pub const SCE680: Self = Self(680);
pub const SCE683: Self = Self(683);
pub const SCE686: Self = Self(686);
}
macro_rules! privileges {
($($name:ident($value:expr)),*) => {
impl Privilege {
$(
pub const $name: Self = Self($value);
)*
}

impl Display for Privilege {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match *self {
Self::MAXFILES => f.write_str("PRIV_MAXFILES"),
Self::PROC_SETLOGIN => f.write_str("PRIV_PROC_SETLOGIN"),
Self::VFS_READ => f.write_str("PRIV_VFS_READ"),
Self::VFS_WRITE => f.write_str("PRIV_VFS_WRITE"),
Self::VFS_ADMIN => f.write_str("PRIV_VFS_ADMIN"),
Self::VFS_EXEC => f.write_str("PRIV_VFS_EXEC"),
Self::VFS_LOOKUP => f.write_str("PRIV_VFS_LOOKUP"),
Self::SCE680 => f.write_str("SCE680"),
Self::SCE683 => f.write_str("SCE683"),
Self::SCE686 => f.write_str("SCE686"),
v => v.0.fmt(f),
impl Display for Privilege {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match *self {
$(
Self($value) => f.write_str(stringify!($name)),
)*
v => v.0.fmt(f),
}
}
}
}
}

privileges! {
MAXFILES(3),
PROC_SETLOGIN(161),
VFS_READ(310),
VFS_WRITE(311),
VFS_ADMIN(312),
VFS_EXEC(313),
VFS_LOOKUP(314),
SCE680(680),
SCE682(682),
SCE683(683),
SCE686(686)
}