drm/drm_file: Fix pid refcounting race
In the Linux kernel, the following vulnerability has been resolved: drm/drm_file: Fix pid refcounting race , Maxime Ripard , Thomas Zimmermann filp->pid is supposed to be a refcounted pointer; however, before this patch, drm_file_update_pid() only increments the refcount of a struct pid after storing a pointer to it in filp->pid and dropping the dev->filelist_mutex, making the following race possible: process A process B ========= ========= begin drm_file_update_pid mutex_lock(&dev->filelist_mutex) rcu_replace_pointer(filp->pid, , 1) mutex_unlock(&dev->filelist_mutex) begin drm_file_update_pid mutex_lock(&dev->filelist_mutex) rcu_replace_pointer(filp->pid, , 1) mutex_unlock(&dev->filelist_mutex) get_pid() synchronize_rcu() put_pid() *** pid B reaches refcount 0 and is freed here *** get_pid() *** UAF *** synchronize_rcu() put_pid() As far as I know, this race can only occur with CONFIG_PREEMPT_RCU=y because it requires RCU to detect a quiescent state in code that is not explicitly calling into the scheduler. This race leads to use-after-free of a "struct pid". It is probably somewhat hard to hit because process A has to pass through a synchronize_rcu() operation while process B is between mutex_unlock() and get_pid(). Fix it by ensuring that by the time a pointer to the current task's pid is stored in the file, an extra reference to the pid has been taken. This fix also removes the condition for synchronize_rcu(); I think that optimization is unnecessary complexity, since in
- Products
- Kernel
- Affected versions
- Not specified
- Fixed versions
- 6.6.37, 6.9.8
- CVEs
- CVE-2024-39486
- Confirmed fixed CVEs
- Not specified
- Updated in this feed
- 7 Nov 2026, 14:29 UTC · Revision 1
Source evidence
In the Linux kernel, the following vulnerability has been resolved: drm/drm_file: Fix pid refcounting race , Maxime Ripard , Thomas Zimmermann filp->pid is supposed to be a refcounted pointer; however, before this patch, drm_file_update_pid() only increments the refcount of a struct pid after storing a pointer to it in filp->pid and dropping the dev->filelist_mutex, making the following race possible: process A process B ========= ========= begin drm_file_update_pid mutex_lock(&dev->filelist_mutex) rcu_replace_pointer(filp->pid, , 1) mutex_unlock(&dev->filelist_mutex) begin drm_file_update_pid mutex_lock(&dev->filelist_mutex) rcu_replace_pointer(filp->pid, , 1) mutex_unlock(&dev->filelist_mutex) get_pid() synchronize_rcu() put_pid() *** pid B reaches refcount 0 and is freed here *** get_pid() *** UAF *** synchronize_rcu() put_pid() As far as I know, this race can only occur with CONFIG_PREEMPT_RCU=y because it requires RCU to detect a quiescent state in code that is not explicitly calling into the scheduler. This race leads to use-after-free of a "struct pid". It is probably somewhat hard to hit because process A has to pass through a synchronize_rcu() operation while process B is between mutex_unlock() and get_pid(). Fix it by ensuring that by the time a pointer to the current task's pid is stored in the file, an extra reference to the pid has been taken. This fix also removes the condition for synchronize_rcu(); I think that optimization is unnecessary complexity, since in
osv:CVE-2024-39486
Kernel
Fixed versions: 6.6.37, 6.9.8
Complete source record
{
"id": "c00ea1287074260dd570556bfa7bbf660fe01e11fdb8fedd1696c1666fdb80d0",
"url": "https://osv.dev/vulnerability/CVE-2024-39486",
"method": "structured",
"payload": {
"kind": "advisory",
"title": "drm/drm_file: Fix pid refcounting race",
"summary": "In the Linux kernel, the following vulnerability has been resolved: drm/drm_file: Fix pid refcounting race , Maxime Ripard , Thomas Zimmermann filp->pid is supposed to be a refcounted pointer; however, before this patch, drm_file_update_pid() only increments the refcount of a struct pid after storing a pointer to it in filp->pid and dropping the dev->filelist_mutex, making the following race possible: process A process B ========= ========= begin drm_file_update_pid mutex_lock(&dev->filelist_mutex) rcu_replace_pointer(filp->pid, , 1) mutex_unlock(&dev->filelist_mutex) begin drm_file_update_pid mutex_lock(&dev->filelist_mutex) rcu_replace_pointer(filp->pid, , 1) mutex_unlock(&dev->filelist_mutex) get_pid() synchronize_rcu() put_pid() *** pid B reaches refcount 0 and is freed here *** get_pid() *** UAF *** synchronize_rcu() put_pid() As far as I know, this race can only occur with CONFIG_PREEMPT_RCU=y because it requires RCU to detect a quiescent state in code that is not explicitly calling into the scheduler. This race leads to use-after-free of a \"struct pid\". It is probably somewhat hard to hit because process A has to pass through a synchronize_rcu() operation while process B is between mutex_unlock() and get_pid(). Fix it by ensuring that by the time a pointer to the current task's pid is stored in the file, an extra reference to the pid has been taken. This fix also removes the condition for synchronize_rcu(); I think that optimization is unnecessary complexity, since in ",
"evidence": "osv:CVE-2024-39486",
"products": [
{
"name": {
"value": "Kernel",
"evidence": "/affected/1/package/name"
},
"prerequisites": [],
"fixed_versions": [
{
"value": "6.6.37",
"evidence": "/affected/1/ranges"
},
{
"value": "6.9.8",
"evidence": "/affected/1/ranges"
}
],
"affected_versions": []
}
],
"severity": "high",
"structured": {
"id": "CVE-2024-39486",
"aliases": [
"CVE-2024-39486"
],
"metrics": [
{
"type": "CVSS_V3",
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H"
}
],
"affected": [
{
"ranges": [
{
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"type": "GIT",
"events": [
{
"introduced": "031ddd28008971cce0b5626379b910d0a05fb4dd"
},
{
"fixed": "16682588ead4a593cf1aebb33b36df4d1e9e4ffa"
}
]
},
{
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"type": "GIT",
"events": [
{
"introduced": "1c7a387ffef894b1ab3942f0482dac7a6e0a909c"
},
{
"fixed": "0acce2a5c619ef1abdee783d7fea5eac78ce4844"
},
{
"fixed": "4f2a129b33a2054e62273edd5a051c34c08d96e9"
}
]
},
{
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"type": "GIT",
"events": [
{
"introduced": "6.6.9"
},
{
"fixed": "6.6.37"
}
]
}
],
"versions": [
"v6.6.36",
"v6.6.35",
"v6.6.34",
"v6.6.33",
"v6.6.32",
"v6.6.31",
"v6.6.30",
"v6.6.29",
"v6.6.28",
"v6.6.27",
"v6.6.26",
"v6.6.25",
"v6.6.24",
"v6.6.23",
"v6.6.22",
"v6.6.21",
"v6.6.20",
"v6.6.19",
"v6.6.18",
"v6.6.17",
"v6.6.16",
"v6.6.15",
"v6.6.14",
"v6.6.13",
"v6.6.12",
"v6.6.11",
"v6.6.10",
"v6.6.9"
],
"database_specific": {
"source": "https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2024-39486.json"
}
},
{
"ranges": [
{
"type": "ECOSYSTEM",
"events": [
{
"introduced": "0"
},
{
"fixed": "6.6.37"
}
]
},
{
"type": "ECOSYSTEM",
"events": [
{
"introduced": "6.7.0"
},
{
"fixed": "6.9.8"
}
]
}
],
"package": {
"name": "Kernel",
"ecosystem": "Linux"
},
"database_specific": {
"source": "https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2024-39486.json"
}
}
],
"modified": "2026-10-28T02:30:51.399473029Z",
"provider": "osv",
"references": [
"https://git.kernel.org/stable/c/0acce2a5c619ef1abdee783d7fea5eac78ce4844",
"https://git.kernel.org/stable/c/16682588ead4a593cf1aebb33b36df4d1e9e4ffa",
"https://git.kernel.org/stable/c/4f2a129b33a2054e62273edd5a051c34c08d96e9",
"https://github.com/CVEProject/cvelistV5/tree/main/cves/2024/39xxx/CVE-2024-39486.json",
"https://nvd.nist.gov/vuln/detail/CVE-2024-39486",
"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git"
],
"provider_metadata": {
"cna_assigner": "Linux",
"osv_generated_from": "https://github.com/CVEProject/cvelistV5/tree/main/cves/2024/39xxx/CVE-2024-39486.json"
}
},
"related_cves": [
{
"value": "CVE-2024-39486",
"evidence": "/id"
}
],
"security_relevant": true,
"severity_evidence": "/severity/0/score"
},
"source_id": "core-osv",
"document_id": 519633,
"published_at": "2024-07-06T09:25:21.514+00:00"
}