Optimize getters of the current process credentials

This commit is contained in:
Zhang Junyang
2024-08-11 13:09:41 +00:00
committed by Tate, Hongliang Tian
parent 66a37da214
commit f84d328956
27 changed files with 96 additions and 148 deletions

View File

@ -8,7 +8,6 @@ use ostd::{
};
use super::{
credentials,
posix_thread::{PosixThread, PosixThreadBuilder, PosixThreadExt, ThreadName},
process_table,
process_vm::ProcessVm,
@ -184,7 +183,7 @@ fn clone_child_thread(
let child_tid = allocate_tid();
let child_thread = {
let credentials = {
let credentials = credentials();
let credentials = ctx.posix_thread.credentials();
Credentials::new_from(&credentials)
};
@ -271,7 +270,7 @@ fn clone_child_process(
let child_thread_name = ThreadName::new_from_executable_path(&child_elf_path)?;
let credentials = {
let credentials = credentials();
let credentials = ctx.posix_thread.credentials();
Credentials::new_from(&credentials)
};

View File

@ -7,12 +7,11 @@ mod group;
mod static_cap;
mod user;
use aster_rights::{FullOp, ReadOp, WriteOp};
use aster_rights::FullOp;
use credentials_::Credentials_;
pub use group::Gid;
pub use user::Uid;
use super::posix_thread::PosixThreadExt;
use crate::prelude::*;
/// `Credentials` represents a set of associated numeric user ids (UIDs) and group identifiers (GIDs)
@ -25,25 +24,3 @@ use crate::prelude::*;
/// - supplementary group IDs;
/// - Linux capabilities.
pub struct Credentials<R = FullOp>(Arc<Credentials_>, R);
/// Gets read-only credentials of current thread.
///
/// # Panics
///
/// This method should only be called in process context.
pub fn credentials() -> Credentials<ReadOp> {
let current_thread = current_thread!();
let posix_thread = current_thread.as_posix_thread().unwrap();
posix_thread.credentials()
}
/// Gets write-only credentials of current thread.
///
/// # Panics
///
/// This method should only be called in process context.
pub fn credentials_mut() -> Credentials<WriteOp> {
let current_thread = current_thread!();
let posix_thread = current_thread.as_posix_thread().unwrap();
posix_thread.credentials_mut()
}

View File

@ -1,7 +1,6 @@
// SPDX-License-Identifier: MPL-2.0
use super::{
credentials,
posix_thread::PosixThreadExt,
process_table,
signal::signals::{user::UserSignal, Signal},
@ -139,10 +138,15 @@ fn kill_process(process: &Process, signal: Option<UserSignal>) -> Result<()> {
}
fn current_thread_sender_ids() -> SignalSenderIds {
let credentials = credentials();
let current_thread = current_thread!();
let current_posix_thread = current_thread.as_posix_thread().unwrap();
let current_process = current_posix_thread.process();
let credentials = current_posix_thread.credentials();
let ruid = credentials.ruid();
let euid = credentials.euid();
let sid = current!().session().unwrap().sid();
let sid = current_process.session().unwrap().sid();
SignalSenderIds::new(ruid, euid, sid)
}

View File

@ -19,7 +19,7 @@ mod term_status;
mod wait;
pub use clone::{clone_child, CloneArgs, CloneFlags};
pub use credentials::{credentials, credentials_mut, Credentials, Gid, Uid};
pub use credentials::{Credentials, Gid, Uid};
pub use exit::do_exit_group;
pub use kill::{kill, kill_all, kill_group, tgkill};
pub use process::{

View File

@ -252,8 +252,16 @@ impl PosixThread {
self.credentials.dup().restrict()
}
/// Gets the write-only credentials of the thread.
pub(in crate::process) fn credentials_mut(&self) -> Credentials<WriteOp> {
/// Gets the write-only credentials of the current thread.
///
/// It is illegal to mutate the credentials from a thread other than the
/// current thread. For performance reasons, this function only checks it
/// using debug assertions.
pub fn credentials_mut(&self) -> Credentials<WriteOp> {
debug_assert!(core::ptr::eq(
current_thread!().as_posix_thread().unwrap(),
self
));
self.credentials.dup().restrict()
}
}

View File

@ -3,16 +3,15 @@
use super::SyscallReturn;
use crate::{
prelude::*,
process::{
credentials,
credentials::c_types::{cap_user_data_t, cap_user_header_t, LINUX_CAPABILITY_VERSION_3},
process::credentials::c_types::{
cap_user_data_t, cap_user_header_t, LINUX_CAPABILITY_VERSION_3,
},
};
pub fn sys_capget(
cap_user_header_addr: Vaddr,
cap_user_data_addr: Vaddr,
_ctx: &Context,
ctx: &Context,
) -> Result<SyscallReturn> {
let user_space = CurrentUserSpace::get();
let cap_user_header: cap_user_header_t =
@ -27,11 +26,11 @@ pub fn sys_capget(
// Capget only query current process's credential. Namely, it only allows header->pid == 0
// or header->pid == getpid(), which are equivalent.
// See https://linux.die.net/man/2/capget (Section. With VFS capability support) for details.
if header_pid != 0 && header_pid != current!().pid() {
if header_pid != 0 && header_pid != ctx.process.pid() {
return_errno_with_message!(Errno::EINVAL, "invalid pid");
}
let credentials = credentials();
let credentials = ctx.posix_thread.credentials();
let inheritable_capset = credentials.inheritable_capset();
let permitted_capset = credentials.permitted_capset();
let effective_capset = credentials.effective_capset();

View File

@ -3,12 +3,9 @@
use super::SyscallReturn;
use crate::{
prelude::*,
process::{
credentials::{
c_types::{cap_user_data_t, cap_user_header_t, LINUX_CAPABILITY_VERSION_3},
capabilities::CapSet,
},
credentials_mut,
process::credentials::{
c_types::{cap_user_data_t, cap_user_header_t, LINUX_CAPABILITY_VERSION_3},
capabilities::CapSet,
},
};
@ -19,7 +16,7 @@ fn make_kernel_cap(low: u32, high: u32) -> u64 {
pub fn sys_capset(
cap_user_header_addr: Vaddr,
cap_user_data_addr: Vaddr,
_ctx: &Context,
ctx: &Context,
) -> Result<SyscallReturn> {
let user_space = CurrentUserSpace::get();
let cap_user_header: cap_user_header_t =
@ -32,7 +29,7 @@ pub fn sys_capset(
// The ability to set capabilities of any other process has been deprecated.
// See: https://elixir.bootlin.com/linux/v6.9.3/source/kernel/capability.c#L209 for more details.
let header_pid = cap_user_header.pid;
if header_pid != 0 && header_pid != current!().pid() {
if header_pid != 0 && header_pid != ctx.process.pid() {
return_errno_with_message!(Errno::EINVAL, "invalid pid");
}
@ -43,7 +40,7 @@ pub fn sys_capset(
let permitted = make_kernel_cap(cap_user_data.permitted, 0);
let effective = make_kernel_cap(cap_user_data.effective, 0);
let credentials = credentials_mut();
let credentials = ctx.posix_thread.credentials_mut();
credentials.set_inheritable_capset(CapSet::from_bits_truncate(inheritable));
credentials.set_permitted_capset(CapSet::from_bits_truncate(permitted));

View File

@ -14,8 +14,8 @@ use crate::{
},
prelude::*,
process::{
check_executable_file, credentials_mut, load_program_to_vm, posix_thread::ThreadName,
Credentials, Process, MAX_ARGV_NUMBER, MAX_ARG_LEN, MAX_ENVP_NUMBER, MAX_ENV_LEN,
check_executable_file, load_program_to_vm, posix_thread::ThreadName, Credentials, Process,
MAX_ARGV_NUMBER, MAX_ARG_LEN, MAX_ENVP_NUMBER, MAX_ENV_LEN,
},
};
@ -123,7 +123,7 @@ fn do_execve(
*posix_thread.robust_list().lock() = None;
debug!("load elf in execve succeeds");
let credentials = credentials_mut();
let credentials = ctx.posix_thread.credentials_mut();
set_uid_from_elf(process, &credentials, &elf_file)?;
set_gid_from_elf(process, &credentials, &elf_file)?;

View File

@ -1,13 +1,10 @@
// SPDX-License-Identifier: MPL-2.0
use super::SyscallReturn;
use crate::{prelude::*, process::credentials};
use crate::prelude::*;
pub fn sys_getegid(_ctx: &Context) -> Result<SyscallReturn> {
let egid = {
let credentials = credentials();
credentials.egid()
};
pub fn sys_getegid(ctx: &Context) -> Result<SyscallReturn> {
let egid = ctx.posix_thread.credentials().egid();
Ok(SyscallReturn::Return(egid.as_u32() as _))
}

View File

@ -1,13 +1,10 @@
// SPDX-License-Identifier: MPL-2.0
use super::SyscallReturn;
use crate::{prelude::*, process::credentials};
use crate::prelude::*;
pub fn sys_geteuid(_ctx: &Context) -> Result<SyscallReturn> {
let euid = {
let credentials = credentials();
credentials.euid()
};
pub fn sys_geteuid(ctx: &Context) -> Result<SyscallReturn> {
let euid = ctx.posix_thread.credentials().euid();
Ok(SyscallReturn::Return(euid.as_u32() as _))
}

View File

@ -1,13 +1,10 @@
// SPDX-License-Identifier: MPL-2.0
use super::SyscallReturn;
use crate::{prelude::*, process::credentials};
use crate::prelude::*;
pub fn sys_getgid(_ctx: &Context) -> Result<SyscallReturn> {
let gid = {
let credentials = credentials();
credentials.rgid()
};
pub fn sys_getgid(ctx: &Context) -> Result<SyscallReturn> {
let gid = ctx.posix_thread.credentials().rgid();
Ok(SyscallReturn::Return(gid.as_u32() as _))
}

View File

@ -1,16 +1,16 @@
// SPDX-License-Identifier: MPL-2.0
use super::SyscallReturn;
use crate::{prelude::*, process::credentials};
use crate::prelude::*;
pub fn sys_getgroups(size: i32, group_list_addr: Vaddr, _ctx: &Context) -> Result<SyscallReturn> {
pub fn sys_getgroups(size: i32, group_list_addr: Vaddr, ctx: &Context) -> Result<SyscallReturn> {
debug!("size = {}, group_list_addr = 0x{:x}", size, group_list_addr);
if size < 0 {
return_errno_with_message!(Errno::EINVAL, "size cannot be negative");
}
let credentials = credentials();
let credentials = ctx.posix_thread.credentials();
let groups = credentials.groups();
if size == 0 {

View File

@ -1,17 +1,17 @@
// SPDX-License-Identifier: MPL-2.0
use super::SyscallReturn;
use crate::{prelude::*, process::credentials};
use crate::prelude::*;
pub fn sys_getresgid(
rgid_ptr: Vaddr,
egid_ptr: Vaddr,
sgid_ptr: Vaddr,
_ctx: &Context,
ctx: &Context,
) -> Result<SyscallReturn> {
debug!("rgid_ptr = 0x{rgid_ptr:x}, egid_ptr = 0x{egid_ptr:x}, sgid_ptr = 0x{sgid_ptr:x}");
let credentials = credentials();
let credentials = ctx.posix_thread.credentials();
let user_space = CurrentUserSpace::get();
let rgid = credentials.rgid();

View File

@ -1,17 +1,17 @@
// SPDX-License-Identifier: MPL-2.0
use super::SyscallReturn;
use crate::{prelude::*, process::credentials};
use crate::prelude::*;
pub fn sys_getresuid(
ruid_ptr: Vaddr,
euid_ptr: Vaddr,
suid_ptr: Vaddr,
_ctx: &Context,
ctx: &Context,
) -> Result<SyscallReturn> {
debug!("ruid_ptr = 0x{ruid_ptr:x}, euid_ptr = 0x{euid_ptr:x}, suid_ptr = 0x{suid_ptr:x}");
let credentials = credentials();
let credentials = ctx.posix_thread.credentials();
let user_space = CurrentUserSpace::get();
let ruid = credentials.ruid();

View File

@ -1,13 +1,10 @@
// SPDX-License-Identifier: MPL-2.0
use super::SyscallReturn;
use crate::{prelude::*, process::credentials};
use crate::prelude::*;
pub fn sys_getuid(_ctx: &Context) -> Result<SyscallReturn> {
let uid = {
let credentials = credentials();
credentials.ruid()
};
pub fn sys_getuid(ctx: &Context) -> Result<SyscallReturn> {
let uid = ctx.posix_thread.credentials().ruid();
Ok(SyscallReturn::Return(uid.as_u32() as _))
}

View File

@ -4,7 +4,7 @@ use super::SyscallReturn;
use crate::{
prelude::*,
process::{
credentials, kill, kill_all, kill_group,
kill, kill_all, kill_group,
signal::{
sig_num::SigNum,
signals::user::{UserSignal, UserSignalKind},
@ -13,7 +13,7 @@ use crate::{
},
};
pub fn sys_kill(process_filter: u64, sig_num: u64, _ctx: &Context) -> Result<SyscallReturn> {
pub fn sys_kill(process_filter: u64, sig_num: u64, ctx: &Context) -> Result<SyscallReturn> {
let process_filter = ProcessFilter::from_id(process_filter as _);
let sig_num = if sig_num == 0 {
None
@ -24,16 +24,16 @@ pub fn sys_kill(process_filter: u64, sig_num: u64, _ctx: &Context) -> Result<Sys
"process_filter = {:?}, sig_num = {:?}",
process_filter, sig_num
);
do_sys_kill(process_filter, sig_num)?;
do_sys_kill(process_filter, sig_num, ctx)?;
Ok(SyscallReturn::Return(0))
}
pub fn do_sys_kill(filter: ProcessFilter, sig_num: Option<SigNum>) -> Result<()> {
pub fn do_sys_kill(filter: ProcessFilter, sig_num: Option<SigNum>, ctx: &Context) -> Result<()> {
let current = current!();
let signal = sig_num.map(|sig_num| {
let pid = current.pid();
let uid = credentials().ruid();
let uid = ctx.posix_thread.credentials().ruid();
UserSignal::new(sig_num, UserSignalKind::Kill, pid, uid)
});

View File

@ -5,7 +5,7 @@ use core::sync::atomic::Ordering;
use super::SyscallReturn;
use crate::{
prelude::*,
process::{credentials, posix_thread::PosixThreadExt, process_table, Pgid, Pid, Process, Uid},
process::{posix_thread::PosixThreadExt, process_table, Pgid, Pid, Process, Uid},
sched::nice::Nice,
};
@ -120,7 +120,11 @@ impl PriorityTarget {
}
Which::PRIO_USER => {
let uid = if who == 0 {
credentials().ruid()
current_thread!()
.as_posix_thread()
.unwrap()
.credentials()
.ruid()
} else {
Uid::new(who)
};

View File

@ -1,12 +1,9 @@
// SPDX-License-Identifier: MPL-2.0
use super::SyscallReturn;
use crate::{
prelude::*,
process::{credentials_mut, Gid},
};
use crate::{prelude::*, process::Gid};
pub fn sys_setfsgid(gid: i32, _ctx: &Context) -> Result<SyscallReturn> {
pub fn sys_setfsgid(gid: i32, ctx: &Context) -> Result<SyscallReturn> {
debug!("gid = {}", gid);
let fsgid = if gid < 0 {
@ -16,7 +13,7 @@ pub fn sys_setfsgid(gid: i32, _ctx: &Context) -> Result<SyscallReturn> {
};
let old_fsgid = {
let credentials = credentials_mut();
let credentials = ctx.posix_thread.credentials_mut();
credentials.set_fsgid(fsgid)?
};

View File

@ -1,12 +1,9 @@
// SPDX-License-Identifier: MPL-2.0
use super::SyscallReturn;
use crate::{
prelude::*,
process::{credentials_mut, Uid},
};
use crate::{prelude::*, process::Uid};
pub fn sys_setfsuid(uid: i32, _ctx: &Context) -> Result<SyscallReturn> {
pub fn sys_setfsuid(uid: i32, ctx: &Context) -> Result<SyscallReturn> {
debug!("uid = {}", uid);
let fsuid = if uid < 0 {
@ -16,7 +13,7 @@ pub fn sys_setfsuid(uid: i32, _ctx: &Context) -> Result<SyscallReturn> {
};
let old_fsuid = {
let credentials = credentials_mut();
let credentials = ctx.posix_thread.credentials_mut();
credentials.set_fsuid(fsuid)?
};

View File

@ -1,12 +1,9 @@
// SPDX-License-Identifier: MPL-2.0
use super::SyscallReturn;
use crate::{
prelude::*,
process::{credentials_mut, Gid},
};
use crate::{prelude::*, process::Gid};
pub fn sys_setgid(gid: i32, _ctx: &Context) -> Result<SyscallReturn> {
pub fn sys_setgid(gid: i32, ctx: &Context) -> Result<SyscallReturn> {
debug!("gid = {}", gid);
if gid < 0 {
@ -15,7 +12,7 @@ pub fn sys_setgid(gid: i32, _ctx: &Context) -> Result<SyscallReturn> {
let gid = Gid::new(gid as u32);
let credentials = credentials_mut();
let credentials = ctx.posix_thread.credentials_mut();
credentials.set_gid(gid);
Ok(SyscallReturn::Return(0))

View File

@ -1,12 +1,9 @@
// SPDX-License-Identifier: MPL-2.0
use super::SyscallReturn;
use crate::{
prelude::*,
process::{credentials_mut, Gid},
};
use crate::{prelude::*, process::Gid};
pub fn sys_setgroups(size: usize, group_list_addr: Vaddr, _ctx: &Context) -> Result<SyscallReturn> {
pub fn sys_setgroups(size: usize, group_list_addr: Vaddr, ctx: &Context) -> Result<SyscallReturn> {
debug!("size = {}, group_list_addr = 0x{:x}", size, group_list_addr);
// TODO: check perm: the calling process should have the CAP_SETGID capability
@ -22,7 +19,7 @@ pub fn sys_setgroups(size: usize, group_list_addr: Vaddr, _ctx: &Context) -> Res
new_groups.insert(gid);
}
let credentials = credentials_mut();
let credentials = ctx.posix_thread.credentials_mut();
*credentials.groups_mut() = new_groups;
Ok(SyscallReturn::Return(0))

View File

@ -1,12 +1,9 @@
// SPDX-License-Identifier: MPL-2.0
use super::SyscallReturn;
use crate::{
prelude::*,
process::{credentials_mut, Gid},
};
use crate::{prelude::*, process::Gid};
pub fn sys_setregid(rgid: i32, egid: i32, _ctx: &Context) -> Result<SyscallReturn> {
pub fn sys_setregid(rgid: i32, egid: i32, ctx: &Context) -> Result<SyscallReturn> {
debug!("rgid = {}, egid = {}", rgid, egid);
let rgid = if rgid > 0 {
@ -21,7 +18,7 @@ pub fn sys_setregid(rgid: i32, egid: i32, _ctx: &Context) -> Result<SyscallRetur
None
};
let credentials = credentials_mut();
let credentials = ctx.posix_thread.credentials_mut();
credentials.set_regid(rgid, egid)?;
Ok(SyscallReturn::Return(0))

View File

@ -1,12 +1,9 @@
// SPDX-License-Identifier: MPL-2.0
use super::SyscallReturn;
use crate::{
prelude::*,
process::{credentials_mut, Gid},
};
use crate::{prelude::*, process::Gid};
pub fn sys_setresgid(rgid: i32, egid: i32, sgid: i32, _ctx: &Context) -> Result<SyscallReturn> {
pub fn sys_setresgid(rgid: i32, egid: i32, sgid: i32, ctx: &Context) -> Result<SyscallReturn> {
let rgid = if rgid > 0 {
Some(Gid::new(rgid as u32))
} else {
@ -27,7 +24,7 @@ pub fn sys_setresgid(rgid: i32, egid: i32, sgid: i32, _ctx: &Context) -> Result<
debug!("rgid = {:?}, egid = {:?}, sgid = {:?}", rgid, egid, sgid);
let credentials = credentials_mut();
let credentials = ctx.posix_thread.credentials_mut();
credentials.set_resgid(rgid, egid, sgid)?;
Ok(SyscallReturn::Return(0))

View File

@ -1,12 +1,9 @@
// SPDX-License-Identifier: MPL-2.0
use super::SyscallReturn;
use crate::{
prelude::*,
process::{credentials_mut, Uid},
};
use crate::{prelude::*, process::Uid};
pub fn sys_setresuid(ruid: i32, euid: i32, suid: i32, _ctx: &Context) -> Result<SyscallReturn> {
pub fn sys_setresuid(ruid: i32, euid: i32, suid: i32, ctx: &Context) -> Result<SyscallReturn> {
let ruid = if ruid > 0 {
Some(Uid::new(ruid as u32))
} else {
@ -27,7 +24,7 @@ pub fn sys_setresuid(ruid: i32, euid: i32, suid: i32, _ctx: &Context) -> Result<
debug!("ruid = {:?}, euid = {:?}, suid = {:?}", ruid, euid, suid);
let credentials = credentials_mut();
let credentials = ctx.posix_thread.credentials_mut();
credentials.set_resuid(ruid, euid, suid)?;

View File

@ -1,12 +1,9 @@
// SPDX-License-Identifier: MPL-2.0
use super::SyscallReturn;
use crate::{
prelude::*,
process::{credentials_mut, Uid},
};
use crate::{prelude::*, process::Uid};
pub fn sys_setreuid(ruid: i32, euid: i32, _ctx: &Context) -> Result<SyscallReturn> {
pub fn sys_setreuid(ruid: i32, euid: i32, ctx: &Context) -> Result<SyscallReturn> {
debug!("ruid = {}, euid = {}", ruid, euid);
let ruid = if ruid > 0 {
@ -21,7 +18,7 @@ pub fn sys_setreuid(ruid: i32, euid: i32, _ctx: &Context) -> Result<SyscallRetur
None
};
let credentials = credentials_mut();
let credentials = ctx.posix_thread.credentials_mut();
credentials.set_reuid(ruid, euid)?;
Ok(SyscallReturn::Return(0))

View File

@ -1,12 +1,9 @@
// SPDX-License-Identifier: MPL-2.0
use super::SyscallReturn;
use crate::{
prelude::*,
process::{credentials_mut, Uid},
};
use crate::{prelude::*, process::Uid};
pub fn sys_setuid(uid: i32, _ctx: &Context) -> Result<SyscallReturn> {
pub fn sys_setuid(uid: i32, ctx: &Context) -> Result<SyscallReturn> {
debug!("uid = {}", uid);
if uid < 0 {
@ -15,7 +12,7 @@ pub fn sys_setuid(uid: i32, _ctx: &Context) -> Result<SyscallReturn> {
let uid = Uid::new(uid as u32);
let credentials = credentials_mut();
let credentials = ctx.posix_thread.credentials_mut();
credentials.set_uid(uid);
Ok(SyscallReturn::Return(0))

View File

@ -4,7 +4,6 @@ use super::SyscallReturn;
use crate::{
prelude::*,
process::{
credentials,
signal::{
sig_num::SigNum,
signals::user::{UserSignal, UserSignalKind},
@ -15,7 +14,7 @@ use crate::{
};
/// tgkill send a signal to a thread with pid as its thread id, and tgid as its thread group id.
pub fn sys_tgkill(tgid: Pid, tid: Tid, sig_num: u8, _ctx: &Context) -> Result<SyscallReturn> {
pub fn sys_tgkill(tgid: Pid, tid: Tid, sig_num: u8, ctx: &Context) -> Result<SyscallReturn> {
let sig_num = if sig_num == 0 {
None
} else {
@ -26,7 +25,7 @@ pub fn sys_tgkill(tgid: Pid, tid: Tid, sig_num: u8, _ctx: &Context) -> Result<Sy
let signal = sig_num.map(|sig_num| {
let pid = current!().pid();
let uid = credentials().ruid();
let uid = ctx.posix_thread.credentials().ruid();
UserSignal::new(sig_num, UserSignalKind::Tkill, pid, uid)
});
tgkill(tid, tgid, signal)?;