CVE-2026-46075
Description
In the Linux kernel, the following vulnerability has been resolved:
crypto: atmel-sha204a - Fix potential UAF and memory leak in remove path
Unregister the hwrng to prevent new ->read() calls and flush the Atmel I2C workqueue before teardown to prevent a potential UAF if a queued callback runs while the device is being removed.
Drop the early return to ensure sysfs entries are removed and ->hwrng.priv is freed, preventing a memory leak.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A UAF and memory leak in the Linux kernel's atmel-sha204a crypto driver are fixed by properly unregistering hwrng and flushing the workqueue before teardown.
Vulnerability
A use-after-free (UAF) and memory leak exist in the atmel-sha204a cryptographic hardware driver (ATECC508A/608A I2C crypto chip) in the Linux kernel. In the remove path, the driver does not unregister the hwrng interface before proceeding with teardown, allowing a ->read() callback to race with device removal and access freed memory [1]. Additionally, the Atmel I2C workqueue is not flushed before teardown, so a queued work item could still run and touch released structures. An early return in the remove function also prevents sysfs entries from being cleaned up and hwrng.priv from being freed, causing a memory leak. This affects kernel versions prior to the fix commit 1193c12126d3 [1].
Exploitation
To trigger the UAF, an attacker must have the ability to open and read from the /dev/hwrng character device (or otherwise invoke hwrng read operations) while the atmel-sha204a device is being removed from the system, for example via driver unbind or hot-unplug of the I2C device. The race window is between the start of the remove function and the actual freeing of the device data structures. If a hwrng read request arrives during this window, the driver will use already-freed memory, leading to a UAF. The memory leak is more straightforward: the early return means sysfs files for the device remain present, and the call that frees hwrng.priv is never executed on removal [1].
Impact
Successful exploitation of the UAF can lead to a kernel crash (denial of service) or potentially to arbitrary code execution in kernel context, depending on the state of the freed memory and the attacker's ability to control it. The memory leak gradually depletes kernel memory over repeated driver bind/unbind cycles or device hot-unplug events, which can contribute to system instability. The CVE description in the Linux kernel git commit confirms these issues and provides the fix [1].
Mitigation
The vulnerability is fixed in the Linux kernel commit 1193c12126d39bf986a5a9214827b73707b193ab [1]. This fix was applied to the stable kernel tree and released as part of incremental stable updates for versions 6.12 and later (exact version depends on the distribution's backport schedule). Users should update their kernel to a version containing this commit. No workaround is available; the vulnerability is in the driver's remove path, which is executed only during device removal, so the only mitigation is to avoid dynamic unbinding or hot-unplug of atmel-sha204a devices until the fixed kernel is deployed. The CVE is not listed in CISA's Known Exploited Vulnerabilities catalog as of the publication date.
AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
1Patches
10775c00d87c38crypto: atmel-sha204a - Fix potential UAF and memory leak in remove path
1 file changed · +2 −5
drivers/crypto/atmel-sha204a.c+2 −5 modifieddiff --git a/drivers/crypto/atmel-sha204a.c b/drivers/crypto/atmel-sha204a.c index 3501bc37d07162..c8c04c6101c3b7 100644 --- a/drivers/crypto/atmel-sha204a.c +++ b/drivers/crypto/atmel-sha204a.c @@ -194,10 +194,8 @@ static void atmel_sha204a_remove(struct i2c_client *client) { struct atmel_i2c_client_priv *i2c_priv = i2c_get_clientdata(client); - if (atomic_read(&i2c_priv->tfm_count)) { - dev_emerg(&client->dev, "Device is busy, will remove it anyhow\n"); - return; - } + devm_hwrng_unregister(&client->dev, &i2c_priv->hwrng); + atmel_i2c_flush_queue(); sysfs_remove_group(&client->dev.kobj, &atmel_sha204a_groups); -- cgit 1.3-korg
c5a45d14234bcrypto: atmel-sha204a - Fix potential UAF and memory leak in remove path
1 file changed · +2 −5
drivers/crypto/atmel-sha204a.c+2 −5 modifieddiff --git a/drivers/crypto/atmel-sha204a.c b/drivers/crypto/atmel-sha204a.c index 67fd084a2b9718..2cf5407818f146 100644 --- a/drivers/crypto/atmel-sha204a.c +++ b/drivers/crypto/atmel-sha204a.c @@ -125,10 +125,8 @@ static void atmel_sha204a_remove(struct i2c_client *client) { struct atmel_i2c_client_priv *i2c_priv = i2c_get_clientdata(client); - if (atomic_read(&i2c_priv->tfm_count)) { - dev_emerg(&client->dev, "Device is busy, will remove it anyhow\n"); - return; - } + devm_hwrng_unregister(&client->dev, &i2c_priv->hwrng); + atmel_i2c_flush_queue(); kfree((void *)i2c_priv->hwrng.priv); } -- cgit 1.3-korg
1193c12126d3crypto: atmel-sha204a - Fix potential UAF and memory leak in remove path
1 file changed · +2 −5
drivers/crypto/atmel-sha204a.c+2 −5 modifieddiff --git a/drivers/crypto/atmel-sha204a.c b/drivers/crypto/atmel-sha204a.c index 8f728cd7d740ea..3fece048529081 100644 --- a/drivers/crypto/atmel-sha204a.c +++ b/drivers/crypto/atmel-sha204a.c @@ -194,10 +194,8 @@ static void atmel_sha204a_remove(struct i2c_client *client) { struct atmel_i2c_client_priv *i2c_priv = i2c_get_clientdata(client); - if (atomic_read(&i2c_priv->tfm_count)) { - dev_emerg(&client->dev, "Device is busy, will remove it anyhow\n"); - return; - } + devm_hwrng_unregister(&client->dev, &i2c_priv->hwrng); + atmel_i2c_flush_queue(); sysfs_remove_group(&client->dev.kobj, &atmel_sha204a_groups); -- cgit 1.3-korg
bab1adf3b87ecrypto: atmel-sha204a - Fix potential UAF and memory leak in remove path
2 files changed · +4 −10
drivers/crypto/atmel-sha204a.c+2 −5 modifieddiff --git a/drivers/crypto/atmel-sha204a.c b/drivers/crypto/atmel-sha204a.c index 691531647fd656..dbb39ed0cea114 100644 --- a/drivers/crypto/atmel-sha204a.c +++ b/drivers/crypto/atmel-sha204a.c @@ -194,10 +194,8 @@ static void atmel_sha204a_remove(struct i2c_client *client) { struct atmel_i2c_client_priv *i2c_priv = i2c_get_clientdata(client); - if (atomic_read(&i2c_priv->tfm_count)) { - dev_emerg(&client->dev, "Device is busy, will remove it anyhow\n"); - return; - } + devm_hwrng_unregister(&client->dev, &i2c_priv->hwrng); + atmel_i2c_flush_queue(); sysfs_remove_group(&client->dev.kobj, &atmel_sha204a_groups); -- cgit 1.3-korg
drivers/crypto/atmel-sha204a.c+2 −5 modifieddiff --git a/drivers/crypto/atmel-sha204a.c b/drivers/crypto/atmel-sha204a.c index 691531647fd656..dbb39ed0cea114 100644 --- a/drivers/crypto/atmel-sha204a.c +++ b/drivers/crypto/atmel-sha204a.c @@ -194,10 +194,8 @@ static void atmel_sha204a_remove(struct i2c_client *client) { struct atmel_i2c_client_priv *i2c_priv = i2c_get_clientdata(client); - if (atomic_read(&i2c_priv->tfm_count)) { - dev_emerg(&client->dev, "Device is busy, will remove it anyhow\n"); - return; - } + devm_hwrng_unregister(&client->dev, &i2c_priv->hwrng); + atmel_i2c_flush_queue(); sysfs_remove_group(&client->dev.kobj, &atmel_sha204a_groups); -- cgit 1.3-korg
31901371ccd1crypto: atmel-sha204a - Fix potential UAF and memory leak in remove path
2 files changed · +4 −10
drivers/crypto/atmel-sha204a.c+2 −5 modifieddiff --git a/drivers/crypto/atmel-sha204a.c b/drivers/crypto/atmel-sha204a.c index 72c9d74d3062ef..b3660f01d89ce8 100644 --- a/drivers/crypto/atmel-sha204a.c +++ b/drivers/crypto/atmel-sha204a.c @@ -194,10 +194,8 @@ static void atmel_sha204a_remove(struct i2c_client *client) { struct atmel_i2c_client_priv *i2c_priv = i2c_get_clientdata(client); - if (atomic_read(&i2c_priv->tfm_count)) { - dev_emerg(&client->dev, "Device is busy, will remove it anyhow\n"); - return; - } + devm_hwrng_unregister(&client->dev, &i2c_priv->hwrng); + atmel_i2c_flush_queue(); sysfs_remove_group(&client->dev.kobj, &atmel_sha204a_groups); -- cgit 1.3-korg
drivers/crypto/atmel-sha204a.c+2 −5 modifieddiff --git a/drivers/crypto/atmel-sha204a.c b/drivers/crypto/atmel-sha204a.c index 72c9d74d3062ef..b3660f01d89ce8 100644 --- a/drivers/crypto/atmel-sha204a.c +++ b/drivers/crypto/atmel-sha204a.c @@ -194,10 +194,8 @@ static void atmel_sha204a_remove(struct i2c_client *client) { struct atmel_i2c_client_priv *i2c_priv = i2c_get_clientdata(client); - if (atomic_read(&i2c_priv->tfm_count)) { - dev_emerg(&client->dev, "Device is busy, will remove it anyhow\n"); - return; - } + devm_hwrng_unregister(&client->dev, &i2c_priv->hwrng); + atmel_i2c_flush_queue(); sysfs_remove_group(&client->dev.kobj, &atmel_sha204a_groups); -- cgit 1.3-korg
1193c12126d3crypto: atmel-sha204a - Fix potential UAF and memory leak in remove path
1 file changed · +2 −5
drivers/crypto/atmel-sha204a.c+2 −5 modifieddiff --git a/drivers/crypto/atmel-sha204a.c b/drivers/crypto/atmel-sha204a.c index 8f728cd7d740ea..3fece048529081 100644 --- a/drivers/crypto/atmel-sha204a.c +++ b/drivers/crypto/atmel-sha204a.c @@ -194,10 +194,8 @@ static void atmel_sha204a_remove(struct i2c_client *client) { struct atmel_i2c_client_priv *i2c_priv = i2c_get_clientdata(client); - if (atomic_read(&i2c_priv->tfm_count)) { - dev_emerg(&client->dev, "Device is busy, will remove it anyhow\n"); - return; - } + devm_hwrng_unregister(&client->dev, &i2c_priv->hwrng); + atmel_i2c_flush_queue(); sysfs_remove_group(&client->dev.kobj, &atmel_sha204a_groups); -- cgit 1.3-korg
31901371ccd1crypto: atmel-sha204a - Fix potential UAF and memory leak in remove path
1 file changed · +2 −5
drivers/crypto/atmel-sha204a.c+2 −5 modifieddiff --git a/drivers/crypto/atmel-sha204a.c b/drivers/crypto/atmel-sha204a.c index 72c9d74d3062ef..b3660f01d89ce8 100644 --- a/drivers/crypto/atmel-sha204a.c +++ b/drivers/crypto/atmel-sha204a.c @@ -194,10 +194,8 @@ static void atmel_sha204a_remove(struct i2c_client *client) { struct atmel_i2c_client_priv *i2c_priv = i2c_get_clientdata(client); - if (atomic_read(&i2c_priv->tfm_count)) { - dev_emerg(&client->dev, "Device is busy, will remove it anyhow\n"); - return; - } + devm_hwrng_unregister(&client->dev, &i2c_priv->hwrng); + atmel_i2c_flush_queue(); sysfs_remove_group(&client->dev.kobj, &atmel_sha204a_groups); -- cgit 1.3-korg
775c00d87c38crypto: atmel-sha204a - Fix potential UAF and memory leak in remove path
1 file changed · +2 −5
drivers/crypto/atmel-sha204a.c+2 −5 modifieddiff --git a/drivers/crypto/atmel-sha204a.c b/drivers/crypto/atmel-sha204a.c index 3501bc37d07162..c8c04c6101c3b7 100644 --- a/drivers/crypto/atmel-sha204a.c +++ b/drivers/crypto/atmel-sha204a.c @@ -194,10 +194,8 @@ static void atmel_sha204a_remove(struct i2c_client *client) { struct atmel_i2c_client_priv *i2c_priv = i2c_get_clientdata(client); - if (atomic_read(&i2c_priv->tfm_count)) { - dev_emerg(&client->dev, "Device is busy, will remove it anyhow\n"); - return; - } + devm_hwrng_unregister(&client->dev, &i2c_priv->hwrng); + atmel_i2c_flush_queue(); sysfs_remove_group(&client->dev.kobj, &atmel_sha204a_groups); -- cgit 1.3-korg
bab1adf3b87ecrypto: atmel-sha204a - Fix potential UAF and memory leak in remove path
1 file changed · +2 −5
drivers/crypto/atmel-sha204a.c+2 −5 modifieddiff --git a/drivers/crypto/atmel-sha204a.c b/drivers/crypto/atmel-sha204a.c index 691531647fd656..dbb39ed0cea114 100644 --- a/drivers/crypto/atmel-sha204a.c +++ b/drivers/crypto/atmel-sha204a.c @@ -194,10 +194,8 @@ static void atmel_sha204a_remove(struct i2c_client *client) { struct atmel_i2c_client_priv *i2c_priv = i2c_get_clientdata(client); - if (atomic_read(&i2c_priv->tfm_count)) { - dev_emerg(&client->dev, "Device is busy, will remove it anyhow\n"); - return; - } + devm_hwrng_unregister(&client->dev, &i2c_priv->hwrng); + atmel_i2c_flush_queue(); sysfs_remove_group(&client->dev.kobj, &atmel_sha204a_groups); -- cgit 1.3-korg
c5a45d14234bcrypto: atmel-sha204a - Fix potential UAF and memory leak in remove path
1 file changed · +2 −5
drivers/crypto/atmel-sha204a.c+2 −5 modifieddiff --git a/drivers/crypto/atmel-sha204a.c b/drivers/crypto/atmel-sha204a.c index 67fd084a2b9718..2cf5407818f146 100644 --- a/drivers/crypto/atmel-sha204a.c +++ b/drivers/crypto/atmel-sha204a.c @@ -125,10 +125,8 @@ static void atmel_sha204a_remove(struct i2c_client *client) { struct atmel_i2c_client_priv *i2c_priv = i2c_get_clientdata(client); - if (atomic_read(&i2c_priv->tfm_count)) { - dev_emerg(&client->dev, "Device is busy, will remove it anyhow\n"); - return; - } + devm_hwrng_unregister(&client->dev, &i2c_priv->hwrng); + atmel_i2c_flush_queue(); kfree((void *)i2c_priv->hwrng.priv); } -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Early return in remove path skips hwrng unregistration, workqueue flush, sysfs cleanup, and memory deallocation, leading to use-after-free and memory leak."
Attack vector
An attacker with the ability to trigger device removal (e.g., unbinding the I2C driver or hot-unplugging the Atmel SHA204A device) while the hardware random number generator is in use can cause a use-after-free. The old `remove` path returned early when `tfm_count` was non-zero, leaving the hwrng registered and the I2C workqueue active. A queued work callback could then access freed device memory after the device is torn down. Additionally, the early return prevented `sysfs_remove_group()` and `kfree()` from running, causing a memory leak of `hwrng.priv` [patch_id=2659923].
Affected code
The vulnerability is in the `atmel_sha204a_remove()` function in `drivers/crypto/atmel-sha204a.c` [patch_id=2659923]. The original code checked `atomic_read(&i2c_priv->tfm_count)` and returned early if the device was busy, skipping cleanup of sysfs entries, the hwrng, and the workqueue.
What the fix does
The patch replaces the early-return guard (`if (atomic_read(&i2c_priv->tfm_count)) return;`) with two proactive teardown steps: `devm_hwrng_unregister()` to prevent new `->read()` calls, and `atmel_i2c_flush_queue()` to drain any pending workqueue items before the device state is freed [patch_id=2659923]. By removing the early return, the function always proceeds to `sysfs_remove_group()` and (in the backport variants) `kfree(i2c_priv->hwrng.priv)`, eliminating the memory leak [patch_id=2659918].
Preconditions
- configThe Atmel SHA204A I2C driver must be loaded and the device must be in use (tfm_count > 0) at the time of removal
- inputAttacker must be able to trigger device removal (e.g., driver unbind, hot-unplug)
Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- git.kernel.org/stable/c/1193c12126d39bf986a5a9214827b73707b193abnvd
- git.kernel.org/stable/c/31901371ccd16b42d2f167b1018ba9ae8bd5a6c7nvd
- git.kernel.org/stable/c/775c00d87c385b758da9504cf053acea00e2ed40nvd
- git.kernel.org/stable/c/bab1adf3b87e4bfac92c4f5963c63db434d561c1nvd
- git.kernel.org/stable/c/c5a45d14234bf26e28a89e3a5dcc08336595cf11nvd
News mentions
0No linked articles in our index yet.