在linux内核中,条件竞争一直是一个经久不息的问题,本文就几种简单的条件竞争模式进行探讨,希望能起到抛砖引玉的效果。
CVE-2016-2546就是一个未正确加锁导致的条件竞争问题,允许多个进程同时对同一共享资源进行访问,未充分考虑加锁导致的条件竞争。
snd_timer
相关的文件操作,重点关注snd_timer_user_ioctl
函数。snd_timer_user_ioctl
函数中未进行加锁,所以可以多个线程同时进入此函数。SNDRV_TIMER_IOCTL_SELECT
和SNDRV_TIMER_IOCTL_START
等多个选项之间存在竞争。
snd_timer_user_tselect
函数首先对tu->tread_sem
进行加锁操作,然后调用snd_timer_close
关闭现有的timeri
。
snd_timer_close
的最后会通过kfree
释放timeri
。若此时另一线程通过cmd
为SNDRV_TIMER_IOCTL_START
参数调用snd_timer_user_ioctl
,则会在snd_timer_user_start
中导致对tu->timeri
的UAF
。
CPU-1 | CPU-2 |
|
snd_timer_user_ioctl
|
snd_timer_user_ts
|
|
mutex_lock
|
snd_timer_user_start
|
snd_timer_close
|
|
kfree
|
|
snd_timer_stop
|
补丁也比较简单,直接对snd_timer_user_ioctl
整个范围加锁。
如下是snd_timer
相关的文件操作,重点关注snd_pcm_common_ioctl
函数。
snd_pcm_common_ioctl
函数中未进行加锁,所以可以多个线程同时进入此函数。
snd_pcm_hw_free
函数首先通过snd_pcm_stream_lock_irq
进行加锁操作,但在调用do_hw_free
进行释放前,就已调用snd_pcm_stream_unlock_irq
解锁,所以如果多线程同时调用snd_pcm_hw_free
就可能会导致竞争问题。
CPU-1 | CPU-2 |
|
|
snd_pcm_hw_free
|
snd_pcm_hw_free
|
snd_pcm_stream_lock_irq
|
|
snd_pcm_stream_unlock_irq
|
snd_pcm_stream_lock_irq
|
snd_pcm_stream_unlock_irq
|
|
do_hw_free |
do_hw_free
|
snd_pcm_common_ioctl
还存在多处其它的竞争问题,所以补丁实际上是增加了一个新的锁来解决,新的锁范围涵盖了do_hw_free
。fd_install
使得用户态可以通过fd
访问对应的file
对象之后(此时用户态可以通过close
释放对应的file
对象),又接着在后面代码中访问file
对象,此时就会导致UAF
。下文将通过CVE-2022-1998进行说明。
在copy_event_to_user
中调用create_fd
创建对应的file
对象和fd
,紧接着调用fd_install
使得用户态可以通过fd
访问对应的file
对象,然后调用copy_info_records_to_user
,此时若copy_info_records_to_user
返回失败,则会进入失败处理流程,调用fput
释放file
对象,但如果用户态在fput
之前就调用close
释放了file
对象,那么在fput
中会出现UAF/Double Free
。
CPU-1 | CPU-2 |
|
|
fd_install
|
|
copy_info_records_to_user
|
|
fput
|
fd_install
往后移,确保不会在fd_install
之后依然使用file对象即可。windows
内核中也存在类似的问题,可以参考这篇文章CVE-2021-41335。UAF
。
CVE-2023-33288就是这一类问题,在bq24190_probe
函数中初始化input_current_limit_work
工作队列指针为bq24190_input_current_limit_work
。
之后当外部电源改变时,会调用bq24190_charger_external_power_changed
将input_current_limit_work
加入到延迟工作队列中(300ms后才会真正调用bq24190_input_current_limit_work
)。
bq24190_remove
进行清理,但该函数没有移除之前的工作队列,导致后续bq24190_input_current_limit_work
被调用时UAF
。bq24190_remove
中加上cancel_delayed_work_sync
移除工作队列即可。总而言之,Linux内核中依然存在很多的条件竞争问题,和其它漏洞类型相比,条件竞争相对不易于理解,难以触发,希望本文能起到抛砖引玉的效果。
【版权说明】
本作品著作权归n2k9所有
未经作者同意,不得转载
天工实验室安全研究员
研究领域:物联网安全、Windows安全、Linux内核安全
原文始发于微信公众号(破壳平台):关于Linux内核条件竞争的探讨
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论