Skip to content

Commit

Permalink
Implements sys_get_proc_type_info (obhq#794)
Browse files Browse the repository at this point in the history
  • Loading branch information
SuchAFuriousDeath authored Apr 1, 2024
1 parent 1cbc0ef commit 69a6ab2
Show file tree
Hide file tree
Showing 4 changed files with 201 additions and 42 deletions.
81 changes: 81 additions & 0 deletions src/kernel/src/process/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::syscalls::{SysErr, SysIn, SysOut, Syscalls};
use crate::sysent::ProcAbi;
use crate::ucred::{AuthInfo, Gid, Privilege, Ucred, Uid};
use crate::vm::{MemoryManagerError, Vm};
use bitflags::bitflags;
use gmtx::{Gutex, GutexGroup, GutexReadGuard, GutexWriteGuard};
use macros::Errno;
use std::any::Any;
Expand Down Expand Up @@ -133,6 +134,7 @@ impl VProc {
sys.register(585, &vp, Self::sys_is_in_sandbox);
sys.register(587, &vp, Self::sys_get_authinfo);
sys.register(602, &vp, Self::sys_randomized_path);
sys.register(612, &vp, Self::sys_get_proc_type_info);

vp.abi.set(ProcAbi::new(sys)).unwrap();

Expand Down Expand Up @@ -726,6 +728,63 @@ impl VProc {
Ok(SysOut::ZERO)
}

fn sys_get_proc_type_info(self: &Arc<Self>, td: &VThread, i: &SysIn) -> Result<SysOut, SysErr> {
let info = unsafe { &mut *Into::<*mut ProcTypeInfo>::into(i.args[0]) };

if info.len != size_of::<ProcTypeInfo>() {
return Err(SysErr::Raw(EINVAL));
}

*info = td.proc().get_proc_type_info();

Ok(SysOut::ZERO)
}

fn get_proc_type_info(&self) -> ProcTypeInfo {
let cred = self.cred();

let mut flags = ProcTypeInfoFlags::empty();

flags.set(
ProcTypeInfoFlags::IS_JIT_COMPILER_PROCESS,
cred.is_jit_compiler_process(),
);
flags.set(
ProcTypeInfoFlags::IS_JIT_APPLICATION_PROCESS,
cred.is_jit_application_process(),
);
flags.set(
ProcTypeInfoFlags::IS_VIDEOPLAYER_PROCESS,
cred.is_videoplayer_process(),
);
flags.set(
ProcTypeInfoFlags::IS_DISKPLAYERUI_PROCESS,
cred.is_diskplayerui_process(),
);
flags.set(
ProcTypeInfoFlags::HAS_USE_VIDEO_SERVICE_CAPABILITY,
cred.has_use_video_service_capability(),
);
flags.set(
ProcTypeInfoFlags::IS_WEBCORE_PROCESS,
cred.is_webcore_process(),
);
flags.set(
ProcTypeInfoFlags::HAS_SCE_PROGRAM_ATTRIBUTE,
cred.has_sce_program_attribute(),
);
flags.set(
ProcTypeInfoFlags::IS_DEBUGGABLE_PROCESS,
cred.is_debuggable_process(),
);

ProcTypeInfo {
len: size_of::<ProcTypeInfo>(),
ty: self.budget_ptype as u32,
flags,
}
}

fn new_id() -> NonZeroI32 {
let id = NEXT_ID.fetch_add(1, Ordering::Relaxed);

Expand Down Expand Up @@ -784,6 +843,28 @@ struct RtPrio {
prio: u16,
}

/// Outout of sys_get_proc_type_info.
#[repr(C)]
struct ProcTypeInfo {
len: usize,
ty: u32,
flags: ProcTypeInfoFlags,
}

bitflags! {
#[repr(transparent)]
struct ProcTypeInfoFlags: u32 {
const IS_JIT_COMPILER_PROCESS = 0x1;
const IS_JIT_APPLICATION_PROCESS = 0x2;
const IS_VIDEOPLAYER_PROCESS = 0x4;
const IS_DISKPLAYERUI_PROCESS = 0x8;
const HAS_USE_VIDEO_SERVICE_CAPABILITY = 0x10;
const IS_WEBCORE_PROCESS = 0x20;
const HAS_SCE_PROGRAM_ATTRIBUTE = 0x40;
const IS_DEBUGGABLE_PROCESS = 0x80;
}
}

/// Represents an error when [`VProc`] construction is failed.
#[derive(Debug, Error)]
pub enum VProcInitError {
Expand Down
20 changes: 20 additions & 0 deletions src/kernel/src/ucred/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,18 @@ impl AuthCaps {
(self.0[0] & 0x2000000000000000) != 0
}

pub fn is_jit_compiler_process(&self) -> bool {
todo!()
}

pub fn is_jit_application_process(&self) -> bool {
todo!()
}

pub fn has_use_video_service_capability(&self) -> bool {
self.0[0] >> 0x39 & 1 != 0
}

pub fn is_system(&self) -> bool {
(self.0[0] & 0x4000000000000000) != 0
}
Expand All @@ -113,6 +125,14 @@ impl AuthAttrs {
Self(raw)
}

pub fn has_sce_program_attribute(&self) -> bool {
todo!()
}

pub fn is_debuggable_process(&self) -> bool {
todo!()
}

pub fn is_unk1(&self) -> bool {
(self.0[0] & 0x800000) != 0
}
Expand Down
46 changes: 41 additions & 5 deletions src/kernel/src/ucred/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,26 +57,62 @@ impl Ucred {
self.groups[1..].binary_search(&gid).is_ok()
}

/// See `sceSblACMgrIsWebcoreProcess` on the PS4 for a reference.
pub fn is_webcore_process(&self) -> bool {
pub fn is_unknown1(&self) -> bool {
// TODO: Refactor this for readability.
let id = self.auth.paid.get().wrapping_add(0xc7ffffffeffffffc);
(id < 0xf) && ((0x6001 >> (id & 0x3f) & 1) != 0)
}

/// See `sceSblACMgrIsDiskplayeruiProcess` on the PS4 for a reference.
pub fn is_diskplayerui_process(&self) -> bool {
pub fn is_unknown2(&self) -> bool {
matches!(
self.auth.paid.get(),
0x380000001000000f | 0x3800000010000013
)
}

/// See `sceSblACMgrIsDiskplayeruiProcess` on the PS4 for a reference.
pub fn is_diskplayerui_process(&self) -> bool {
self.auth.paid.get() == 0x3800000010000009
}

/// See `sceSblACMgrIsJitCompilerProcess` on the PS4 for a reference.
pub fn is_jit_compiler_process(&self) -> bool {
self.auth.caps.is_jit_compiler_process()
}

/// See `sceSblACMgrIsJitCompilerProcess` on the PS4 for a reference.
pub fn is_jit_application_process(&self) -> bool {
self.auth.caps.is_jit_application_process()
}

/// See `sceSblACMgrIsVideoplayerProcess` on the PS4 for a reference.
pub fn is_videoplayer_process(&self) -> bool {
self.auth.paid.get().wrapping_add(0xc7ffffffefffffff) < 2
}

/// See `sceSblACMgrHasUseVideoServiceCapability` on the PS4 for a reference.
pub fn has_use_video_service_capability(&self) -> bool {
self.auth.caps.has_use_video_service_capability()
}

/// See `sceSblACMgrIsWebcoreProcess` on the PS4 for a reference.
pub fn is_webcore_process(&self) -> bool {
todo!()
}

pub fn has_sce_program_attribute(&self) -> bool {
self.auth.attrs.has_sce_program_attribute()
}

/// See `sceSblACMgrHasSceProgramAttribute` on the PS4 for a reference.
pub fn is_debuggable_process(&self) -> bool {
self.auth.attrs.is_debuggable_process()
}

/// See `sceSblACMgrIsNongameUcred` on the PS4 for a reference.
pub fn is_nongame(&self) -> bool {
self.auth.caps.is_nongame()
}

/// See `sceSblACMgrIsSystemUcred` on the PS4 for a reference.
pub fn is_system(&self) -> bool {
self.auth.caps.is_system()
Expand Down
96 changes: 59 additions & 37 deletions src/kernel/src/ucred/privilege.rs
Original file line number Diff line number Diff line change
@@ -1,42 +1,64 @@
use std::fmt::{Display, Formatter};

/// Privilege identifier.
///
/// See https://github.com/freebsd/freebsd-src/blob/release/9.1.0/sys/sys/priv.h for standard
/// FreeBSD privileges.
#[repr(transparent)]
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct Privilege(i32);
macro_rules! privileges {
(
$( #[$attr:meta] )*
pub enum $name:ident {
$(
$( #[$var_attr:meta] )*
$variant:ident = $value:expr,
)*
}
) => {
$( #[$attr] )*
pub enum $name {
$(
$( #[$var_attr] )*
#[allow(non_camel_case_types)]
$variant = $value
),*
}

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 SCE685: Self = Self(685);
pub const SCE686: Self = Self(686);
impl std::fmt::Display for $name {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match *self {
$(
Self::$variant => f.write_str(stringify!($variant)),
)*
}
}
}
};
}

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::SCE685 => f.write_str("SCE685"),
Self::SCE686 => f.write_str("SCE686"),
v => v.0.fmt(f),
}
privileges! {
/// Privilege identifier.
///
/// See https://github.com/freebsd/freebsd-src/blob/release/9.1.0/sys/sys/priv.h for standard
/// FreeBSD privileges.
#[repr(i32)]
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Privilege {
/// Exceed system open files limit.
#[allow(unused)]
MAXFILES = 3,
/// Can call setlogin.
PROC_SETLOGIN = 161,
/// Override vnode DAC read perm.
VFS_READ = 310,
/// Override vnode DAC write perm.
VFS_WRITE = 311,
/// Override vnode DAC admin perm.
VFS_ADMIN = 312,
/// Override vnode DAC exec perm.
VFS_EXEC = 313,
/// Override vnode DAC lookup perm.
VFS_LOOKUP = 314,
/// Currently unknown.
SCE680 = 680,
/// Currently unknown.
SCE683 = 683,
/// Currently unknown.
SCE685 = 685,
/// Currently unknown.
SCE686 = 686,
}
}

0 comments on commit 69a6ab2

Please sign in to comment.