关于Linux内核条件竞争的探讨

admin 2024年2月28日14:47:37评论10 views字数 2518阅读8分23秒阅读模式
前 言

在linux内核中,条件竞争一直是一个经久不息的问题,本文就几种简单的条件竞争模式进行探讨,希望能起到抛砖引玉的效果。

关于Linux内核条件竞争的探讨

未 加 锁

CVE-2016-2546就是一个未正确加锁导致的条件竞争问题,允许多个进程同时对同一共享资源进行访问,未充分考虑加锁导致的条件竞争。

如下snd_timer关的文件操作,重点关注snd_timer_user_ioctl函数

关于Linux内核条件竞争的探讨

关于Linux内核条件竞争的探讨

snd_timer_user_ioctl函数中未进行加锁,所以可以多个线程同时进入此函数。SNDRV_TIMER_IOCTL_SELECTSNDRV_TIMER_IOCTL_START等多个选项之间存在竞争。

snd_timer_user_tselect函数首先对tu->tread_sem进行加锁操作,然后调用snd_timer_close关闭现有的timeri

关于Linux内核条件竞争的探讨

snd_timer_close的最后会通过kfree释放timeri

关于Linux内核条件竞争的探讨

若此时另一线程通过cmdSNDRV_TIMER_IOCTL_START参数调用snd_timer_user_ioctl,则会在snd_timer_user_start中导致对tu->timeriUAF

关于Linux内核条件竞争的探讨

本质上是释放路径和访问路径中存在一条未加锁的路径,导致的竞争问题。

CPU-1

CPU-2

snd_timer_user_ioctl

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整个范围加锁。

关于Linux内核条件竞争的探讨

过早释放锁
虽然加锁了,但如果过早的释放锁,也会导致问题。CVE-2022-1048就是一个很好的例子。

如下是snd_timer相关的文件操作,重点关注snd_pcm_common_ioctl函数。

关于Linux内核条件竞争的探讨

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就可能会导致竞争问题。

关于Linux内核条件竞争的探讨

CPU-1

CPU-2

snd_pcm_common_ioctl

snd_pcm_common_ioc

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

关于Linux内核条件竞争的探讨

过早暴露给用户态
当一个对象被过早的暴露给用户态时,也会存在竞争问题。例如一个函数中调用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

关于Linux内核条件竞争的探讨

CPU-1

CPU-2

copy_event_to_user

fd_install

copy_info_records_to_user

close

fput

补丁也很简单,将fd_install往后移,确保不会在fd_install之后依然使用file对象即可。windows内核中也存在类似的问题,可以参考这篇文章CVE-2021-41335

关于Linux内核条件竞争的探讨

未取消工作列队
此类问题常见于设备移除过程,linux设备有时会通过创建工作队列,来处理一些问题。若是在设备移除时,忘记取消之前创建的工作队列,那么就可能导致UAF

CVE-2023-33288就是这一类问题,在bq24190_probe函数中初始化input_current_limit_work工作队列指针为bq24190_input_current_limit_work

关于Linux内核条件竞争的探讨

之后当外部电源改变时,会调用bq24190_charger_external_power_changedinput_current_limit_work加入到延迟工作队列中(300ms后才会真正调用bq24190_input_current_limit_work)。

关于Linux内核条件竞争的探讨

若此时移除此模块,则会调用bq24190_remove进行清理,但该函数没有移除之前的工作队列,导致后续bq24190_input_current_limit_work被调用时UAF

关于Linux内核条件竞争的探讨

补丁也很简单,在bq24190_remove中加上cancel_delayed_work_sync移除工作队列即可。

关于Linux内核条件竞争的探讨

总 结
本文总结了Linux内核中常见的几种条件竞争问题,还有许多更复杂的条件竞争类型,限于笔者水平,尚不能很好的分析总结。

总而言之,Linux内核中依然存在很多的条件竞争问题,和其它漏洞类型相比,条件竞争相对不易于理解,难以触发,希望本文能起到抛砖引玉的效果。

【版权说明】

本作品著作权归n2k9所有

未经作者同意,不得转载

关于Linux内核条件竞争的探讨
n2k9

天工实验室安全研究员

研究领域:物联网安全、Windows安全、Linux内核安全

原文始发于微信公众号(破壳平台):关于Linux内核条件竞争的探讨

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年2月28日14:47:37
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   关于Linux内核条件竞争的探讨http://cn-sec.com/archives/2533285.html

发表评论

匿名网友 填写信息