mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
fs/ntfs3: add depth limit to indx_find_buffer to prevent stack overflow
indx_find_buffer() recursively descends the B+ tree index with no depth limit. A crafted NTFS image with circular index node references causes unbounded recursion, overflowing the kernel stack and panicking the system. This is reachable by mounting a malicious NTFS filesystem (e.g. from a USB drive via desktop automount) and deleting a file whose index entry triggers the rebalancing fallback path in indx_delete_entry(). Add a depth parameter and bail out with -EINVAL when it reaches the fnd->nodes array bound, matching the constraint already enforced by fnd_push() in indx_find(). The related function indx_find() was previously patched for a similar infinite-loop issue (commit1732053c8a), but indx_find_buffer() was missed. Fixes:82cae269cf("fs/ntfs3: Add initialization of super block") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4-6 Assisted-by: Codex:gpt-5-4 Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com> Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
This commit is contained in:
parent
254f49634e
commit
1ebd684b8f
|
|
@ -2022,13 +2022,21 @@ int indx_insert_entry(struct ntfs_index *indx, struct ntfs_inode *ni,
|
|||
static struct indx_node *indx_find_buffer(struct ntfs_index *indx,
|
||||
struct ntfs_inode *ni,
|
||||
const struct INDEX_ROOT *root,
|
||||
__le64 vbn, struct indx_node *n)
|
||||
__le64 vbn, struct indx_node *n,
|
||||
int depth)
|
||||
{
|
||||
int err;
|
||||
const struct NTFS_DE *e;
|
||||
struct indx_node *r;
|
||||
const struct INDEX_HDR *hdr = n ? &n->index->ihdr : &root->ihdr;
|
||||
|
||||
/*
|
||||
* Limit recursion depth to prevent stack overflow from crafted
|
||||
* images. Use the same bound as the fnd->nodes array (20).
|
||||
*/
|
||||
if (depth > ARRAY_SIZE(((struct ntfs_fnd *)NULL)->nodes))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
/* Step 1: Scan one level. */
|
||||
for (e = hdr_first_de(hdr);; e = hdr_next_de(hdr, e)) {
|
||||
if (!e)
|
||||
|
|
@ -2049,7 +2057,8 @@ static struct indx_node *indx_find_buffer(struct ntfs_index *indx,
|
|||
if (err)
|
||||
return ERR_PTR(err);
|
||||
|
||||
r = indx_find_buffer(indx, ni, root, vbn, n);
|
||||
r = indx_find_buffer(indx, ni, root, vbn, n,
|
||||
depth + 1);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
|
@ -2462,7 +2471,7 @@ int indx_delete_entry(struct ntfs_index *indx, struct ntfs_inode *ni,
|
|||
|
||||
fnd_clear(fnd);
|
||||
|
||||
in = indx_find_buffer(indx, ni, root, sub_vbn, NULL);
|
||||
in = indx_find_buffer(indx, ni, root, sub_vbn, NULL, 0);
|
||||
if (IS_ERR(in)) {
|
||||
err = PTR_ERR(in);
|
||||
goto out;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user