mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
hfsplus: validate extent record length before writing it back
__hfsplus_ext_write_extent() writes the cached extent record back into a B-tree node using fd->entrylength as the length, and fd->entrylength is derived in __hfs_brec_find() from two on-disk values: fd->entrylength = len - keylen; A crafted image can keep both len and keylen valid but make fd->entrylength negative (keylen > len). __hfsplus_ext_write_extent() doesn't check fd->entrylength before consuming it, and hfs_bnode_write() takes the length as u32, so the negative value turns into a huge one. The copy then reads data past the end of hip->cached_extents, which is only sizeof(hfsplus_extent_rec) bytes long, and leaks kernel memory into the image. Reject an fd->entrylength that does not match sizeof(hfsplus_extent_rec) in __hfsplus_ext_write_extent(), mirroring the check already performed in __hfsplus_ext_read_extent(). Link: https://lore.kernel.org/lkml/cbd7003314c530d4f910eacf019ff80adad6687e.camel@dubeyko.com/ Signed-off-by: Jiaming Zhang <r772577952@gmail.com> Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com> Link: https://lore.kernel.org/r/20260810092422.1691377-1-r772577952@gmail.com Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
This commit is contained in:
parent
00aedd67d7
commit
627b7865c0
|
|
@ -110,6 +110,8 @@ static int __hfsplus_ext_write_extent(struct inode *inode,
|
|||
} else {
|
||||
if (res)
|
||||
return res;
|
||||
if (fd->entrylength != sizeof(hfsplus_extent_rec))
|
||||
return -EIO;
|
||||
hfs_bnode_write(fd->bnode, hip->cached_extents,
|
||||
fd->entryoffset, fd->entrylength);
|
||||
hip->extent_state &= ~HFSPLUS_EXT_DIRTY;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user