CVE-2026-45960
Description
In the Linux kernel, the following vulnerability has been resolved:
hfsplus: return error when node already exists in hfs_bnode_create
When hfs_bnode_create() finds that a node is already hashed (which should not happen in normal operation), it currently returns the existing node without incrementing its reference count. This causes a reference count inconsistency that leads to a kernel panic when the node is later freed in hfs_bnode_put():
kernel BUG at fs/hfsplus/bnode.c:676! BUG_ON(!atomic_read(&node->refcnt))
This scenario can occur when hfs_bmap_alloc() attempts to allocate a node that is already in use (e.g., when node 0's bitmap bit is incorrectly unset), or due to filesystem corruption.
Returning an existing node from a create path is not normal operation.
Fix this by returning ERR_PTR(-EEXIST) instead of the node when it's already hashed. This properly signals the error condition to callers, which already check for IS_ERR() return values.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Returning already-hashed node from hfs_bnode_create causes refcount bug and kernel panic; fix returns -EEXIST instead.
Vulnerability
In the Linux kernel's HFS+ filesystem, the function hfs_bnode_create() at fs/hfsplus/bnode.c returns a node that is already hashed without incrementing its reference count, leading to a BUG_ON(!atomic_read(&node->refcnt)) panic in hfs_bnode_put(). This occurs when hfs_bmap_alloc() attempts to allocate a node already in use, often due to filesystem corruption [1].
Exploitation
An attacker cannot directly trigger this in normal operation. However, by providing a corrupted HFS+ filesystem image (e.g., via a mounted malicious volume), the kernel can call hfs_bmap_alloc() on an already-allocated node, causing the reference count inconsistency and subsequent panic. No authentication or special privileges are required beyond mounting the filesystem [2].
Impact
Successful exploitation results in a kernel panic, leading to a denial of service (system crash). There is no information disclosure or privilege escalation; the impact is limited to availability [1].
Mitigation
The fix changes hfs_bnode_create() to return ERR_PTR(-EEXIST) instead of the already-hashed node, preventing the refcount bug. The patch is included in stable kernel trees as commits d8a73cc46c84 and 507a1de58c21 [1][2]. Users should update to a kernel containing these commits. No workaround is available.
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
16d8a73cc46c84hfsplus: return error when node already exists in hfs_bnode_create
2 files changed · +2 −4
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 191661af967789..250a226336ea7a 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -629,7 +629,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 191661af967789..250a226336ea7a 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -629,7 +629,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
1ca428769cb4hfsplus: return error when node already exists in hfs_bnode_create
2 files changed · +2 −4
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 7c127922ac0c7e..1fa4a1d18b7b2a 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -640,7 +640,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 7c127922ac0c7e..1fa4a1d18b7b2a 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -640,7 +640,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
507a1de58c21hfsplus: return error when node already exists in hfs_bnode_create
2 files changed · +2 −4
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 7c127922ac0c7e..1fa4a1d18b7b2a 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -640,7 +640,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 7c127922ac0c7e..1fa4a1d18b7b2a 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -640,7 +640,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
986455135b95hfsplus: return error when node already exists in hfs_bnode_create
2 files changed · +2 −4
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index c0089849be50ed..fb437598e26259 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -629,7 +629,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index c0089849be50ed..fb437598e26259 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -629,7 +629,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
7b57ada854b3hfsplus: return error when node already exists in hfs_bnode_create
2 files changed · +2 −4
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index c0089849be50ed..fb437598e26259 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -629,7 +629,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index c0089849be50ed..fb437598e26259 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -629,7 +629,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
51838112d9c2hfsplus: return error when node already exists in hfs_bnode_create
2 files changed · +2 −4
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index c0089849be50ed..fb437598e26259 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -629,7 +629,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index c0089849be50ed..fb437598e26259 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -629,7 +629,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
2e6ff6a6fc69hfsplus: return error when node already exists in hfs_bnode_create
2 files changed · +2 −4
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 482a6c5faa1975..8e60e04c427bd2 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -629,7 +629,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 482a6c5faa1975..8e60e04c427bd2 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -629,7 +629,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
2e9185a42e0ehfsplus: return error when node already exists in hfs_bnode_create
2 files changed · +2 −4
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 191661af967789..250a226336ea7a 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -629,7 +629,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 191661af967789..250a226336ea7a 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -629,7 +629,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
1ca428769cb4hfsplus: return error when node already exists in hfs_bnode_create
2 files changed · +2 −4
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 7c127922ac0c7e..1fa4a1d18b7b2a 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -640,7 +640,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 7c127922ac0c7e..1fa4a1d18b7b2a 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -640,7 +640,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
2e6ff6a6fc69hfsplus: return error when node already exists in hfs_bnode_create
2 files changed · +2 −4
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 482a6c5faa1975..8e60e04c427bd2 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -629,7 +629,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 482a6c5faa1975..8e60e04c427bd2 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -629,7 +629,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
2e9185a42e0ehfsplus: return error when node already exists in hfs_bnode_create
2 files changed · +2 −4
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 191661af967789..250a226336ea7a 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -629,7 +629,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 191661af967789..250a226336ea7a 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -629,7 +629,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
507a1de58c21hfsplus: return error when node already exists in hfs_bnode_create
2 files changed · +2 −4
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 7c127922ac0c7e..1fa4a1d18b7b2a 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -640,7 +640,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 7c127922ac0c7e..1fa4a1d18b7b2a 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -640,7 +640,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
51838112d9c2hfsplus: return error when node already exists in hfs_bnode_create
2 files changed · +2 −4
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index c0089849be50ed..fb437598e26259 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -629,7 +629,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index c0089849be50ed..fb437598e26259 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -629,7 +629,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
7b57ada854b3hfsplus: return error when node already exists in hfs_bnode_create
2 files changed · +2 −4
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index c0089849be50ed..fb437598e26259 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -629,7 +629,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index c0089849be50ed..fb437598e26259 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -629,7 +629,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
986455135b95hfsplus: return error when node already exists in hfs_bnode_create
2 files changed · +2 −4
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index c0089849be50ed..fb437598e26259 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -629,7 +629,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index c0089849be50ed..fb437598e26259 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -629,7 +629,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
d8a73cc46c84hfsplus: return error when node already exists in hfs_bnode_create
2 files changed · +2 −4
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 191661af967789..250a226336ea7a 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -629,7 +629,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
fs/hfsplus/bnode.c+1 −2 modifieddiff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 191661af967789..250a226336ea7a 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -629,7 +629,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) if (node) { pr_crit("new node %u already hashed?\n", num); WARN_ON(1); - return node; + return ERR_PTR(-EEXIST); } node = __hfs_bnode_create(tree, num); if (!node) -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Missing reference count increment when hfs_bnode_create() returns an already-hashed node, causing a reference count inconsistency that triggers a kernel panic on subsequent free."
Attack vector
An attacker can trigger this bug by mounting a crafted or corrupted HFS+ filesystem that causes `hfs_bmap_alloc()` to attempt allocating a node that is already in use — for example, when node 0's bitmap bit is incorrectly unset [patch_id=2660971]. The call to `hfs_bnode_create()` finds the node already hashed and returns it without bumping the reference count, leading to a reference count inconsistency. When the node is later freed via `hfs_bnode_put()`, the `BUG_ON(!atomic_read(&node->refcnt))` at line 676 fires, causing a kernel panic (denial of service) [patch_id=2660971]. No special privileges beyond the ability to mount a malicious filesystem image are required.
Affected code
The vulnerable function is `hfs_bnode_create()` in `fs/hfsplus/bnode.c` [patch_id=2660971]. When `hfs_bnode_findhash()` returns a non-NULL node (meaning the node is already hashed), the function returned that existing node pointer directly without incrementing its reference count [patch_id=2660971].
What the fix does
The patch changes the `return node;` statement in `hfs_bnode_create()` to `return ERR_PTR(-EEXIST);` when `hfs_bnode_findhash()` finds the node already hashed [patch_id=2660971]. This ensures the function never returns a live node without a corresponding reference count increment. Callers already check for `IS_ERR()` return values, so the error is properly propagated instead of silently handing back an under-referenced node. The fix closes the reference-count inconsistency that caused the BUG_ON panic at `fs/hfsplus/bnode.c:676` [patch_id=2660971].
Preconditions
- inputAttacker must be able to mount a crafted or corrupted HFS+ filesystem image
- configThe filesystem must have a state where hfs_bmap_alloc() attempts to allocate an already-in-use node (e.g., node 0's bitmap bit incorrectly unset)
Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
8- git.kernel.org/stable/c/1ca428769cb4737a25bd32fb4d1573cc09eeaeefnvd
- git.kernel.org/stable/c/2e6ff6a6fc69cc17ed10c9cb6242935d52acd52dnvd
- git.kernel.org/stable/c/2e9185a42e0e237c74435fd092b7c34537c62156nvd
- git.kernel.org/stable/c/507a1de58c21c95ad7c44afccaf1222d1c42246bnvd
- git.kernel.org/stable/c/51838112d9c22502333c3085ca0c0d691e7093c6nvd
- git.kernel.org/stable/c/7b57ada854b32310f224abd61bcfec2d5790ff0anvd
- git.kernel.org/stable/c/986455135b95f32c1f142068e451098fc751749envd
- git.kernel.org/stable/c/d8a73cc46c8462a969a7516131feb3096f4c49d3nvd
News mentions
0No linked articles in our index yet.