FKIE_CVE-2024-39486
Vulnerability from fkie_nvd - Published: 2024-07-06 10:15 - Updated: 2024-11-21 09:27
Severity ?
Summary
In the Linux kernel, the following vulnerability has been resolved:
drm/drm_file: Fix pid refcounting race
<maarten.lankhorst@linux.intel.com>, Maxime Ripard
<mripard@kernel.org>, Thomas Zimmermann <tzimmermann@suse.de>
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, <pid B>, 1)
mutex_unlock(&dev->filelist_mutex)
begin drm_file_update_pid
mutex_lock(&dev->filelist_mutex)
rcu_replace_pointer(filp->pid, <pid A>, 1)
mutex_unlock(&dev->filelist_mutex)
get_pid(<pid A>)
synchronize_rcu()
put_pid(<pid B>) *** pid B reaches refcount 0 and is freed here ***
get_pid(<pid B>) *** UAF ***
synchronize_rcu()
put_pid(<pid A>)
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 that case we
would usually have bailed out on the lockless check above.
References
Impacted products
| Vendor | Product | Version | |
|---|---|---|---|
| linux | linux_kernel | * | |
| linux | linux_kernel | * | |
| linux | linux_kernel | 6.10 | |
| linux | linux_kernel | 6.10 | |
| linux | linux_kernel | 6.10 | |
| linux | linux_kernel | 6.10 | |
| linux | linux_kernel | 6.10 |
{
"configurations": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"matchCriteriaId": "A5921D6B-4FCC-4C29-8923-DE2113CE1C03",
"versionEndExcluding": "6.6.37",
"versionStartIncluding": "6.6.9",
"vulnerable": true
},
{
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"matchCriteriaId": "E95105F2-32E3-4C5F-9D18-7AEFD0E6275C",
"versionEndExcluding": "6.9.8",
"versionStartIncluding": "6.7",
"vulnerable": true
},
{
"criteria": "cpe:2.3:o:linux:linux_kernel:6.10:rc1:*:*:*:*:*:*",
"matchCriteriaId": "2EBB4392-5FA6-4DA9-9772-8F9C750109FA",
"vulnerable": true
},
{
"criteria": "cpe:2.3:o:linux:linux_kernel:6.10:rc2:*:*:*:*:*:*",
"matchCriteriaId": "331C2F14-12C7-45D5-893D-8C52EE38EA10",
"vulnerable": true
},
{
"criteria": "cpe:2.3:o:linux:linux_kernel:6.10:rc3:*:*:*:*:*:*",
"matchCriteriaId": "3173713D-909A-4DD3-9DD4-1E171EB057EE",
"vulnerable": true
},
{
"criteria": "cpe:2.3:o:linux:linux_kernel:6.10:rc4:*:*:*:*:*:*",
"matchCriteriaId": "79F18AFA-40F7-43F0-BA30-7BDB65F918B9",
"vulnerable": true
},
{
"criteria": "cpe:2.3:o:linux:linux_kernel:6.10:rc5:*:*:*:*:*:*",
"matchCriteriaId": "BD973AA4-A789-49BD-8D57-B2846935D3C7",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
]
}
],
"cveTags": [],
"descriptions": [
{
"lang": "en",
"value": "In the Linux kernel, the following vulnerability has been resolved:\n\ndrm/drm_file: Fix pid refcounting race\n\n\u003cmaarten.lankhorst@linux.intel.com\u003e, Maxime Ripard\n\u003cmripard@kernel.org\u003e, Thomas Zimmermann \u003ctzimmermann@suse.de\u003e\n\nfilp-\u003epid is supposed to be a refcounted pointer; however, before this\npatch, drm_file_update_pid() only increments the refcount of a struct\npid after storing a pointer to it in filp-\u003epid and dropping the\ndev-\u003efilelist_mutex, making the following race possible:\n\nprocess A process B\n========= =========\n begin drm_file_update_pid\n mutex_lock(\u0026dev-\u003efilelist_mutex)\n rcu_replace_pointer(filp-\u003epid, \u003cpid B\u003e, 1)\n mutex_unlock(\u0026dev-\u003efilelist_mutex)\nbegin drm_file_update_pid\nmutex_lock(\u0026dev-\u003efilelist_mutex)\nrcu_replace_pointer(filp-\u003epid, \u003cpid A\u003e, 1)\nmutex_unlock(\u0026dev-\u003efilelist_mutex)\nget_pid(\u003cpid A\u003e)\nsynchronize_rcu()\nput_pid(\u003cpid B\u003e) *** pid B reaches refcount 0 and is freed here ***\n get_pid(\u003cpid B\u003e) *** UAF ***\n synchronize_rcu()\n put_pid(\u003cpid A\u003e)\n\nAs far as I know, this race can only occur with CONFIG_PREEMPT_RCU=y\nbecause it requires RCU to detect a quiescent state in code that is not\nexplicitly calling into the scheduler.\n\nThis race leads to use-after-free of a \"struct pid\".\nIt is probably somewhat hard to hit because process A has to pass\nthrough a synchronize_rcu() operation while process B is between\nmutex_unlock() and get_pid().\n\nFix it by ensuring that by the time a pointer to the current task\u0027s pid\nis stored in the file, an extra reference to the pid has been taken.\n\nThis fix also removes the condition for synchronize_rcu(); I think\nthat optimization is unnecessary complexity, since in that case we\nwould usually have bailed out on the lockless check above."
},
{
"lang": "es",
"value": "En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: drm/drm_file: corrige la ejecuci\u00f3n de recuento de pid filp-\u0026gt;pid se supone que es un puntero recontado; sin embargo, antes de este parche, drm_file_update_pid() solo incrementa el recuento de una estructura pid despu\u00e9s de almacenar un puntero a ella en filp-\u0026gt;pid y eliminar dev-\u0026gt;filelist_mutex, haciendo posible la siguiente ejecuci\u00f3n: proceso A proceso B ==== ===== ========= comenzar drm_file_update_pid mutex_lock(\u0026amp;dev-\u0026gt;filelist_mutex) rcu_replace_pointer(filp-\u0026gt;pid, , 1) mutex_unlock(\u0026amp;dev-\u0026gt;filelist_mutex) begin drm_file_update_pid mutex_lock(\u0026amp;dev- \u0026gt;filelist_mutex) rcu_replace_pointer(filp-\u0026gt;pid, , 1) mutex_unlock(\u0026amp;dev-\u0026gt;filelist_mutex) get_pid() synchronize_rcu() put_pid() *** pid B alcanza refcount 0 y se libera aqu\u00ed *** get_pid() *** UAF *** synchronize_rcu() put_pid() Hasta donde yo s\u00e9, esta ejecuci\u00f3n solo puede ocurrir con CONFIG_PREEMPT_RCU=y porque requiere que RCU detecte un estado inactivo en el c\u00f3digo que no llame expl\u00edcitamente al programador. Esta ejecuci\u00f3n conduce a use after free de una \"estructura pid\". Probablemente sea algo dif\u00edcil de lograr porque el proceso A tiene que pasar por una operaci\u00f3n synchronize_rcu() mientras que el proceso B est\u00e1 entre mutex_unlock() y get_pid(). Solucionelo asegur\u00e1ndose de que cuando se almacene en el archivo un puntero al pid de la tarea actual, se haya tomado una referencia adicional al pid. Esta soluci\u00f3n tambi\u00e9n elimina la condici\u00f3n de synchronize_rcu(); Creo que la optimizaci\u00f3n es una complejidad innecesaria, ya que en ese caso normalmente habr\u00edamos abandonado la verificaci\u00f3n sin bloqueo anterior."
}
],
"id": "CVE-2024-39486",
"lastModified": "2024-11-21T09:27:47.623",
"metrics": {
"cvssMetricV31": [
{
"cvssData": {
"attackComplexity": "HIGH",
"attackVector": "LOCAL",
"availabilityImpact": "HIGH",
"baseScore": 7.0,
"baseSeverity": "HIGH",
"confidentialityImpact": "HIGH",
"integrityImpact": "HIGH",
"privilegesRequired": "LOW",
"scope": "UNCHANGED",
"userInteraction": "NONE",
"vectorString": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H",
"version": "3.1"
},
"exploitabilityScore": 1.0,
"impactScore": 5.9,
"source": "nvd@nist.gov",
"type": "Primary"
}
]
},
"published": "2024-07-06T10:15:03.393",
"references": [
{
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"tags": [
"Patch"
],
"url": "https://git.kernel.org/stable/c/0acce2a5c619ef1abdee783d7fea5eac78ce4844"
},
{
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"tags": [
"Patch"
],
"url": "https://git.kernel.org/stable/c/16682588ead4a593cf1aebb33b36df4d1e9e4ffa"
},
{
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"tags": [
"Patch"
],
"url": "https://git.kernel.org/stable/c/4f2a129b33a2054e62273edd5a051c34c08d96e9"
},
{
"source": "af854a3a-2127-422b-91ae-364da2661108",
"tags": [
"Patch"
],
"url": "https://git.kernel.org/stable/c/0acce2a5c619ef1abdee783d7fea5eac78ce4844"
},
{
"source": "af854a3a-2127-422b-91ae-364da2661108",
"tags": [
"Patch"
],
"url": "https://git.kernel.org/stable/c/16682588ead4a593cf1aebb33b36df4d1e9e4ffa"
},
{
"source": "af854a3a-2127-422b-91ae-364da2661108",
"tags": [
"Patch"
],
"url": "https://git.kernel.org/stable/c/4f2a129b33a2054e62273edd5a051c34c08d96e9"
}
],
"sourceIdentifier": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"vulnStatus": "Modified",
"weaknesses": [
{
"description": [
{
"lang": "en",
"value": "CWE-416"
}
],
"source": "nvd@nist.gov",
"type": "Primary"
}
]
}
Loading…
Loading…
Sightings
| Author | Source | Type | Date |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Loading…
Loading…