mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
ntfs: sanitize MFT references returned from ntfs_lookup_inode_by_name()
ntfs_lookup_inode_by_name() returns MFT references read from directory
index entries on disk. These values are untrusted, but the function can
currently return an error-marked MFT reference to its callers without
validating it.
Callers later decode lookup failures with MREF_ERR(). A crafted NTFS image
can set the MREF error bit while leaving the low bits as an arbitrary
value, causing callers to consume a bogus pseudo-errno instead of treating
the lookup result as corrupted on-disk metadata.
Fix this at the source by normalizing every error-marked MFT reference
returned from ntfs_lookup_inode_by_name() to ERR_MREF(-EIO). Apply this to
all four directory lookup return paths so every caller gets a validated
result without needing additional checks or an API change.
This keeps the sanitization in the common lookup helper, which is cleaner
than duplicating validation in each caller.
Fixes: 1e9ea7e044 ("Revert "fs: Remove NTFS classic"")
Cc: stable@vger.kernel.org
Reported-by: Hongling Zeng <zenghongling@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
This commit is contained in:
parent
06769b8f23
commit
d97a36bae8
|
|
@ -23,6 +23,13 @@
|
|||
__le16 I30[5] = { cpu_to_le16('$'), cpu_to_le16('I'),
|
||||
cpu_to_le16('3'), cpu_to_le16('0'), 0 };
|
||||
|
||||
static inline u64 ntfs_check_mref(u64 mref)
|
||||
{
|
||||
if (IS_ERR_MREF(mref))
|
||||
return ERR_MREF(-EIO);
|
||||
return mref;
|
||||
}
|
||||
|
||||
/*
|
||||
* ntfs_lookup_inode_by_name - find an inode in a directory given its name
|
||||
* @dir_ni: ntfs inode of the directory in which to search for the name
|
||||
|
|
@ -178,7 +185,7 @@ u64 ntfs_lookup_inode_by_name(struct ntfs_inode *dir_ni, const __le16 *uname,
|
|||
mref = le64_to_cpu(ie->data.dir.indexed_file);
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
unmap_mft_record(dir_ni);
|
||||
return mref;
|
||||
return ntfs_check_mref(mref);
|
||||
}
|
||||
/*
|
||||
* For a case insensitive mount, we also perform a case
|
||||
|
|
@ -273,7 +280,7 @@ u64 ntfs_lookup_inode_by_name(struct ntfs_inode *dir_ni, const __le16 *uname,
|
|||
if (name) {
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
unmap_mft_record(dir_ni);
|
||||
return name->mref;
|
||||
return ntfs_check_mref(name->mref);
|
||||
}
|
||||
ntfs_debug("Entry not found.");
|
||||
err = -ENOENT;
|
||||
|
|
@ -413,7 +420,7 @@ u64 ntfs_lookup_inode_by_name(struct ntfs_inode *dir_ni, const __le16 *uname,
|
|||
mref = le64_to_cpu(ie->data.dir.indexed_file);
|
||||
kfree(kaddr);
|
||||
iput(ia_vi);
|
||||
return mref;
|
||||
return ntfs_check_mref(mref);
|
||||
}
|
||||
/*
|
||||
* For a case insensitive mount, we also perform a case
|
||||
|
|
@ -538,7 +545,7 @@ u64 ntfs_lookup_inode_by_name(struct ntfs_inode *dir_ni, const __le16 *uname,
|
|||
if (name) {
|
||||
kfree(kaddr);
|
||||
iput(ia_vi);
|
||||
return name->mref;
|
||||
return ntfs_check_mref(name->mref);
|
||||
}
|
||||
ntfs_debug("Entry not found.");
|
||||
err = -ENOENT;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user