VYPR
Unrated severityNVD Advisory· Published Jun 8, 2026

CVE-2026-46299

CVE-2026-46299

Description

Linux kernel's HFS+ filesystem has a lock-after-free vulnerability in hfsplus_fill_super() that can be triggered during mount.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Linux kernel's HFS+ filesystem has a lock-after-free vulnerability in hfsplus_fill_super() that can be triggered during mount.

Vulnerability

In the Linux kernel, the HFS+ filesystem contains a vulnerability in the hfsplus_fill_super() function. This function calls hfs_find_init() which acquires tree->tree_lock. If a subsequent call to hfsplus_cat_build_key() fails, the function jumps to an error label without releasing the lock. The cleanup path then frees the tree data structure while the lock is still held, leading to a 'held lock freed' warning. This issue affects versions including v6.13-rc1 and the latest mainline kernel [1].

Exploitation

An attacker can trigger this vulnerability by mounting an HFS+ filesystem. Specifically, the error path can be exercised by dynamically shrinking the max_unistr_len parameter to 1 before hfsplus_asc2uni() is called. This causes hfsplus_asc2uni() to return -ENAMETOOLONG, which propagates to hfsplus_cat_build_key(), forcing the faulty error path and the subsequent lock-after-free condition during the mount process [1].

Impact

Successful exploitation of this vulnerability results in a 'held lock freed' warning, indicating a memory management issue. While the provided references do not detail a direct security impact such as information disclosure or code execution, the detected memory corruption can potentially lead to system instability or crashes when the HFS+ filesystem is mounted [1].

Mitigation

The vulnerability has been resolved by adding a missing hfs_find_exit(&fd) call before jumping to the out_put_root error label in hfsplus_fill_super(), ensuring proper lock release. This fix is available in the Linux kernel. No specific version or release date for the fix is provided in the available references, and no workarounds are disclosed [1].

AI Insight generated on Jun 8, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

2

Patches

10
90c500e4fd83

