In the Linux kernel, the following vulnerability has been resolved:
hfsplus: fix missing hfsbnodeget() in _hfsbnode_create
When sync() and link() are called concurrently, both threads may enter hfsbnodefind() without finding the node in the hash table and proceed to create it.
Thread A: hfspluswriteinode() -> hfspluswritesysteminode() -> hfsbtreewrite() -> hfsbnodefind(tree, 0) -> _hfsbnodecreate(tree, 0)
Thread B: hfspluscreatecat() -> hfsbrecinsert() -> hfsbnodesplit() -> hfsbmapalloc() -> hfsbnodefind(tree, 0) -> _hfsbnode_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, hfsbnodefind() requires each call to take a reference. Here both threads end up setting refcnt=1. When they later put the node, this triggers:
BUGON(!atomicread(&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 hfsbnodeget() 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 hfsbnodeget() in _hfsbnode_create") but the same issue remained in HFS+ until now.
{
"cna_assigner": "Linux",
"osv_generated_from": "https://github.com/CVEProject/cvelistV5/tree/main/cves/2025/68xxx/CVE-2025-68774.json"
}