mirror of https://github.com/torvalds/linux.git
The original code uses cancel_delayed_work() in xc5000_release(), which
does not guarantee that the delayed work item timer_sleep has fully
completed if it was already running. This leads to use-after-free scenarios
where xc5000_release() may free the xc5000_priv while timer_sleep is still
active and attempts to dereference the xc5000_priv.
A typical race condition is illustrated below:
CPU 0 (release thread) | CPU 1 (delayed work callback)
xc5000_release() | xc5000_do_timer_sleep()
cancel_delayed_work() |
hybrid_tuner_release_state(priv) |
kfree(priv) |
| priv = container_of() // UAF
Replace cancel_delayed_work() with cancel_delayed_work_sync() to ensure
that the timer_sleep is properly canceled before the xc5000_priv memory
is deallocated.
A deadlock concern was considered: xc5000_release() is called in a process
context and is not holding any locks that the timer_sleep work item might
also need. Therefore, the use of the _sync() variant is safe here.
This bug was initially identified through static analysis.
Fixes:
|
||
|---|---|---|
| .. | ||
| Kconfig | ||
| Makefile | ||
| e4000.c | ||
| e4000.h | ||
| e4000_priv.h | ||
| fc001x-common.h | ||
| fc0011.c | ||
| fc0011.h | ||
| fc0012-priv.h | ||
| fc0012.c | ||
| fc0012.h | ||
| fc0013-priv.h | ||
| fc0013.c | ||
| fc0013.h | ||
| fc2580.c | ||
| fc2580.h | ||
| fc2580_priv.h | ||
| it913x.c | ||
| it913x.h | ||
| m88rs6000t.c | ||
| m88rs6000t.h | ||
| max2165.c | ||
| max2165.h | ||
| max2165_priv.h | ||
| mc44s803.c | ||
| mc44s803.h | ||
| mc44s803_priv.h | ||
| msi001.c | ||
| mt20xx.c | ||
| mt20xx.h | ||
| mt2060.c | ||
| mt2060.h | ||
| mt2060_priv.h | ||
| mt2063.c | ||
| mt2063.h | ||
| mt2131.c | ||
| mt2131.h | ||
| mt2131_priv.h | ||
| mt2266.c | ||
| mt2266.h | ||
| mxl301rf.c | ||
| mxl301rf.h | ||
| mxl5005s.c | ||
| mxl5005s.h | ||
| mxl5007t.c | ||
| mxl5007t.h | ||
| qm1d1b0004.c | ||
| qm1d1b0004.h | ||
| qm1d1c0042.c | ||
| qm1d1c0042.h | ||
| qt1010.c | ||
| qt1010.h | ||
| qt1010_priv.h | ||
| r820t.c | ||
| r820t.h | ||
| si2157.c | ||
| si2157.h | ||
| si2157_priv.h | ||
| tda827x.c | ||
| tda827x.h | ||
| tda8290.c | ||
| tda8290.h | ||
| tda9887.c | ||
| tda9887.h | ||
| tda18212.c | ||
| tda18212.h | ||
| tda18218.c | ||
| tda18218.h | ||
| tda18218_priv.h | ||
| tda18250.c | ||
| tda18250.h | ||
| tda18250_priv.h | ||
| tda18271-common.c | ||
| tda18271-fe.c | ||
| tda18271-maps.c | ||
| tda18271-priv.h | ||
| tda18271.h | ||
| tea5761.c | ||
| tea5761.h | ||
| tea5767.c | ||
| tea5767.h | ||
| tua9001.c | ||
| tua9001.h | ||
| tua9001_priv.h | ||
| tuner-i2c.h | ||
| tuner-simple.c | ||
| tuner-simple.h | ||
| tuner-types.c | ||
| xc2028-types.h | ||
| xc2028.c | ||
| xc2028.h | ||
| xc4000.c | ||
| xc4000.h | ||
| xc5000.c | ||
| xc5000.h | ||