mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-20 22:36:31 +00:00
new:在fork时拷贝signal和sighand (#91)
* refcount初始化 * new: 实现copy_sighand del: 删除sighand_struct的wqh, 待将来有需要时,替换成rust版本的 * new: 拷贝signal bugfix: 解决拷贝sighand时的uaf问题
This commit is contained in:
@ -12,11 +12,12 @@ int process_copy_files(uint64_t clone_flags, struct process_control_block *pcb);
|
||||
int process_copy_flags(uint64_t clone_flags, struct process_control_block *pcb);
|
||||
int process_copy_mm(uint64_t clone_flags, struct process_control_block *pcb);
|
||||
int process_copy_thread(uint64_t clone_flags, struct process_control_block *pcb, uint64_t stack_start,
|
||||
uint64_t stack_size, struct pt_regs *current_regs);
|
||||
|
||||
extern int process_copy_sighand(uint64_t clone_flags, struct process_control_block * pcb);
|
||||
extern int process_copy_signal(uint64_t clone_flags, struct process_control_block * pcb);
|
||||
uint64_t stack_size, struct pt_regs *current_regs);
|
||||
|
||||
extern int process_copy_sighand(uint64_t clone_flags, struct process_control_block *pcb);
|
||||
extern int process_copy_signal(uint64_t clone_flags, struct process_control_block *pcb);
|
||||
extern void process_exit_sighand(struct process_control_block *pcb);
|
||||
extern void process_exit_signal(struct process_control_block *pcb);
|
||||
|
||||
/**
|
||||
* @brief fork当前进程
|
||||
@ -111,14 +112,14 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
|
||||
retval = process_copy_files(clone_flags, tsk);
|
||||
if (retval)
|
||||
goto copy_files_failed;
|
||||
|
||||
|
||||
// 拷贝信号处理函数
|
||||
retval = process_copy_sighand(clone_flags, tsk);
|
||||
if(retval)
|
||||
if (retval)
|
||||
goto copy_sighand_failed;
|
||||
|
||||
|
||||
retval = process_copy_signal(clone_flags, tsk);
|
||||
if(retval)
|
||||
if (retval)
|
||||
goto copy_signal_failed;
|
||||
|
||||
// 拷贝线程结构体
|
||||
@ -338,7 +339,7 @@ static int process_rewrite_rbp(struct pt_regs *new_regs, struct process_control_
|
||||
* @return uint64_t
|
||||
*/
|
||||
int process_copy_thread(uint64_t clone_flags, struct process_control_block *pcb, uint64_t stack_start,
|
||||
uint64_t stack_size, struct pt_regs *current_regs)
|
||||
uint64_t stack_size, struct pt_regs *current_regs)
|
||||
{
|
||||
// 将线程结构体放置在pcb后方
|
||||
struct thread_struct *thd = (struct thread_struct *)(pcb + 1);
|
||||
|
@ -1,27 +1,102 @@
|
||||
use crate::{include::bindings::bindings::{process_control_block, CLONE_SIGHAND}, kdebug, libs::{refcount::{refcount_inc, RefCount}, ffi_convert::FFIBind2Rust}, arch::x86_64::asm::current::current_pcb};
|
||||
use core::ptr::null_mut;
|
||||
|
||||
use alloc::boxed::Box;
|
||||
|
||||
use crate::{
|
||||
arch::x86_64::asm::current::current_pcb,
|
||||
include::{
|
||||
bindings::bindings::{
|
||||
process_control_block, CLONE_CLEAR_SIGHAND, CLONE_SIGHAND, CLONE_THREAD, ENOMEM,
|
||||
},
|
||||
DragonOS::signal::{sigaction, sighand_struct, signal_struct},
|
||||
},
|
||||
ipc::signal::DEFAULT_SIGACTION,
|
||||
kdebug,
|
||||
libs::{
|
||||
ffi_convert::FFIBind2Rust,
|
||||
refcount::{refcount_inc, RefCount},
|
||||
spinlock::{spin_lock_irqsave, spin_unlock_irqrestore}, atomic::atomic_set,
|
||||
},
|
||||
};
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn process_copy_sighand(clone_flags: u64, pcb: *mut process_control_block) -> i32 {
|
||||
kdebug!("process_copy_sighand");
|
||||
if(clone_flags & (CLONE_SIGHAND as u64)) != 0{
|
||||
let r = RefCount::convert_mut(unsafe{&mut (*((current_pcb().sighand))).count}).unwrap();
|
||||
refcount_inc(r);
|
||||
if (clone_flags & (CLONE_SIGHAND as u64)) != 0 {
|
||||
let r = RefCount::convert_mut(unsafe { &mut (*(current_pcb().sighand)).count }).unwrap();
|
||||
refcount_inc(r);
|
||||
}
|
||||
0
|
||||
// 在这里使用Box::leak将动态申请的内存的生命周期转换为static的
|
||||
let mut sig: &mut sighand_struct = Box::leak(Box::new(sighand_struct::default()));
|
||||
if (sig as *mut sighand_struct) == null_mut() {
|
||||
return -(ENOMEM as i32);
|
||||
}
|
||||
// 将新的sighand赋值给pcb
|
||||
unsafe {
|
||||
(*pcb).sighand = sig as *mut sighand_struct as usize
|
||||
as *mut crate::include::bindings::bindings::sighand_struct;
|
||||
}
|
||||
|
||||
// 拷贝sigaction
|
||||
let mut flags: u64 = 0;
|
||||
spin_lock_irqsave(unsafe { &mut (*current_pcb().sighand).siglock }, &mut flags);
|
||||
for (index, x) in unsafe { (*current_pcb().sighand).action }
|
||||
.iter()
|
||||
.enumerate()
|
||||
{
|
||||
if !(x as *const crate::include::bindings::bindings::sigaction).is_null() {
|
||||
sig.action[index] =
|
||||
*sigaction::convert_ref(x as *const crate::include::bindings::bindings::sigaction)
|
||||
.unwrap();
|
||||
} else {
|
||||
sig.action[index] = DEFAULT_SIGACTION;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(unsafe { &mut (*current_pcb().sighand).siglock }, &flags);
|
||||
|
||||
// 将所有屏蔽的信号的处理函数设置为default
|
||||
if (clone_flags & (CLONE_CLEAR_SIGHAND as u64)) != 0 {
|
||||
todo!();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn process_copy_signal(clone_flags: u64, pcb: *mut process_control_block) -> i32 {
|
||||
kdebug!("process_copy_signal");
|
||||
0
|
||||
// 如果克隆的是线程,则不拷贝信号(同一进程的各个线程之间共享信号)
|
||||
if (clone_flags & (CLONE_THREAD as u64)) != 0 {
|
||||
return 0;
|
||||
}
|
||||
let sig: &mut signal_struct = Box::leak(Box::new(signal_struct::default()));
|
||||
if (sig as *mut signal_struct) == null_mut() {
|
||||
return -(ENOMEM as i32);
|
||||
}
|
||||
atomic_set(&mut sig.sig_cnt, 1);
|
||||
// 将sig赋值给pcb中的字段
|
||||
unsafe {
|
||||
(*pcb).signal = sig as *mut signal_struct as usize
|
||||
as *mut crate::include::bindings::bindings::signal_struct;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn process_exit_signal(pcb: *mut process_control_block){
|
||||
// todo: 回收进程的信号结构体
|
||||
pub extern "C" fn process_exit_signal(pcb: *mut process_control_block) {
|
||||
// 回收进程的信号结构体
|
||||
unsafe {
|
||||
drop((*pcb).sighand as *mut sighand_struct);
|
||||
(*pcb).sighand = 0 as *mut crate::include::bindings::bindings::sighand_struct;
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn process_exit_sighand(pcb: *mut process_control_block){
|
||||
pub extern "C" fn process_exit_sighand(pcb: *mut process_control_block) {
|
||||
// todo: 回收进程的sighand结构体
|
||||
unsafe {
|
||||
drop((*pcb).signal as *mut signal_struct);
|
||||
(*pcb).signal = 0 as *mut crate::include::bindings::bindings::signal_struct;
|
||||
}
|
||||
}
|
||||
|
@ -1,26 +1,21 @@
|
||||
use crate::{
|
||||
include::{
|
||||
bindings::bindings::{atomic_t, spinlock_t, wait_queue_head_t, List},
|
||||
bindings::bindings::{atomic_t, spinlock_t},
|
||||
DragonOS::signal::{sighand_struct, signal_struct, MAX_SIG_NUM},
|
||||
},
|
||||
ipc::signal::DEFAULT_SIGACTION,
|
||||
};
|
||||
|
||||
/// @brief 初始进程的signal结构体
|
||||
#[no_mangle]
|
||||
pub static INITIAL_SIGNALS: signal_struct = signal_struct {
|
||||
sig_cnt: atomic_t { value: 0 },
|
||||
};
|
||||
|
||||
/// @brief 初始进程的sighand结构体
|
||||
#[no_mangle]
|
||||
pub static mut INITIAL_SIGHAND: sighand_struct = sighand_struct {
|
||||
count: REFCOUNT_INIT!(1),
|
||||
siglock: spinlock_t { lock: 1 },
|
||||
signal_fd_wqh: wait_queue_head_t {
|
||||
lock: spinlock_t { lock: 1 },
|
||||
wait_list: List {
|
||||
prev: unsafe { &INITIAL_SIGHAND.signal_fd_wqh.wait_list as *const List } as *mut List,
|
||||
next: unsafe { &INITIAL_SIGHAND.signal_fd_wqh.wait_list as *const List } as *mut List,
|
||||
},
|
||||
},
|
||||
action: [DEFAULT_SIGACTION; MAX_SIG_NUM as usize],
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <DragonOS/signal.h>
|
||||
#include <common/wait_queue.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// 进程最大可拥有的文件描述符数量
|
||||
#define PROC_MAX_FD_NUM 16
|
||||
@ -32,11 +32,12 @@
|
||||
#define USER_DS (0x30)
|
||||
|
||||
// 进程初始化时的数据拷贝标志位
|
||||
#define CLONE_FS (1UL << 0) // 在进程间共享打开的文件
|
||||
#define CLONE_SIGNAL (1UL << 1) // 克隆时,与父进程共享信号结构体
|
||||
#define CLONE_VM (1UL << 2) // 在进程间共享虚拟内存空间
|
||||
#define CLONE_SIGHAND (1UL << 3) // 克隆时,与父进程共享信号处理结构体
|
||||
|
||||
#define CLONE_FS (1UL << 0) // 在进程间共享打开的文件
|
||||
#define CLONE_SIGNAL (1UL << 1) // 克隆时,与父进程共享信号结构体
|
||||
#define CLONE_VM (1UL << 2) // 在进程间共享虚拟内存空间
|
||||
#define CLONE_SIGHAND (1UL << 3) // 克隆时,与父进程共享信号处理结构体
|
||||
#define CLONE_CLEAR_SIGHAND (1UL << 4) // 克隆时,将原本被设置为SIG_IGNORE的信号,设置回SIG_DEFAULT
|
||||
#define CLONE_THREAD (1UL << 5) // 拷贝线程
|
||||
#define PCB_NAME_LEN 16
|
||||
|
||||
struct thread_struct
|
||||
|
Reference in New Issue
Block a user