aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext2/xattr.c
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@suse.de>2004-10-18 18:17:06 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-10-18 18:17:06 -0700
commitdfca7b2165ab74442b0a0e2058d268615d61d4d4 (patch)
tree9cb66483a829f3ada559f31c637da909ec529f22 /fs/ext2/xattr.c
parentf25ce515d029ef60a4b14872d8244da4a966fe7f (diff)
downloadhistory-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.c35
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);