From: Darrick J. Wong Date: Sun, 10 Aug 2014 22:22:07 +0000 (-0400) Subject: libext2fs/e2fsck: don't run off the end of the EA block X-Git-Tag: v1.43-WIP-2015-05-18~242 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=88334ce084ef45929d7aacff5af283994358c5d6;p=thirdparty%2Fe2fsprogs.git libext2fs/e2fsck: don't run off the end of the EA block When we're (a) reading EAs into a buffer; (b) byte-swapping EA entries; or (c) checking EA data, be careful not to run off the end of the memory buffer, because this causes invalid memory accesses and e2fsck crashes. This can happen if we encounter a specially crafted FS image. Signed-off-by: Darrick J. Wong Signed-off-by: Theodore Ts'o --- diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index 5c72f48a4..6c79eedfd 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -302,7 +302,8 @@ static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx) /* take finish entry 0UL into account */ remain = storage_size - sizeof(__u32); - while (!EXT2_EXT_IS_LAST_ENTRY(entry)) { + while (remain >= sizeof(struct ext2_ext_attr_entry) && + !EXT2_EXT_IS_LAST_ENTRY(entry)) { __u32 hash; /* header eats this space */ diff --git a/lib/ext2fs/ext_attr.c b/lib/ext2fs/ext_attr.c index 96530f83b..5732ca6f2 100644 --- a/lib/ext2fs/ext_attr.c +++ b/lib/ext2fs/ext_attr.c @@ -633,7 +633,8 @@ static errcode_t read_xattrs_from_buffer(struct ext2_xattr_handle *handle, entry = entries; remain = storage_size; - while (!EXT2_EXT_IS_LAST_ENTRY(entry)) { + while (remain >= sizeof(struct ext2_ext_attr_entry) && + !EXT2_EXT_IS_LAST_ENTRY(entry)) { __u32 hash; /* header eats this space */ diff --git a/lib/ext2fs/swapfs.c b/lib/ext2fs/swapfs.c index f08859b57..e2aa41dca 100644 --- a/lib/ext2fs/swapfs.c +++ b/lib/ext2fs/swapfs.c @@ -196,7 +196,9 @@ void ext2fs_swap_ext_attr(char *to, char *from, int bufsize, int has_header) to_entry = (struct ext2_ext_attr_entry *)to_header; } - while ((char *)from_entry < from_end && *(__u32 *)from_entry) { + while ((char *)from_entry < from_end && + (char *)EXT2_EXT_ATTR_NEXT(from_entry) <= from_end && + *(__u32 *)from_entry) { ext2fs_swap_ext_attr_entry(to_entry, from_entry); from_entry = EXT2_EXT_ATTR_NEXT(from_entry); to_entry = EXT2_EXT_ATTR_NEXT(to_entry);