在信号量操作流程中调用wait_event是否合法?存在哪些风险?
信号量逻辑中调用wait_event的合理性与代码风险说明
wait_event*系列接口本身没有禁止和信号量配合使用,不存在绝对的不合理性,但你给出的这段代码存在明确的隐患,具体问题如下:
核心风险点
- 临界区竞态问题
这段代码的执行前提应该是你当前已经持有了sem信号量,先执行up(&sem)释放信号量后再进入等待状态时,其他内核路径完全可以拿到这个信号量,修改你原本用信号量保护的共享资源。等你从wait_event_interruptible唤醒、再执行down(&sem)拿回信号量时,之前读取的共享资源状态已经全部失效,如果你后续逻辑没有重新校验资源状态,直接复用等待前的缓存值就会出现竞态漏洞。 - 返回值未处理的逻辑异常
wait_event_interruptible支持被信号中断,返回非0值时代表等待被信号打断,你没有判断返回值就直接执行down(&sem),如果上层逻辑收到信号后需要退出流程,这里多余的拿信号量操作会导致资源泄漏,甚至后续退出逻辑漏释放信号量引发死锁。 - 极端场景死锁风险
如果你等待的事件的触发逻辑本身需要持有你刚刚释放的sem信号量,就会触发死锁:你等待事件触发,而事件触发逻辑拿不到sem无法执行唤醒操作,双方会陷入无限等待。
合理使用建议
- 如果你等待的事件触发逻辑不需要持有当前
sem信号量,且不需要释放信号量的场景下,可以直接在持有信号量的状态下调用wait_event_interruptible,等待过程中信号量还是被你持有,其他路径无法修改临界资源,唤醒后可以直接操作资源。 - 如果你确实需要先释放信号量再等待,唤醒后拿到信号量必须全量重新校验所有共享资源的状态,不能直接使用等待前读取的缓存值。
- 必须处理
wait_event_interruptible的返回值,如果是被信号打断,直接走错误退出逻辑,释放所有已持有的资源后返回错误码,不要继续执行正常业务流程。
内容的提问来源于stack exchange,提问作者Shisui
相关产品推荐
相关产品推荐

