diff options
author | Andreas Gruenbacher <agruen@suse.de> | 2004-10-18 18:17:06 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-10-18 18:17:06 -0700 |
commit | dfca7b2165ab74442b0a0e2058d268615d61d4d4 (patch) | |
tree | 9cb66483a829f3ada559f31c637da909ec529f22 /fs/ext2/xattr.c | |
parent | f25ce515d029ef60a4b14872d8244da4a966fe7f (diff) | |
download | history-dfca7b2165ab74442b0a0e2058d268615d61d4d4.tar.gz |
[PATCH] xattr: re-introduce validity check before xattr cache insert
* ext[23]_xattr_list():
- Before inserting an xattr block into the cache, make sure that the
block is not corrupted. The check got moved after inserting into the
cache in the xattr consolidation patches, so corrupted blocks could become
visible to cache users.
- Take a variable out of the loop that calls the ->list handlers.
* A few cosmetic changes.
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/ext2/xattr.c')
-rw-r--r-- | fs/ext2/xattr.c | 35 |
1 files changed, 19 insertions, 16 deletions
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index a0d8fe369e878d..fffddd16b06437 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c @@ -270,8 +270,8 @@ ext2_xattr_list(struct inode *inode, char *buffer, size_t buffer_size) { struct buffer_head *bh = NULL; struct ext2_xattr_entry *entry; - size_t total_size = 0; - char *buf, *end; + char *end; + size_t rest = buffer_size; int error; ea_idebug(inode, "buffer=%p, buffer_size=%ld", @@ -298,36 +298,39 @@ bad_block: ext2_error(inode->i_sb, "ext2_xattr_list", goto cleanup; } + /* check the on-disk data structure */ + entry = FIRST_ENTRY(bh); + while (!IS_LAST_ENTRY(entry)) { + struct ext2_xattr_entry *next = EXT2_XATTR_NEXT(entry); + + if ((char *)next >= end) + goto bad_block; + entry = next; + } if (ext2_xattr_cache_insert(bh)) ea_idebug(inode, "cache insert failed"); /* list the attribute names */ - buf = buffer; for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry); entry = EXT2_XATTR_NEXT(entry)) { - struct xattr_handler *handler; - struct ext2_xattr_entry *next = EXT2_XATTR_NEXT(entry); - - if ((char *)next >= end) - goto bad_block; + struct xattr_handler *handler = + ext2_xattr_handler(entry->e_name_index); - handler = ext2_xattr_handler(entry->e_name_index); if (handler) { - size_t size = handler->list(inode, buf, buffer_size, + size_t size = handler->list(inode, buffer, rest, entry->e_name, entry->e_name_len); - if (buf) { - if (size > buffer_size) { + if (buffer) { + if (size > rest) { error = -ERANGE; goto cleanup; } - buf += size; - buffer_size -= size; + buffer += size; } - total_size += size; + rest -= size; } } - error = total_size; + error = buffer_size - rest; /* total size */ cleanup: brelse(bh); |