Add credential-related syscalls
This commit is contained in:
parent
c99e6b4ced
commit
90be8038e0
|
|
@ -1,7 +1,7 @@
|
|||
use super::posix_thread::{PosixThread, PosixThreadBuilder, PosixThreadExt, ThreadName};
|
||||
use super::process_vm::ProcessVm;
|
||||
use super::signal::sig_disposition::SigDispositions;
|
||||
use super::{process_table, Process, ProcessBuilder};
|
||||
use super::{credentials, process_table, Credentials, Process, ProcessBuilder};
|
||||
use crate::current_thread;
|
||||
use crate::fs::file_table::FileTable;
|
||||
use crate::fs::fs_resolver::FsResolver;
|
||||
|
|
@ -176,7 +176,13 @@ fn clone_child_thread(parent_context: UserContext, clone_args: CloneArgs) -> Res
|
|||
let child_tid = allocate_tid();
|
||||
let child_thread = {
|
||||
let is_main_thread = child_tid == current.pid();
|
||||
let thread_builder = PosixThreadBuilder::new(child_tid, child_user_space)
|
||||
|
||||
let credentials = {
|
||||
let credentials = credentials();
|
||||
Credentials::new_from(&credentials)
|
||||
};
|
||||
|
||||
let thread_builder = PosixThreadBuilder::new(child_tid, child_user_space, credentials)
|
||||
.process(Arc::downgrade(¤t))
|
||||
.sig_mask(sig_mask)
|
||||
.is_main_thread(is_main_thread);
|
||||
|
|
@ -255,7 +261,13 @@ fn clone_child_process(parent_context: UserContext, clone_args: CloneArgs) -> Re
|
|||
let child_elf_path = current.executable_path();
|
||||
let child_thread_builder = {
|
||||
let child_thread_name = ThreadName::new_from_executable_path(&child_elf_path)?;
|
||||
PosixThreadBuilder::new(child_tid, child_user_space)
|
||||
|
||||
let credentials = {
|
||||
let credentials = credentials();
|
||||
Credentials::new_from(&credentials)
|
||||
};
|
||||
|
||||
PosixThreadBuilder::new(child_tid, child_user_space, credentials)
|
||||
.thread_name(Some(child_thread_name))
|
||||
.sig_mask(child_sig_mask)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use crate::{
|
|||
process::{
|
||||
posix_thread::name::ThreadName,
|
||||
signal::{sig_mask::SigMask, sig_queues::SigQueues},
|
||||
Process,
|
||||
Credentials, Process,
|
||||
},
|
||||
thread::{status::ThreadStatus, task::create_new_user_task, thread_table, Thread, Tid},
|
||||
};
|
||||
|
|
@ -18,6 +18,7 @@ pub struct PosixThreadBuilder {
|
|||
tid: Tid,
|
||||
user_space: Arc<UserSpace>,
|
||||
process: Weak<Process>,
|
||||
credentials: Credentials,
|
||||
|
||||
// Optional part
|
||||
thread_name: Option<ThreadName>,
|
||||
|
|
@ -29,11 +30,12 @@ pub struct PosixThreadBuilder {
|
|||
}
|
||||
|
||||
impl PosixThreadBuilder {
|
||||
pub fn new(tid: Tid, user_space: Arc<UserSpace>) -> Self {
|
||||
pub fn new(tid: Tid, user_space: Arc<UserSpace>, credentials: Credentials) -> Self {
|
||||
Self {
|
||||
tid,
|
||||
user_space,
|
||||
process: Weak::new(),
|
||||
credentials,
|
||||
thread_name: None,
|
||||
set_child_tid: 0,
|
||||
clear_child_tid: 0,
|
||||
|
|
@ -79,6 +81,7 @@ impl PosixThreadBuilder {
|
|||
tid,
|
||||
user_space,
|
||||
process,
|
||||
credentials,
|
||||
thread_name,
|
||||
set_child_tid,
|
||||
clear_child_tid,
|
||||
|
|
@ -96,6 +99,7 @@ impl PosixThreadBuilder {
|
|||
name: Mutex::new(thread_name),
|
||||
set_child_tid: Mutex::new(set_child_tid),
|
||||
clear_child_tid: Mutex::new(clear_child_tid),
|
||||
credentials,
|
||||
sig_mask: Mutex::new(sig_mask),
|
||||
sig_queues: Mutex::new(sig_queues),
|
||||
sig_context,
|
||||
|
|
|
|||
|
|
@ -1,21 +1,18 @@
|
|||
use crate::{
|
||||
events::Observer,
|
||||
prelude::*,
|
||||
process::{
|
||||
do_exit_group,
|
||||
posix_thread::{futex::futex_wake, robust_list::wake_robust_futex},
|
||||
TermStatus,
|
||||
},
|
||||
thread::{thread_table, Tid},
|
||||
util::write_val_to_user,
|
||||
};
|
||||
|
||||
use super::{
|
||||
signal::{
|
||||
sig_mask::SigMask, sig_queues::SigQueues, signals::Signal, SigEvents, SigEventsFilter,
|
||||
},
|
||||
Process,
|
||||
};
|
||||
use super::kill::SignalSenderIds;
|
||||
use super::signal::sig_mask::SigMask;
|
||||
use super::signal::sig_num::SigNum;
|
||||
use super::signal::sig_queues::SigQueues;
|
||||
use super::signal::signals::Signal;
|
||||
use super::signal::{SigEvents, SigEventsFilter};
|
||||
use super::{do_exit_group, Credentials, Process, TermStatus};
|
||||
use crate::events::Observer;
|
||||
use crate::prelude::*;
|
||||
use crate::process::signal::constants::SIGCONT;
|
||||
use crate::thread::{thread_table, Tid};
|
||||
use crate::util::write_val_to_user;
|
||||
use futex::futex_wake;
|
||||
use jinux_rights::{ReadOp, WriteOp};
|
||||
use robust_list::wake_robust_futex;
|
||||
|
||||
mod builder;
|
||||
pub mod futex;
|
||||
|
|
@ -43,6 +40,9 @@ pub struct PosixThread {
|
|||
|
||||
robust_list: Mutex<Option<RobustListHead>>,
|
||||
|
||||
/// Process credentials. At the kernel level, credentials are a per-thread attribute.
|
||||
credentials: Credentials,
|
||||
|
||||
// signal
|
||||
/// blocked signals
|
||||
sig_mask: Mutex<SigMask>,
|
||||
|
|
@ -78,7 +78,57 @@ impl PosixThread {
|
|||
!self.sig_queues.lock().is_empty()
|
||||
}
|
||||
|
||||
pub fn enqueue_signal(&self, signal: Box<dyn Signal>) {
|
||||
/// Returns whether the signal is blocked by the thread.
|
||||
pub(in crate::process) fn has_signal_blocked(&self, signal: &dyn Signal) -> bool {
|
||||
let mask = self.sig_mask.lock();
|
||||
mask.contains(signal.num())
|
||||
}
|
||||
|
||||
/// Checks whether the signal can be delivered to the thread.
|
||||
///
|
||||
/// For a signal can be delivered to the thread, the sending thread must either
|
||||
/// be privileged, or the real or effective user ID of the sending thread must equal
|
||||
/// the real or saved set-user-ID of the target thread.
|
||||
///
|
||||
/// For SIGCONT, the sending and receiving processes should belong to the same session.
|
||||
pub(in crate::process) fn check_signal_perm(
|
||||
&self,
|
||||
signum: Option<&SigNum>,
|
||||
sender: &SignalSenderIds,
|
||||
) -> Result<()> {
|
||||
if sender.euid().is_root() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if let Some(signum) = signum && *signum == SIGCONT {
|
||||
let receiver_sid = self.process().session().unwrap().sid();
|
||||
if receiver_sid == sender.sid() {
|
||||
return Ok(())
|
||||
} else {
|
||||
return_errno_with_message!(Errno::EPERM, "sigcont requires that sender and receiver belongs to the same session");
|
||||
}
|
||||
}
|
||||
|
||||
let (receiver_ruid, receiver_suid) = {
|
||||
let credentials = self.credentials();
|
||||
(credentials.ruid(), credentials.suid())
|
||||
};
|
||||
|
||||
// FIXME: further check the below code to ensure the behavior is same as Linux. According
|
||||
// to man(2) kill, the real or effective user ID of the sending process must equal the
|
||||
// real or saved set-user-ID of the target process.
|
||||
if sender.ruid() == receiver_ruid
|
||||
|| sender.ruid() == receiver_suid
|
||||
|| sender.euid() == receiver_ruid
|
||||
|| sender.euid() == receiver_suid
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
return_errno_with_message!(Errno::EPERM, "sending signal to the thread is not allowed.");
|
||||
}
|
||||
|
||||
pub(in crate::process) fn enqueue_signal(&self, signal: Box<dyn Signal>) {
|
||||
self.sig_queues.lock().enqueue(signal);
|
||||
}
|
||||
|
||||
|
|
@ -177,4 +227,14 @@ impl PosixThread {
|
|||
futex_wake(Arc::as_ptr(&self.process()) as Vaddr, 1)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Gets the read-only credentials of the thread.
|
||||
pub(in crate::process) fn credentials(&self) -> Credentials<ReadOp> {
|
||||
self.credentials.dup().restrict()
|
||||
}
|
||||
|
||||
/// Gets the write-only credentials of the thread.
|
||||
pub(in crate::process) fn credentials_mut(&self) -> Credentials<WriteOp> {
|
||||
self.credentials.dup().restrict()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,15 +3,17 @@ use jinux_frame::{cpu::UserContext, user::UserSpace};
|
|||
use crate::{
|
||||
fs::fs_resolver::{FsPath, FsResolver, AT_FDCWD},
|
||||
prelude::*,
|
||||
process::{process_vm::ProcessVm, program_loader::load_program_to_vm, Process},
|
||||
process::{process_vm::ProcessVm, program_loader::load_program_to_vm, Credentials, Process},
|
||||
thread::{Thread, Tid},
|
||||
};
|
||||
|
||||
use super::{builder::PosixThreadBuilder, name::ThreadName, PosixThread};
|
||||
pub trait PosixThreadExt {
|
||||
fn as_posix_thread(&self) -> Option<&PosixThread>;
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn new_posix_thread_from_executable(
|
||||
tid: Tid,
|
||||
credentials: Credentials,
|
||||
process_vm: &ProcessVm,
|
||||
fs_resolver: &FsResolver,
|
||||
executable_path: &str,
|
||||
|
|
@ -25,6 +27,7 @@ impl PosixThreadExt for Thread {
|
|||
/// This function should only be called when launch shell()
|
||||
fn new_posix_thread_from_executable(
|
||||
tid: Tid,
|
||||
credentials: Credentials,
|
||||
process_vm: &ProcessVm,
|
||||
fs_resolver: &FsResolver,
|
||||
executable_path: &str,
|
||||
|
|
@ -45,7 +48,7 @@ impl PosixThreadExt for Thread {
|
|||
cpu_ctx.set_rsp(elf_load_info.user_stack_top() as _);
|
||||
let user_space = Arc::new(UserSpace::new(vm_space, cpu_ctx));
|
||||
let thread_name = Some(ThreadName::new_from_executable_path(executable_path)?);
|
||||
let thread_builder = PosixThreadBuilder::new(tid, user_space)
|
||||
let thread_builder = PosixThreadBuilder::new(tid, user_space, credentials)
|
||||
.thread_name(thread_name)
|
||||
.process(process);
|
||||
Ok(thread_builder.build())
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use jinux_frame::cpu::UserContext;
|
||||
use jinux_rights::WriteOp;
|
||||
|
||||
use super::{constants::*, SyscallReturn};
|
||||
use crate::fs::file_table::FileDescripter;
|
||||
|
|
@ -7,7 +8,9 @@ use crate::fs::utils::{Dentry, InodeType};
|
|||
use crate::log_syscall_entry;
|
||||
use crate::prelude::*;
|
||||
use crate::process::posix_thread::{PosixThreadExt, ThreadName};
|
||||
use crate::process::{check_executable_file, load_program_to_vm};
|
||||
use crate::process::{
|
||||
check_executable_file, credentials_mut, load_program_to_vm, Credentials, Gid, Uid,
|
||||
};
|
||||
use crate::syscall::{SYS_EXECVE, SYS_EXECVEAT};
|
||||
use crate::util::{read_cstring_from_user, read_val_from_user};
|
||||
|
||||
|
|
@ -100,9 +103,14 @@ fn do_execve(
|
|||
let (new_executable_path, elf_load_info) = {
|
||||
let fs_resolver = &*current.fs().read();
|
||||
let process_vm = current.vm();
|
||||
load_program_to_vm(process_vm, elf_file, argv, envp, fs_resolver, 1)?
|
||||
load_program_to_vm(process_vm, elf_file.clone(), argv, envp, fs_resolver, 1)?
|
||||
};
|
||||
debug!("load elf in execve succeeds");
|
||||
|
||||
let credentials = credentials_mut();
|
||||
set_uid_from_elf(&credentials, &elf_file);
|
||||
set_gid_from_elf(&credentials, &elf_file);
|
||||
|
||||
// set executable path
|
||||
current.set_executable_path(new_executable_path);
|
||||
// set signal disposition to default
|
||||
|
|
@ -157,3 +165,25 @@ fn read_cstring_vec(
|
|||
}
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
/// Sets uid for credentials as the same of uid of elf file if elf file has `set_uid` bit.
|
||||
fn set_uid_from_elf(credentials: &Credentials<WriteOp>, elf_file: &Arc<Dentry>) {
|
||||
if elf_file.inode_mode().has_set_uid() {
|
||||
let uid = Uid::new(elf_file.inode_metadata().uid as u32);
|
||||
credentials.set_euid(uid);
|
||||
}
|
||||
|
||||
// No matter whether the elf_file has `set_uid` bit, suid should be reset.
|
||||
credentials.reset_suid();
|
||||
}
|
||||
|
||||
/// Sets gid for credentials as the same of gid of elf file if elf file has `set_gid` bit.
|
||||
fn set_gid_from_elf(credentials: &Credentials<WriteOp>, elf_file: &Arc<Dentry>) {
|
||||
if elf_file.inode_mode().has_set_gid() {
|
||||
let gid = Gid::new(elf_file.inode_metadata().gid as u32);
|
||||
credentials.set_egid(gid);
|
||||
}
|
||||
|
||||
// No matter whether the the elf file has `set_gid` bit, sgid should be reset.
|
||||
credentials.reset_sgid();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,16 @@
|
|||
use crate::{log_syscall_entry, prelude::*, syscall::SYS_GETEGID};
|
||||
use crate::log_syscall_entry;
|
||||
use crate::prelude::*;
|
||||
use crate::process::credentials;
|
||||
|
||||
use super::SyscallReturn;
|
||||
use super::{SyscallReturn, SYS_GETEGID};
|
||||
|
||||
pub fn sys_getegid() -> Result<SyscallReturn> {
|
||||
log_syscall_entry!(SYS_GETEGID);
|
||||
// TODO: getegid only return a fake egid now
|
||||
Ok(SyscallReturn::Return(0))
|
||||
|
||||
let egid = {
|
||||
let credentials = credentials();
|
||||
credentials.egid()
|
||||
};
|
||||
|
||||
Ok(SyscallReturn::Return(egid.as_u32() as _))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
use crate::{log_syscall_entry, prelude::*, syscall::SYS_GETEUID};
|
||||
|
||||
use super::SyscallReturn;
|
||||
use super::{SyscallReturn, SYS_GETEUID};
|
||||
use crate::log_syscall_entry;
|
||||
use crate::prelude::*;
|
||||
use crate::process::credentials;
|
||||
|
||||
pub fn sys_geteuid() -> Result<SyscallReturn> {
|
||||
log_syscall_entry!(SYS_GETEUID);
|
||||
// TODO: geteuid only return a fake euid now"
|
||||
Ok(SyscallReturn::Return(0))
|
||||
|
||||
let euid = {
|
||||
let credentials = credentials();
|
||||
credentials.euid()
|
||||
};
|
||||
|
||||
Ok(SyscallReturn::Return(euid.as_u32() as _))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
use crate::{log_syscall_entry, prelude::*, syscall::SYS_GETGID};
|
||||
|
||||
use super::SyscallReturn;
|
||||
use super::{SyscallReturn, SYS_GETGID};
|
||||
use crate::log_syscall_entry;
|
||||
use crate::prelude::*;
|
||||
use crate::process::credentials;
|
||||
|
||||
pub fn sys_getgid() -> Result<SyscallReturn> {
|
||||
log_syscall_entry!(SYS_GETGID);
|
||||
// TODO: getgid only return a fake gid now"
|
||||
Ok(SyscallReturn::Return(0))
|
||||
|
||||
let gid = {
|
||||
let credentials = credentials();
|
||||
credentials.rgid()
|
||||
};
|
||||
|
||||
Ok(SyscallReturn::Return(gid.as_u32() as _))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
use super::{SyscallReturn, SYS_GETGROUPS};
|
||||
use crate::log_syscall_entry;
|
||||
use crate::prelude::*;
|
||||
use crate::process::credentials;
|
||||
use crate::util::write_val_to_user;
|
||||
|
||||
pub fn sys_getgroups(size: i32, group_list_addr: Vaddr) -> Result<SyscallReturn> {
|
||||
log_syscall_entry!(SYS_GETGROUPS);
|
||||
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 groups = credentials.groups();
|
||||
|
||||
if size == 0 {
|
||||
return Ok(SyscallReturn::Return(groups.len() as _));
|
||||
}
|
||||
|
||||
if groups.len() > size as usize {
|
||||
return_errno_with_message!(
|
||||
Errno::EINVAL,
|
||||
"size is less than the number of supplementary group IDs"
|
||||
);
|
||||
}
|
||||
|
||||
for (idx, gid) in groups.iter().enumerate() {
|
||||
let addr = group_list_addr + idx * core::mem::size_of_val(gid);
|
||||
write_val_to_user(addr, gid)?;
|
||||
}
|
||||
|
||||
Ok(SyscallReturn::Return(groups.len() as _))
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
use super::{SyscallReturn, SYS_GETRESGID};
|
||||
use crate::log_syscall_entry;
|
||||
use crate::prelude::*;
|
||||
use crate::process::credentials;
|
||||
use crate::util::write_val_to_user;
|
||||
|
||||
pub fn sys_getresgid(rgid_ptr: Vaddr, egid_ptr: Vaddr, sgid_ptr: Vaddr) -> Result<SyscallReturn> {
|
||||
log_syscall_entry!(SYS_GETRESGID);
|
||||
debug!("rgid_ptr = 0x{rgid_ptr:x}, egid_ptr = 0x{egid_ptr:x}, sgid_ptr = 0x{sgid_ptr:x}");
|
||||
|
||||
let credentials = credentials();
|
||||
|
||||
let rgid = credentials.rgid();
|
||||
write_val_to_user(rgid_ptr, &rgid)?;
|
||||
|
||||
let egid = credentials.egid();
|
||||
write_val_to_user(egid_ptr, &egid)?;
|
||||
|
||||
let sgid = credentials.sgid();
|
||||
write_val_to_user(sgid_ptr, &sgid)?;
|
||||
|
||||
Ok(SyscallReturn::Return(0))
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
use super::{SyscallReturn, SYS_GETRESUID};
|
||||
use crate::log_syscall_entry;
|
||||
use crate::prelude::*;
|
||||
use crate::process::credentials;
|
||||
use crate::util::write_val_to_user;
|
||||
|
||||
pub fn sys_getresuid(ruid_ptr: Vaddr, euid_ptr: Vaddr, suid_ptr: Vaddr) -> Result<SyscallReturn> {
|
||||
log_syscall_entry!(SYS_GETRESUID);
|
||||
debug!("ruid_ptr = 0x{ruid_ptr:x}, euid_ptr = 0x{euid_ptr:x}, suid_ptr = 0x{suid_ptr:x}");
|
||||
|
||||
let credentials = credentials();
|
||||
|
||||
let ruid = credentials.ruid();
|
||||
write_val_to_user(ruid_ptr, &ruid)?;
|
||||
|
||||
let euid = credentials.euid();
|
||||
write_val_to_user(euid_ptr, &euid)?;
|
||||
|
||||
let suid = credentials.suid();
|
||||
write_val_to_user(suid_ptr, &suid)?;
|
||||
|
||||
Ok(SyscallReturn::Return(0))
|
||||
}
|
||||
|
|
@ -1,9 +1,15 @@
|
|||
use crate::{log_syscall_entry, prelude::*, syscall::SYS_GETUID};
|
||||
|
||||
use super::SyscallReturn;
|
||||
use super::{SyscallReturn, SYS_GETUID};
|
||||
use crate::log_syscall_entry;
|
||||
use crate::prelude::*;
|
||||
use crate::process::credentials;
|
||||
|
||||
pub fn sys_getuid() -> Result<SyscallReturn> {
|
||||
log_syscall_entry!(SYS_GETUID);
|
||||
// TODO: getuid only return a fake uid now;
|
||||
Ok(SyscallReturn::Return(0))
|
||||
|
||||
let uid = {
|
||||
let credentials = credentials();
|
||||
credentials.ruid()
|
||||
};
|
||||
|
||||
Ok(SyscallReturn::Return(uid.as_u32() as _))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,8 +75,11 @@ use self::accept::sys_accept;
|
|||
use self::bind::sys_bind;
|
||||
use self::connect::sys_connect;
|
||||
use self::execve::sys_execveat;
|
||||
use self::getgroups::sys_getgroups;
|
||||
use self::getpeername::sys_getpeername;
|
||||
use self::getrandom::sys_getrandom;
|
||||
use self::getresgid::sys_getresgid;
|
||||
use self::getresuid::sys_getresuid;
|
||||
use self::getsid::sys_getsid;
|
||||
use self::getsockname::sys_getsockname;
|
||||
use self::getsockopt::sys_getsockopt;
|
||||
|
|
@ -84,8 +87,17 @@ use self::listen::sys_listen;
|
|||
use self::pread64::sys_pread64;
|
||||
use self::recvfrom::sys_recvfrom;
|
||||
use self::sendto::sys_sendto;
|
||||
use self::setfsgid::sys_setfsgid;
|
||||
use self::setfsuid::sys_setfsuid;
|
||||
use self::setgid::sys_setgid;
|
||||
use self::setgroups::sys_setgroups;
|
||||
use self::setregid::sys_setregid;
|
||||
use self::setresgid::sys_setresgid;
|
||||
use self::setresuid::sys_setresuid;
|
||||
use self::setreuid::sys_setreuid;
|
||||
use self::setsid::sys_setsid;
|
||||
use self::setsockopt::sys_setsockopt;
|
||||
use self::setuid::sys_setuid;
|
||||
use self::shutdown::sys_shutdown;
|
||||
use self::socket::sys_socket;
|
||||
use self::socketpair::sys_socketpair;
|
||||
|
|
@ -116,11 +128,14 @@ mod getdents64;
|
|||
mod getegid;
|
||||
mod geteuid;
|
||||
mod getgid;
|
||||
mod getgroups;
|
||||
mod getpeername;
|
||||
mod getpgrp;
|
||||
mod getpid;
|
||||
mod getppid;
|
||||
mod getrandom;
|
||||
mod getresgid;
|
||||
mod getresuid;
|
||||
mod getsid;
|
||||
mod getsockname;
|
||||
mod getsockopt;
|
||||
|
|
@ -157,9 +172,18 @@ mod select;
|
|||
mod sendto;
|
||||
mod set_robust_list;
|
||||
mod set_tid_address;
|
||||
mod setfsgid;
|
||||
mod setfsuid;
|
||||
mod setgid;
|
||||
mod setgroups;
|
||||
mod setpgid;
|
||||
mod setregid;
|
||||
mod setresgid;
|
||||
mod setresuid;
|
||||
mod setreuid;
|
||||
mod setsid;
|
||||
mod setsockopt;
|
||||
mod setuid;
|
||||
mod shutdown;
|
||||
mod socket;
|
||||
mod socketpair;
|
||||
|
|
@ -273,12 +297,24 @@ define_syscall_nums!(
|
|||
SYS_GETTIMEOFDAY = 96,
|
||||
SYS_GETUID = 102,
|
||||
SYS_GETGID = 104,
|
||||
SYS_SETUID = 105,
|
||||
SYS_SETGID = 106,
|
||||
SYS_GETEUID = 107,
|
||||
SYS_GETEGID = 108,
|
||||
SYS_SETPGID = 109,
|
||||
SYS_GETPPID = 110,
|
||||
SYS_GETPGRP = 111,
|
||||
SYS_SETSID = 112,
|
||||
SYS_SETREUID = 113,
|
||||
SYS_SETREGID = 114,
|
||||
SYS_GETGROUPS = 115,
|
||||
SYS_SETGROUPS = 116,
|
||||
SYS_SETRESUID = 117,
|
||||
SYS_GETRESUID = 118,
|
||||
SYS_SETRESGID = 119,
|
||||
SYS_GETRESGID = 120,
|
||||
SYS_SETFSUID = 122,
|
||||
SYS_SETFSGID = 123,
|
||||
SYS_GETSID = 124,
|
||||
SYS_STATFS = 137,
|
||||
SYS_FSTATFS = 138,
|
||||
|
|
@ -436,12 +472,24 @@ pub fn syscall_dispatch(
|
|||
SYS_GETTIMEOFDAY => syscall_handler!(1, sys_gettimeofday, args),
|
||||
SYS_GETUID => syscall_handler!(0, sys_getuid),
|
||||
SYS_GETGID => syscall_handler!(0, sys_getgid),
|
||||
SYS_SETUID => syscall_handler!(1, sys_setuid, args),
|
||||
SYS_SETGID => syscall_handler!(1, sys_setgid, args),
|
||||
SYS_GETEUID => syscall_handler!(0, sys_geteuid),
|
||||
SYS_GETEGID => syscall_handler!(0, sys_getegid),
|
||||
SYS_SETPGID => syscall_handler!(2, sys_setpgid, args),
|
||||
SYS_GETPPID => syscall_handler!(0, sys_getppid),
|
||||
SYS_GETPGRP => syscall_handler!(0, sys_getpgrp),
|
||||
SYS_SETSID => syscall_handler!(0, sys_setsid),
|
||||
SYS_SETREUID => syscall_handler!(2, sys_setreuid, args),
|
||||
SYS_SETREGID => syscall_handler!(2, sys_setregid, args),
|
||||
SYS_GETGROUPS => syscall_handler!(2, sys_getgroups, args),
|
||||
SYS_SETGROUPS => syscall_handler!(2, sys_setgroups, args),
|
||||
SYS_SETRESUID => syscall_handler!(3, sys_setresuid, args),
|
||||
SYS_GETRESUID => syscall_handler!(3, sys_getresuid, args),
|
||||
SYS_SETRESGID => syscall_handler!(3, sys_setresgid, args),
|
||||
SYS_GETRESGID => syscall_handler!(3, sys_getresgid, args),
|
||||
SYS_SETFSUID => syscall_handler!(1, sys_setfsuid, args),
|
||||
SYS_SETFSGID => syscall_handler!(1, sys_setfsgid, args),
|
||||
SYS_GETSID => syscall_handler!(1, sys_getsid, args),
|
||||
SYS_STATFS => syscall_handler!(2, sys_statfs, args),
|
||||
SYS_FSTATFS => syscall_handler!(2, sys_fstatfs, args),
|
||||
|
|
@ -487,6 +535,11 @@ pub fn syscall_dispatch(
|
|||
macro_rules! log_syscall_entry {
|
||||
($syscall_name: tt) => {
|
||||
let syscall_name_str = stringify!($syscall_name);
|
||||
info!("[SYSCALL][id={}][{}]", $syscall_name, syscall_name_str);
|
||||
let pid = $crate::current!().pid();
|
||||
let tid = $crate::current_thread!().tid();
|
||||
info!(
|
||||
"[pid={}][tid={}][id={}][{}]",
|
||||
pid, tid, $syscall_name, syscall_name_str
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,10 @@
|
|||
use jinux_frame::vm::VmIo;
|
||||
|
||||
use super::{SyscallReturn, SYS_RT_SIGPROCMASK};
|
||||
use crate::log_syscall_entry;
|
||||
use crate::prelude::*;
|
||||
use crate::process::posix_thread::PosixThreadExt;
|
||||
use crate::process::signal::constants::{SIGKILL, SIGSTOP};
|
||||
use crate::{
|
||||
log_syscall_entry,
|
||||
prelude::*,
|
||||
process::signal::sig_mask::SigMask,
|
||||
syscall::{SyscallReturn, SYS_RT_SIGPROCMASK},
|
||||
};
|
||||
use crate::process::signal::sig_mask::SigMask;
|
||||
use jinux_frame::vm::VmIo;
|
||||
|
||||
pub fn sys_rt_sigprocmask(
|
||||
how: u32,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
use crate::log_syscall_entry;
|
||||
use crate::prelude::*;
|
||||
use crate::process::{credentials_mut, Gid};
|
||||
|
||||
use super::{SyscallReturn, SYS_SETFSGID};
|
||||
|
||||
pub fn sys_setfsgid(gid: i32) -> Result<SyscallReturn> {
|
||||
log_syscall_entry!(SYS_SETFSGID);
|
||||
debug!("gid = {}", gid);
|
||||
|
||||
let fsgid = if gid < 0 {
|
||||
None
|
||||
} else {
|
||||
Some(Gid::new(gid as u32))
|
||||
};
|
||||
|
||||
let old_fsgid = {
|
||||
let credentials = credentials_mut();
|
||||
credentials.set_fsgid(fsgid)?
|
||||
};
|
||||
|
||||
Ok(SyscallReturn::Return(old_fsgid.as_u32() as _))
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
use crate::log_syscall_entry;
|
||||
use crate::prelude::*;
|
||||
use crate::process::{credentials_mut, Uid};
|
||||
|
||||
use super::{SyscallReturn, SYS_SETFSUID};
|
||||
|
||||
pub fn sys_setfsuid(uid: i32) -> Result<SyscallReturn> {
|
||||
log_syscall_entry!(SYS_SETFSUID);
|
||||
debug!("uid = {}", uid);
|
||||
|
||||
let fsuid = if uid < 0 {
|
||||
None
|
||||
} else {
|
||||
Some(Uid::new(uid as u32))
|
||||
};
|
||||
|
||||
let old_fsuid = {
|
||||
let credentials = credentials_mut();
|
||||
credentials.set_fsuid(fsuid)?
|
||||
};
|
||||
|
||||
Ok(SyscallReturn::Return(old_fsuid.as_u32() as _))
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
use crate::log_syscall_entry;
|
||||
use crate::prelude::*;
|
||||
use crate::process::{credentials_mut, Gid};
|
||||
|
||||
use super::{SyscallReturn, SYS_SETGID};
|
||||
|
||||
pub fn sys_setgid(gid: i32) -> Result<SyscallReturn> {
|
||||
log_syscall_entry!(SYS_SETGID);
|
||||
|
||||
debug!("gid = {}", gid);
|
||||
|
||||
if gid < 0 {
|
||||
return_errno_with_message!(Errno::EINVAL, "gid cannot be negative");
|
||||
}
|
||||
|
||||
let gid = Gid::new(gid as u32);
|
||||
|
||||
let credentials = credentials_mut();
|
||||
credentials.set_gid(gid);
|
||||
|
||||
Ok(SyscallReturn::Return(0))
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
use super::{SyscallReturn, SYS_SETGROUPS};
|
||||
use crate::log_syscall_entry;
|
||||
use crate::prelude::*;
|
||||
use crate::process::{credentials_mut, Gid};
|
||||
use crate::util::read_val_from_user;
|
||||
|
||||
pub fn sys_setgroups(size: usize, group_list_addr: Vaddr) -> Result<SyscallReturn> {
|
||||
log_syscall_entry!(SYS_SETGROUPS);
|
||||
debug!("size = {}, group_list_addr = 0x{:x}", size, group_list_addr);
|
||||
|
||||
// TODO: check perm: the calling process should have the CAP_SETGID capability
|
||||
|
||||
if size > NGROUPS_MAX {
|
||||
return_errno_with_message!(Errno::EINVAL, "size cannot be greater than NGROUPS_MAX");
|
||||
}
|
||||
|
||||
let mut new_groups = BTreeSet::new();
|
||||
for idx in 0..size {
|
||||
let addr = group_list_addr + idx * core::mem::size_of::<Gid>();
|
||||
let gid = read_val_from_user(addr)?;
|
||||
new_groups.insert(gid);
|
||||
}
|
||||
|
||||
let credentials = credentials_mut();
|
||||
*credentials.groups_mut() = new_groups;
|
||||
|
||||
Ok(SyscallReturn::Return(0))
|
||||
}
|
||||
|
||||
const NGROUPS_MAX: usize = 65536;
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
use crate::log_syscall_entry;
|
||||
use crate::prelude::*;
|
||||
use crate::process::{credentials_mut, Gid};
|
||||
|
||||
use super::{SyscallReturn, SYS_SETREGID};
|
||||
|
||||
pub fn sys_setregid(rgid: i32, egid: i32) -> Result<SyscallReturn> {
|
||||
log_syscall_entry!(SYS_SETREGID);
|
||||
debug!("rgid = {}, egid = {}", rgid, egid);
|
||||
|
||||
let rgid = if rgid > 0 {
|
||||
Some(Gid::new(rgid as u32))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let egid = if egid > 0 {
|
||||
Some(Gid::new(egid as u32))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let credentials = credentials_mut();
|
||||
credentials.set_regid(rgid, egid)?;
|
||||
|
||||
Ok(SyscallReturn::Return(0))
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
use crate::log_syscall_entry;
|
||||
use crate::prelude::*;
|
||||
use crate::process::{credentials_mut, Gid};
|
||||
|
||||
use super::{SyscallReturn, SYS_SETRESGID};
|
||||
|
||||
pub fn sys_setresgid(rgid: i32, egid: i32, sgid: i32) -> Result<SyscallReturn> {
|
||||
log_syscall_entry!(SYS_SETRESGID);
|
||||
|
||||
let rgid = if rgid > 0 {
|
||||
Some(Gid::new(rgid as u32))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let egid = if egid > 0 {
|
||||
Some(Gid::new(egid as u32))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let sgid = if sgid > 0 {
|
||||
Some(Gid::new(sgid as u32))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
debug!("rgid = {:?}, egid = {:?}, sgid = {:?}", rgid, egid, sgid);
|
||||
|
||||
let credentials = credentials_mut();
|
||||
credentials.set_resgid(rgid, egid, sgid)?;
|
||||
|
||||
Ok(SyscallReturn::Return(0))
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
use crate::log_syscall_entry;
|
||||
use crate::prelude::*;
|
||||
use crate::process::{credentials_mut, Uid};
|
||||
|
||||
use super::{SyscallReturn, SYS_SETRESUID};
|
||||
|
||||
pub fn sys_setresuid(ruid: i32, euid: i32, suid: i32) -> Result<SyscallReturn> {
|
||||
log_syscall_entry!(SYS_SETRESUID);
|
||||
|
||||
let ruid = if ruid > 0 {
|
||||
Some(Uid::new(ruid as u32))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let euid = if euid > 0 {
|
||||
Some(Uid::new(euid as u32))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let suid = if suid > 0 {
|
||||
Some(Uid::new(suid as u32))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
debug!("ruid = {:?}, euid = {:?}, suid = {:?}", ruid, euid, suid);
|
||||
|
||||
let credentials = credentials_mut();
|
||||
|
||||
credentials.set_resuid(ruid, euid, suid)?;
|
||||
|
||||
Ok(SyscallReturn::Return(0))
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
use crate::log_syscall_entry;
|
||||
use crate::prelude::*;
|
||||
use crate::process::{credentials_mut, Uid};
|
||||
|
||||
use super::{SyscallReturn, SYS_SETREUID};
|
||||
|
||||
pub fn sys_setreuid(ruid: i32, euid: i32) -> Result<SyscallReturn> {
|
||||
log_syscall_entry!(SYS_SETREUID);
|
||||
debug!("ruid = {}, euid = {}", ruid, euid);
|
||||
|
||||
let ruid = if ruid > 0 {
|
||||
Some(Uid::new(ruid as u32))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let euid = if euid > 0 {
|
||||
Some(Uid::new(euid as u32))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let credentials = credentials_mut();
|
||||
credentials.set_reuid(ruid, euid)?;
|
||||
|
||||
Ok(SyscallReturn::Return(0))
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
use super::{SyscallReturn, SYS_SETUID};
|
||||
use crate::log_syscall_entry;
|
||||
use crate::prelude::*;
|
||||
use crate::process::{credentials_mut, Uid};
|
||||
|
||||
pub fn sys_setuid(uid: i32) -> Result<SyscallReturn> {
|
||||
log_syscall_entry!(SYS_SETUID);
|
||||
|
||||
debug!("uid = {}", uid);
|
||||
|
||||
if uid < 0 {
|
||||
return_errno_with_message!(Errno::EINVAL, "uid cannot be negative");
|
||||
}
|
||||
|
||||
let uid = Uid::new(uid as u32);
|
||||
|
||||
let credentials = credentials_mut();
|
||||
credentials.set_uid(uid);
|
||||
|
||||
Ok(SyscallReturn::Return(0))
|
||||
}
|
||||
Loading…
Reference in New Issue