FKIE_CVE-2025-68774
Vulnerability from fkie_nvd - Published: 2026-01-13 16:15 - Updated: 2026-04-15 00:35
Severity ?
Summary
In the Linux kernel, the following vulnerability has been resolved:
hfsplus: fix missing hfs_bnode_get() in __hfs_bnode_create
When sync() and link() are called concurrently, both threads may
enter hfs_bnode_find() without finding the node in the hash table
and proceed to create it.
Thread A:
hfsplus_write_inode()
-> hfsplus_write_system_inode()
-> hfs_btree_write()
-> hfs_bnode_find(tree, 0)
-> __hfs_bnode_create(tree, 0)
Thread B:
hfsplus_create_cat()
-> hfs_brec_insert()
-> hfs_bnode_split()
-> hfs_bmap_alloc()
-> hfs_bnode_find(tree, 0)
-> __hfs_bnode_create(tree, 0)
In this case, thread A creates the bnode, sets refcnt=1, and hashes it.
Thread B also tries to create the same bnode, notices it has already
been inserted, drops its own instance, and uses the hashed one without
getting the node.
```
node2 = hfs_bnode_findhash(tree, cnid);
if (!node2) { <- Thread A
hash = hfs_bnode_hash(cnid);
node->next_hash = tree->node_hash[hash];
tree->node_hash[hash] = node;
tree->node_hash_cnt++;
} else { <- Thread B
spin_unlock(&tree->hash_lock);
kfree(node);
wait_event(node2->lock_wq,
!test_bit(HFS_BNODE_NEW, &node2->flags));
return node2;
}
```
However, hfs_bnode_find() requires each call to take a reference.
Here both threads end up setting refcnt=1. When they later put the node,
this triggers:
BUG_ON(!atomic_read(&node->refcnt))
In this scenario, Thread B in fact finds the node in the hash table
rather than creating a new one, and thus must take a reference.
Fix this by calling hfs_bnode_get() when reusing a bnode newly created by
another thread to ensure the refcount is updated correctly.
A similar bug was fixed in HFS long ago in commit
a9dc087fd3c4 ("fix missing hfs_bnode_get() in __hfs_bnode_create")
but the same issue remained in HFS+ until now.
References
Impacted products
| Vendor | Product | Version |
|---|
{
"cveTags": [],
"descriptions": [
{
"lang": "en",
"value": "In the Linux kernel, the following vulnerability has been resolved:\n\nhfsplus: fix missing hfs_bnode_get() in __hfs_bnode_create\n\nWhen sync() and link() are called concurrently, both threads may\nenter hfs_bnode_find() without finding the node in the hash table\nand proceed to create it.\n\nThread A:\n hfsplus_write_inode()\n -\u003e hfsplus_write_system_inode()\n -\u003e hfs_btree_write()\n -\u003e hfs_bnode_find(tree, 0)\n -\u003e __hfs_bnode_create(tree, 0)\n\nThread B:\n hfsplus_create_cat()\n -\u003e hfs_brec_insert()\n -\u003e hfs_bnode_split()\n -\u003e hfs_bmap_alloc()\n -\u003e hfs_bnode_find(tree, 0)\n -\u003e __hfs_bnode_create(tree, 0)\n\nIn this case, thread A creates the bnode, sets refcnt=1, and hashes it.\nThread B also tries to create the same bnode, notices it has already\nbeen inserted, drops its own instance, and uses the hashed one without\ngetting the node.\n\n```\n\n\tnode2 = hfs_bnode_findhash(tree, cnid);\n\tif (!node2) { \u003c- Thread A\n\t\thash = hfs_bnode_hash(cnid);\n\t\tnode-\u003enext_hash = tree-\u003enode_hash[hash];\n\t\ttree-\u003enode_hash[hash] = node;\n\t\ttree-\u003enode_hash_cnt++;\n\t} else { \u003c- Thread B\n\t\tspin_unlock(\u0026tree-\u003ehash_lock);\n\t\tkfree(node);\n\t\twait_event(node2-\u003elock_wq,\n\t\t\t!test_bit(HFS_BNODE_NEW, \u0026node2-\u003eflags));\n\t\treturn node2;\n\t}\n```\n\nHowever, hfs_bnode_find() requires each call to take a reference.\nHere both threads end up setting refcnt=1. When they later put the node,\nthis triggers:\n\nBUG_ON(!atomic_read(\u0026node-\u003erefcnt))\n\nIn this scenario, Thread B in fact finds the node in the hash table\nrather than creating a new one, and thus must take a reference.\n\nFix this by calling hfs_bnode_get() when reusing a bnode newly created by\nanother thread to ensure the refcount is updated correctly.\n\nA similar bug was fixed in HFS long ago in commit\na9dc087fd3c4 (\"fix missing hfs_bnode_get() in __hfs_bnode_create\")\nbut the same issue remained in HFS+ until now."
},
{
"lang": "es",
"value": "En el kernel de Linux, la siguiente vulnerabilidad ha sido resuelta:\n\nhfsplus: corrige la falta de hfs_bnode_get() en __hfs_bnode_create\n\nCuando sync() y link() se llaman concurrentemente, ambos hilos pueden entrar en hfs_bnode_find() sin encontrar el nodo en la tabla hash y proceder a crearlo.\n\nHilo A:\n hfsplus_write_inode()\n -\u0026gt; hfsplus_write_system_inode()\n -\u0026gt; hfs_btree_write()\n -\u0026gt; hfs_bnode_find(tree, 0)\n -\u0026gt; __hfs_bnode_create(tree, 0)\n\nHilo B:\n hfsplus_create_cat()\n -\u0026gt; hfs_brec_insert()\n -\u0026gt; hfs_bnode_split()\n -\u0026gt; hfs_bmap_alloc()\n -\u0026gt; hfs_bnode_find(tree, 0)\n -\u0026gt; __hfs_bnode_create(tree, 0)\n\nEn este caso, el hilo A crea el bnode, establece refcnt=1 y lo hashea. El hilo B tambi\u00e9n intenta crear el mismo bnode, nota que ya ha sido insertado, descarta su propia instancia y usa el hasheado sin obtener el nodo.\n\n```\n\n\tnode2 = hfs_bnode_findhash(tree, cnid);\n\tif (!node2) { \u0026lt;- Hilo A\n\t\thash = hfs_bnode_hash(cnid);\n\t\tnode-\u0026gt;next_hash = tree-\u0026gt;node_hash[hash];\n\t\ttree-\u0026gt;node_hash[hash] = node;\n\t\ttree-\u0026gt;node_hash_cnt++;\n\t} else { \u0026lt;- Hilo B\n\t\tspin_unlock(\u0026amp;tree-\u0026gt;hash_lock);\n\t\tkfree(node);\n\t\twait_event(node2-\u0026gt;lock_wq,\n\t\t\t!test_bit(HFS_BNODE_NEW, \u0026amp;node2-\u0026gt;flags));\n\t\treturn node2;\n\t}\n```\n\nSin embargo, hfs_bnode_find() requiere que cada llamada tome una referencia. Aqu\u00ed ambos hilos terminan estableciendo refcnt=1. Cuando m\u00e1s tarde liberan el nodo, esto dispara:\n\nBUG_ON(!atomic_read(\u0026amp;node-\u0026gt;refcnt))\n\nEn este escenario, el Hilo B de hecho encuentra el nodo en la tabla hash en lugar de crear uno nuevo, y por lo tanto debe tomar una referencia.\n\nSolucione esto llamando a hfs_bnode_get() al reutilizar un bnode reci\u00e9n creado por otro hilo para asegurar que el contador de referencias se actualice correctamente.\n\nUn error similar fue corregido en HFS hace mucho tiempo en el commit a9dc087fd3c4 (\u0027corrige la falta de hfs_bnode_get() en __hfs_bnode_create\u0027) pero el mismo problema permaneci\u00f3 en HFS+ hasta ahora."
}
],
"id": "CVE-2025-68774",
"lastModified": "2026-04-15T00:35:42.020",
"metrics": {},
"published": "2026-01-13T16:15:56.960",
"references": [
{
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"url": "https://git.kernel.org/stable/c/152af114287851583cf7e0abc10129941f19466a"
},
{
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"url": "https://git.kernel.org/stable/c/39e149d58ef4d7883cbf87448d39d51292fd342d"
},
{
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"url": "https://git.kernel.org/stable/c/3b0fc7af50b896d0f3d104e70787ba1973bc0b56"
},
{
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"url": "https://git.kernel.org/stable/c/457f795e7abd7770de10216d7f9994a3f12a56d6"
},
{
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"url": "https://git.kernel.org/stable/c/5882e7c8cdbb5e254a69628b780acff89c78071e"
},
{
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"url": "https://git.kernel.org/stable/c/b68dc4134b18a3922cd33439ec614aad4172bc86"
},
{
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"url": "https://git.kernel.org/stable/c/b9d1c6bb5f19460074ce9862cb80be86b5fb0a50"
}
],
"sourceIdentifier": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"vulnStatus": "Deferred"
}
Loading…
Loading…
Experimental. This forecast is provided for visualization only and may change without notice. Do not use it for operational decisions.
Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.
Sightings
| Author | Source | Type | Date | Other |
|---|
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…