-
-
Notifications
You must be signed in to change notification settings - Fork 168
fix(signal): correct pid retrieval and signal ignoring logic #1434
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
base: master
Are you sure you want to change the base?
Conversation
Signed-off-by: aLinChe <[email protected]>
Signed-off-by: aLinChe <[email protected]>
Signed-off-by: aLinChe <[email protected]>
Signed-off-by: aLinChe <[email protected]>
| tgid.data() | ||
| ); | ||
| return Ok(1); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个问题需要解决一下
|
@claude review,审查功能、性能、安全、linux一致性的问题 |
|
Claude finished @fslongjin's task —— View job PR Review: #1434 - fix(signal): correct pid retrieval and signal ignoring logicI've completed a thorough review of this PR for functionality, performance, security, and Linux compatibility. Here are my findings: Overall AssessmentThe PR addresses four important issues related to signal handling and process management. Most changes are correct and improve Linux compatibility, but there is one critical bug in 1. getpid System Call Changes (
|
|
@claude review 根据Linux6.6.21的源码重新分析你说的 3. Signal Blocking Mask Fix static int do_sigtimedwait(const sigset_t *which, kernel_siginfo_t *info,
const struct timespec64 *ts)
{
ktime_t *to = NULL, timeout = KTIME_MAX;
struct task_struct *tsk = current;
sigset_t mask = *which;
enum pid_type type;
int sig, ret = 0;
if (ts) {
if (!timespec64_valid(ts))
return -EINVAL;
timeout = timespec64_to_ktime(*ts);
to = &timeout;
}
/*
* Invert the set of allowed signals to get those we want to block.
*/
sigdelsetmask(&mask, sigmask(SIGKILL) | sigmask(SIGSTOP));
signotset(&mask);
spin_lock_irq(&tsk->sighand->siglock);
sig = dequeue_signal(tsk, &mask, info, &type);
if (!sig && timeout) {
/*
* None ready, temporarily unblock those we're interested
* while we are sleeping in so that we'll be awakened when
* they arrive. Unblocking is always fine, we can avoid
* set_current_blocked().
*/
tsk->real_blocked = tsk->blocked;
// 这里的操作等价于 new_blocked.remove(awaited)
// 数学原理: Blocked & (~Awaited) === Blocked - Awaited
sigandsets(&tsk->blocked, &tsk->blocked, &mask);
recalc_sigpending();
spin_unlock_irq(&tsk->sighand->siglock);
__set_current_state(TASK_INTERRUPTIBLE|TASK_FREEZABLE);
ret = schedule_hrtimeout_range(to, tsk->timer_slack_ns,
HRTIMER_MODE_REL);
spin_lock_irq(&tsk->sighand->siglock);
__set_task_blocked(tsk, &tsk->real_blocked);
sigemptyset(&tsk->real_blocked);
sig = dequeue_signal(tsk, &mask, info, &type);
}
spin_unlock_irq(&tsk->sighand->siglock);
if (sig)
return sig;
return ret ? -EINTR : -EAGAIN;
}https://code.dragonos.org.cn/xref/linux-6.6.21/kernel/signal.c#3604 |
Signed-off-by: aLinChe <[email protected]>
Signed-off-by: aLinChe <[email protected]>
本次PR主要修复了与 信号处理、进程ID获取 和 fork 相关的四个关键问题:
getpid系统调用:将getpid()的实现改为返回task_tgid_vnr(current),以确保在PID命名空间环境中能返回当前命名空间下的正确进程组ID(TGID),符合 Linux 标准语义,修复了tgkill等依赖 TGID 的操作在多线程或容器环境下的归属判断错误。new_blocked.remove(awaited)的逻辑错误,确保在等待信号期间能正确管理信号的阻塞状态,避免了本该被丢弃的忽略信号被错误入队。。sig_task_ignored和sig_ignored函数,为核心信号处理逻辑添加了完整的信号忽略判断机制。该机制能正确处理:SIGKILL和SIGSTOP信号的特殊忽略规则。UNKILLABLE的进程的信号处理。SIG_KERNEL_IGNORE_MASK)。sigmask和saved_sigmask),确保即使信号的处置为忽略,但如果该信号被阻塞,它也会被正确放入队列而不被立即丢弃。copy_process流程顺序与并发安全性修复sched_fork、资源拷贝(copy_fs提前)、PID 分配等步骤的执行顺序。ProcessManager::add_pcb(全局可见)推迟到所有 PID 初始化(init_task_pid)和哈希表挂载(attach_pid)完成之后执行。这消除了 PCB 对外可见但内部 ID 数据尚未初始化的竞态窗口。