This adds sanity checks for xfs_dir2_data_unused and xfs_dir2_data_entry to make sure don't stray beyond valid memory region. It just checks start offset < end without checking end offset < end. So if last entry is xfs_dir2_data_unused, and is located at the end of ag. We can change dup->length to dup->length-1 and leave 1 byte of space. In the next traversal, this space will be considered as dup or dep. We may encounter an out-of-bound read when accessing the fixed members. Signed-off-by: lei lu <llfamsec@xxxxxxxxx> --- fs/xfs/libxfs/xfs_dir2_data.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c index dbcf58979a59..08c18e0c1baa 100644 --- a/fs/xfs/libxfs/xfs_dir2_data.c +++ b/fs/xfs/libxfs/xfs_dir2_data.c @@ -178,6 +178,9 @@ __xfs_dir3_data_check( struct xfs_dir2_data_unused *dup = bp->b_addr + offset; struct xfs_dir2_data_entry *dep = bp->b_addr + offset; + if (offset + sizeof(*dup) > end) + return __this_address; + /* * If it's unused, look for the space in the bestfree table. * If we find it, account for that, else make sure it @@ -210,6 +213,10 @@ __xfs_dir3_data_check( lastfree = 1; continue; } + + if (offset + sizeof(*dep) > end) + return __this_address; + /* * It's a real entry. Validate the fields. * If this is a block directory then make sure it's -- 2.34.1