hfsplus: fix held lock freed on hfsplus_fill_super()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitZilin GuanMar 27, 2026Fixed in 7.1-rc1via kernel-cna
1 file changed · +3 2
  • fs/hfsplus/super.c+3 2 modified
    diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
    index 242ccca3acb7c..a36243b08c7cf 100644
    --- a/fs/hfsplus/super.c
    +++ b/fs/hfsplus/super.c
    @@ -569,8 +569,10 @@ static int hfsplus_fill_super(struct super_block *sb, struct fs_context *fc)
     	if (err)
     		goto out_put_root;
     	err = hfsplus_cat_build_key(sb, fd.search_key, HFSPLUS_ROOT_CNID, &str);
    -	if (unlikely(err < 0))
    +	if (unlikely(err < 0)) {
    +		hfs_find_exit(&fd);
     		goto out_put_root;
    +	}
     	if (!hfsplus_brec_read_cat(&fd, &entry)) {
     		hfs_find_exit(&fd);
     		if (entry.type != cpu_to_be16(HFSPLUS_FOLDER)) {
    -- 
    cgit 1.3-korg
    
    
    
bfbcce6a7b05

hfsplus: fix held lock freed on hfsplus_fill_super()

1 file changed · +3 2
  • fs/hfsplus/super.c+3 2 modified
    diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
    index 5ef0f71b1a330..67df3af9cf155 100644
    --- a/fs/hfsplus/super.c
    +++ b/fs/hfsplus/super.c
    @@ -569,8 +569,10 @@ static int hfsplus_fill_super(struct super_block *sb, struct fs_context *fc)
     	if (err)
     		goto out_put_root;
     	err = hfsplus_cat_build_key(sb, fd.search_key, HFSPLUS_ROOT_CNID, &str);
    -	if (unlikely(err < 0))
    +	if (unlikely(err < 0)) {
    +		hfs_find_exit(&fd);
     		goto out_put_root;
    +	}
     	if (!hfsplus_brec_read_cat(&fd, &entry)) {
     		hfs_find_exit(&fd);
     		if (entry.type != cpu_to_be16(HFSPLUS_FOLDER)) {
    -- 
    cgit 1.3-korg
    
    
    
d309d3308de6

hfsplus: fix held lock freed on hfsplus_fill_super()

1 file changed · +3 2
  • fs/hfsplus/super.c+3 2 modified
    diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
    index 59ea956c72018..e1e2833f528d1 100644
    --- a/fs/hfsplus/super.c
    +++ b/fs/hfsplus/super.c
    @@ -569,8 +569,10 @@ static int hfsplus_fill_super(struct super_block *sb, struct fs_context *fc)
     	if (err)
     		goto out_put_root;
     	err = hfsplus_cat_build_key(sb, fd.search_key, HFSPLUS_ROOT_CNID, &str);
    -	if (unlikely(err < 0))
    +	if (unlikely(err < 0)) {
    +		hfs_find_exit(&fd);
     		goto out_put_root;
    +	}
     	if (!hfsplus_brec_read_cat(&fd, &entry)) {
     		hfs_find_exit(&fd);
     		if (entry.type != cpu_to_be16(HFSPLUS_FOLDER)) {
    -- 
    cgit 1.3-korg
    
    
    
3ca80e3012c8

hfsplus: fix held lock freed on hfsplus_fill_super()

1 file changed · +3 2
  • fs/hfsplus/super.c+3 2 modified
    diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
    index 4790ddd92a8c1..0d15e440d6869 100644
    --- a/fs/hfsplus/super.c
    +++ b/fs/hfsplus/super.c
    @@ -539,8 +539,10 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
     	if (err)
     		goto out_put_root;
     	err = hfsplus_cat_build_key(sb, fd.search_key, HFSPLUS_ROOT_CNID, &str);
    -	if (unlikely(err < 0))
    +	if (unlikely(err < 0)) {
    +		hfs_find_exit(&fd);
     		goto out_put_root;
    +	}
     	if (!hfsplus_brec_read_cat(&fd, &entry)) {
     		hfs_find_exit(&fd);
     		if (entry.type != cpu_to_be16(HFSPLUS_FOLDER)) {
    -- 
    cgit 1.3-korg
    
    
    
041acda6d9f9

hfsplus: fix held lock freed on hfsplus_fill_super()

1 file changed · +3 2
  • fs/hfsplus/super.c+3 2 modified
    diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
    index fa90cc9fe93a9..3f7576d38ade9 100644
    --- a/fs/hfsplus/super.c
    +++ b/fs/hfsplus/super.c
    @@ -545,8 +545,10 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
     	if (err)
     		goto out_put_root;
     	err = hfsplus_cat_build_key(sb, fd.search_key, HFSPLUS_ROOT_CNID, &str);
    -	if (unlikely(err < 0))
    +	if (unlikely(err < 0)) {
    +		hfs_find_exit(&fd);
     		goto out_put_root;
    +	}
     	if (!hfsplus_brec_read_cat(&fd, &entry)) {
     		hfs_find_exit(&fd);
     		if (entry.type != cpu_to_be16(HFSPLUS_FOLDER)) {
    -- 
    cgit 1.3-korg
    
    
    
90c500e4fd83

hfsplus: fix held lock freed on hfsplus_fill_super()

1 file changed · +3 2
  • fs/hfsplus/super.c+3 2 modified
    diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
    index 242ccca3acb7c..a36243b08c7cf 100644
    --- a/fs/hfsplus/super.c
    +++ b/fs/hfsplus/super.c
    @@ -569,8 +569,10 @@ static int hfsplus_fill_super(struct super_block *sb, struct fs_context *fc)
     	if (err)
     		goto out_put_root;
     	err = hfsplus_cat_build_key(sb, fd.search_key, HFSPLUS_ROOT_CNID, &str);
    -	if (unlikely(err < 0))
    +	if (unlikely(err < 0)) {
    +		hfs_find_exit(&fd);
     		goto out_put_root;
    +	}
     	if (!hfsplus_brec_read_cat(&fd, &entry)) {
     		hfs_find_exit(&fd);
     		if (entry.type != cpu_to_be16(HFSPLUS_FOLDER)) {
    -- 
    cgit 1.3-korg
    
    
    
bfbcce6a7b05

hfsplus: fix held lock freed on hfsplus_fill_super()

1 file changed · +3 2
  • fs/hfsplus/super.c+3 2 modified
    diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
    index 5ef0f71b1a330..67df3af9cf155 100644
    --- a/fs/hfsplus/super.c
    +++ b/fs/hfsplus/super.c
    @@ -569,8 +569,10 @@ static int hfsplus_fill_super(struct super_block *sb, struct fs_context *fc)
     	if (err)
     		goto out_put_root;
     	err = hfsplus_cat_build_key(sb, fd.search_key, HFSPLUS_ROOT_CNID, &str);
    -	if (unlikely(err < 0))
    +	if (unlikely(err < 0)) {
    +		hfs_find_exit(&fd);
     		goto out_put_root;
    +	}
     	if (!hfsplus_brec_read_cat(&fd, &entry)) {
     		hfs_find_exit(&fd);
     		if (entry.type != cpu_to_be16(HFSPLUS_FOLDER)) {
    -- 
    cgit 1.3-korg
    
    
    
3ca80e3012c8

hfsplus: fix held lock freed on hfsplus_fill_super()

1 file changed · +3 2
  • fs/hfsplus/super.c+3 2 modified
    diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
    index 4790ddd92a8c1..0d15e440d6869 100644
    --- a/fs/hfsplus/super.c
    +++ b/fs/hfsplus/super.c
    @@ -539,8 +539,10 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
     	if (err)
     		goto out_put_root;
     	err = hfsplus_cat_build_key(sb, fd.search_key, HFSPLUS_ROOT_CNID, &str);
    -	if (unlikely(err < 0))
    +	if (unlikely(err < 0)) {
    +		hfs_find_exit(&fd);
     		goto out_put_root;
    +	}
     	if (!hfsplus_brec_read_cat(&fd, &entry)) {
     		hfs_find_exit(&fd);
     		if (entry.type != cpu_to_be16(HFSPLUS_FOLDER)) {
    -- 
    cgit 1.3-korg
    
    
    
d309d3308de6

hfsplus: fix held lock freed on hfsplus_fill_super()

1 file changed · +3 2
  • fs/hfsplus/super.c+3 2 modified
    diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
    index 59ea956c72018..e1e2833f528d1 100644
    --- a/fs/hfsplus/super.c
    +++ b/fs/hfsplus/super.c
    @@ -569,8 +569,10 @@ static int hfsplus_fill_super(struct super_block *sb, struct fs_context *fc)
     	if (err)
     		goto out_put_root;
     	err = hfsplus_cat_build_key(sb, fd.search_key, HFSPLUS_ROOT_CNID, &str);
    -	if (unlikely(err < 0))
    +	if (unlikely(err < 0)) {
    +		hfs_find_exit(&fd);
     		goto out_put_root;
    +	}
     	if (!hfsplus_brec_read_cat(&fd, &entry)) {
     		hfs_find_exit(&fd);
     		if (entry.type != cpu_to_be16(HFSPLUS_FOLDER)) {
    -- 
    cgit 1.3-korg
    
    
    
041acda6d9f9

hfsplus: fix held lock freed on hfsplus_fill_super()

1 file changed · +3 2
  • fs/hfsplus/super.c+3 2 modified
    diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
    index fa90cc9fe93a9..3f7576d38ade9 100644
    --- a/fs/hfsplus/super.c
    +++ b/fs/hfsplus/super.c
    @@ -545,8 +545,10 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
     	if (err)
     		goto out_put_root;
     	err = hfsplus_cat_build_key(sb, fd.search_key, HFSPLUS_ROOT_CNID, &str);
    -	if (unlikely(err < 0))
    +	if (unlikely(err < 0)) {
    +		hfs_find_exit(&fd);
     		goto out_put_root;
    +	}
     	if (!hfsplus_brec_read_cat(&fd, &entry)) {
     		hfs_find_exit(&fd);
     		if (entry.type != cpu_to_be16(HFSPLUS_FOLDER)) {
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Synthesis attempt was rejected by the grounding validator. Re-run pending.

References

5

News mentions

1