CVE-2024-39486
Severity CVSS v4.0:
Pending analysis
Type:
CWE-416
Use After Free
Publication date:
06/07/2024
Last modified:
22/08/2024
Description
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
drm/drm_file: Fix pid refcounting race<br />
<br />
, Maxime Ripard<br />
, Thomas Zimmermann <br />
<br />
filp->pid is supposed to be a refcounted pointer; however, before this<br />
patch, drm_file_update_pid() only increments the refcount of a struct<br />
pid after storing a pointer to it in filp->pid and dropping the<br />
dev->filelist_mutex, making the following race possible:<br />
<br />
process A process B<br />
========= =========<br />
begin drm_file_update_pid<br />
mutex_lock(&dev->filelist_mutex)<br />
rcu_replace_pointer(filp->pid, , 1)<br />
mutex_unlock(&dev->filelist_mutex)<br />
begin drm_file_update_pid<br />
mutex_lock(&dev->filelist_mutex)<br />
rcu_replace_pointer(filp->pid, , 1)<br />
mutex_unlock(&dev->filelist_mutex)<br />
get_pid()<br />
synchronize_rcu()<br />
put_pid() *** pid B reaches refcount 0 and is freed here ***<br />
get_pid() *** UAF ***<br />
synchronize_rcu()<br />
put_pid()<br />
<br />
As far as I know, this race can only occur with CONFIG_PREEMPT_RCU=y<br />
because it requires RCU to detect a quiescent state in code that is not<br />
explicitly calling into the scheduler.<br />
<br />
This race leads to use-after-free of a "struct pid".<br />
It is probably somewhat hard to hit because process A has to pass<br />
through a synchronize_rcu() operation while process B is between<br />
mutex_unlock() and get_pid().<br />
<br />
Fix it by ensuring that by the time a pointer to the current task&#39;s pid<br />
is stored in the file, an extra reference to the pid has been taken.<br />
<br />
This fix also removes the condition for synchronize_rcu(); I think<br />
that optimization is unnecessary complexity, since in that case we<br />
would usually have bailed out on the lockless check above.
Impact
Base Score 3.x
7.00
Severity 3.x
HIGH
Vulnerable products and versions
CPE | From | Up to |
---|---|---|
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.6.9 (including) | 6.6.37 (excluding) |
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.7 (including) | 6.9.8 (excluding) |
cpe:2.3:o:linux:linux_kernel:6.10:rc1:*:*:*:*:*:* | ||
cpe:2.3:o:linux:linux_kernel:6.10:rc2:*:*:*:*:*:* | ||
cpe:2.3:o:linux:linux_kernel:6.10:rc3:*:*:*:*:*:* | ||
cpe:2.3:o:linux:linux_kernel:6.10:rc4:*:*:*:*:*:* | ||
cpe:2.3:o:linux:linux_kernel:6.10:rc5:*:*:*:*:*:* |
To consult the complete list of CPE names with products and versions, see this page