Whamcloud - gitweb
debugfs: add better error checking when printing extended attributes
authorTheodore Ts'o <tytso@mit.edu>
Fri, 29 Aug 2014 18:20:21 +0000 (14:20 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Fri, 29 Aug 2014 18:20:21 +0000 (14:20 -0400)
Check to make sure the length of the name and value fields in the
extended attribute don't result in overrun the bounds of the inode.

Addresses-Coverity-Bug: #709517

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
debugfs/debugfs.c

index 00c2d38..5423634 100644 (file)
@@ -535,7 +535,6 @@ static void internal_dump_inode_extra(FILE *out,
        struct ext2_ext_attr_entry *entry;
        __u32 *magic;
        char *start, *end;
-       unsigned int storage_size;
 
        fprintf(out, "Size of extra inode fields: %u\n", inode->i_extra_isize);
        if (inode->i_extra_isize > EXT2_INODE_SIZE(current_fs->super) -
@@ -544,9 +543,6 @@ static void internal_dump_inode_extra(FILE *out,
                                inode->i_extra_isize);
                return;
        }
-       storage_size = EXT2_INODE_SIZE(current_fs->super) -
-                       EXT2_GOOD_OLD_INODE_SIZE -
-                       inode->i_extra_isize;
        magic = (__u32 *)((char *)inode + EXT2_GOOD_OLD_INODE_SIZE +
                        inode->i_extra_isize);
        if (*magic == EXT2_EXT_ATTR_MAGIC) {
@@ -557,17 +553,19 @@ static void internal_dump_inode_extra(FILE *out,
                while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
                        struct ext2_ext_attr_entry *next =
                                EXT2_EXT_ATTR_NEXT(entry);
-                       if (entry->e_value_size > storage_size ||
-                                       (char *) next >= end) {
+                       char *name = EXT2_EXT_ATTR_NAME(entry);
+                       char *value = start + entry->e_value_offs;
+
+                       if (name + entry->e_name_len >= end ||
+                           value + entry->e_value_size >= end ||
+                           (char *) next >= end) {
                                fprintf(out, "invalid EA entry in inode\n");
                                return;
                        }
                        fprintf(out, "  ");
-                       dump_xattr_string(out, EXT2_EXT_ATTR_NAME(entry),
-                                         entry->e_name_len);
+                       dump_xattr_string(out, name, entry->e_name_len);
                        fprintf(out, " = \"");
-                       dump_xattr_string(out, start + entry->e_value_offs,
-                                               entry->e_value_size);
+                       dump_xattr_string(out, value, entry->e_value_size);
                        fprintf(out, "\" (%u)\n", entry->e_value_size);
                        entry = next;
                }