kill与pid_namespace


基础知识与结构

信号本质上是在软件层次上对中断机制的一种模拟,其主要有以下几种来源:

  • 程序错误:除零,非法内存访问等。
  • 外部信号:终端 Ctrl-C 产生 SGINT 信号,定时器到期产生SIGALRM等。
  • 显式请求:kill函数允许进程发送任何信号给其他进程或进程组。

KILL学习

kill系统调用给用户的接口如下:

int kill(pid_t pid, int sig);

查看Linux源码:https://elixir.bootlin.com/linux/v6.13.5/source/kernel/signal.c#L3951

info准备

prepare_kill_siginfo的作用就是准备info,这里只涉及和信号发出者相关的信息,比如si_pid和si_uid:

si_pid

需要注意的是,这里的si_pid的获取是通过如下函数进行的:

其中,ns获取了当前进程的pid_namespace,这个rcu_dereference解析出来了当前进程的pid结构体,然后upid获取到了对应level的number,这个时候的nr就是当前pid_namespace下的pid,因此si_pid是子pid_namespace下的pid:

si_uid

下面看si_uid的获取过程,其是通过from_kuid_munged函数获取的:

这个函数调用了from_kuid,这个函数就是通过查uid_map来将全局的uid转换成当前user_namespace下的uid:

综上所述,si_uid也是子namespace下的uid;

kill

先看kill_proc_info:

其调用了kill_pid_info,且在此之前同构find_vpid对pid进行了转换,应该就是从当前的pid_namespace中找pid结构体:

通过pid结构体找到task,然后在死循环中不断尝试传递信号:

总结

参考

https://www.51cto.com/article/675743.html


文章作者: q1ming
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 q1ming !
  目录