]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
libext2fs/e2fsck: don't run off the end of the EA block
authorDarrick J. Wong <darrick.wong@oracle.com>
Sun, 10 Aug 2014 22:22:07 +0000 (18:22 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Sun, 10 Aug 2014 22:22:07 +0000 (18:22 -0400)
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 <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
e2fsck/pass1.c
lib/ext2fs/ext_attr.c
lib/ext2fs/swapfs.c

index 5c72f48a4228f7b378f9b3f10e157f5b25e8abcb..6c79eedfd571b96a54ed7095a39c74ab9728f84b 100644 (file)
@@ -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 */
index 96530f83bea5caf563f1b96348aa4329f5e808d7..5732ca6f21b12e0695483401d6ef244a2f4f468d 100644 (file)
@@ -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 */
index f08859b5722dfa93188a0ab2cafae6c9cb448263..e2aa41dcaf6215aa15361eccd989ccb45271b305 100644 (file)
@@ -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);