linux 信号处理(Linux是什么软件)
其实linux 信号处理的问题并不复杂,但是又很多的朋友都不太了解Linux是什么软件,因此呢,今天小编就来为大家分享linux 信号处理的一些知识,希望可以帮助到大家,下面我们一起来看看这个问题的分析吧!
linux中进程信号捕获,signal和sigaction。
一、基本概念
信号是事件通知机制,与中断相似,在事件发生时打断进程的执行流程。信号可用于进程间通信或作为同步技术,通常由内核向进程发送,引发事件包括但不限于内核操作。信号在系统中具有唯一编号,程序中应使用符号名表示。信号分为标准信号(编号1-31)和实时信号(编号31以上,至64以内)。信号在生成后可能等待一段时间被处理,通常在内核返回用户态时检查信号是否到达。进程向其他进程发送信号时,信号通常处于等待状态,直到接收者被调度或正在执行。若进程向自身发送信号,则信号处理可能立即进行。有时,可以使用掩码屏蔽信号,被屏蔽信号将处于等待状态,直至解除屏蔽。通过 `/proc/pid/status`可查看当前进程的信号。
二、信号处理函数的设置
从内核角度看,线程的信号可能存于共享队列或私有队列。通常信号被发送到线程组共享的信号队列,线程组中的任意线程处理一次即可;而在用户态看来,信号可能被线程组中的任一线程处理。`tkill`系统调用可将信号直接发送给线程的私有队列,确保特定线程处理。内核中信号相关的结构体定义如下。各结构体关系以图表展示。Linux用户态通过 `signal`和 `sigaction`函数设置信号处理函数,二者最终调用 `do_sigaction`函数。以 `sys_signal`为例,展示了信号处理流程。
三、信号的发送
以 `sys_kill`为例,用户态入口系统调用发送信号。`prepare_signal`定义了信号准备流程,而 `complete_signal`定义了信号完成流程。信号发送涉及将信号设置到线程队列,并可能为线程标记 `TIF_SIGPENDING`标志。内核返回用户态时会检查并处理信号。
四、信号的处理与等待
信号处理分为两种场景:内核返回用户态时检查并处理信号,或内核线程循环检查自身信号。用户态代码在异常触发时检查信号。信号处理过程分为使用默认行为、忽略信号和执行处理函数三种情况。在处理函数执行过程中,信号可能再次中断,且后到信号被优先处理。安全分析重点关注信号处理过程中权限提升风险。
五、信号处理举例与中断处理
具体信号处理流程通过图表展示。EL0异常返回前,`exit_to_user_mode`检查信号。`do_signal`是信号处理入口,从队列中获取信号,将其处理。用户态上下文在信号处理前保存,信号处理后通过 `sys_rt_sigreturn`恢复。
六、SROP原理与安全性分析
SROP(Sigreturn Oriented Programming)允许攻击者控制当前栈帧后执行 `sys_rt_sigreturn`,从而控制所有通用硬件寄存器。这为执行任何参数设置、控制流转移、返回地址设置和堆栈指针修改提供了可能性。利用SROP执行 `execve`的流程通过图表展示。需注意使用SROP链接多个系统调用时,可能需要额外的 `syscall& ret` gadget。
linux系统上信号发送和信号接收讲解
用于进程间通信,通信机制由操作系统保证,比较稳定。
在linux中可以通过kill-l查看所有信号的类型。
kill-信号类型进程ID
int kill(pid_t pid, int sig);
入参pid:
pid> 0:发送信号给指定的进程。
pid= 0:发送信号给与调用kill函数进程属于同一进程组的所有进程。
pid< 0:取|pid|发给对应进程组。
pid=-1:发送给进程有权限发送的系统中所有进程。
sig:信号类型。
返回值:成功:0;失败:-1(ID非法,信号非法,普通用户杀init进程等权级问题),设置errno
以OpenHarmony源码为例,应用ANR后,AbilityManagerService会通知应用dump堆栈信息,就是通过信号量做的。
头文件位置:
include<signal.h>
函数解释:
typedef void(*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
当接收到指定的信号signum时,就会跳转到参数handler指定的函数执行。其中handler的入参是信号值。
函数原型:
signum参数指出要捕获的信号类型,act参数指定新的信号处理方式,oldact参数输出先前信号的处理方式(如果不为NULL的话)。
sigaction结构体
sa_handler信号处理函数
sa_mask在处理该信号时可以暂时将sa_mask指定的信号集搁置
sa_flags指定一组修改信号行为的标志。它由以下零个或多个的按位或组成
SA_RESETHAND:当调用信号处理函数时,将信号的处理函数重置为缺省值SIG_DFL
SA_RESTART:如果信号中断了进程的某个系统调用,则系统自动启动该系统调用
SA_NODEFER:一般情况下,当信号处理函数运行时,内核将阻塞该给定信号。但是如果设置了 SA_NODEFER标记,那么在该信号处理函数运行时,内核将不会阻塞该信号
sa_restorer是一个替代的信号处理程序,当设置SA_SIGINFO时才会用它。
相关函数
int sigemptyset( sigset_t*set);
sigemptyset()用来将参数set信号集初始化并清空。
执行成功则返回0,如果有错误则返回-1。
完整示例
linux系统下进程的信号(signal)处理流程是怎么样的
信号处理是Linux下进程管理的重要机制。信号的来源可分为三大类:硬件异常、外部信号和显示请求。
硬件异常产生的错误包括非法内存访问、除数为0等;外部信号则通过按键操作如Ctrl-C或定时器到期产生;显示请求则通常由`kill`函数触发。
在Linux中,每个进程由`task_struct`结构创建,包含`task vector`数组,其大小决定系统最大进程数,默认为512。`task_struct`中`Signal_Strct`包含`list_head`和`sigset_t`表,定义64种信号含义。
信号处理机制基于表存储,即每个进程都存有一张表,描述每种信号的意义。信号触发和发送是异步的,内核负责转发以确保安全,避免任意程序随意中止进程,如SIGSTOP和SIGKILL信号。
发送信号时,进程A根据信号表设置对应项。内核验证权限后更新B进程的信号表。信号处理没有排队机制,后续相同信号会被阻塞丢弃。内核发送中断请求给B进程,触发信号处理函数。信号处理后,B进程返回,再次设置frame,继续执行。
使用时,通过`kill`函数发送信号,接收进程调用`sighandler`或`signalaction`处理信号消息。此过程直观展示了Linux下进程信号处理的机制与流程。