Commit d0fa70ac authored by lei lu's avatar lei lu Committed by Dave Kleikamp

jfs: don't walk off the end of ealist

Add a check before visiting the members of ea to
make sure each ea stays within the ealist.
Signed-off-by: default avatarlei lu <llfamsec@gmail.com>
Signed-off-by: default avatarDave Kleikamp <dave.kleikamp@oracle.com>
parent 7063b802
...@@ -795,7 +795,7 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data, ...@@ -795,7 +795,7 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
size_t buf_size) size_t buf_size)
{ {
struct jfs_ea_list *ealist; struct jfs_ea_list *ealist;
struct jfs_ea *ea; struct jfs_ea *ea, *ealist_end;
struct ea_buffer ea_buf; struct ea_buffer ea_buf;
int xattr_size; int xattr_size;
ssize_t size; ssize_t size;
...@@ -815,9 +815,16 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data, ...@@ -815,9 +815,16 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
goto not_found; goto not_found;
ealist = (struct jfs_ea_list *) ea_buf.xattr; ealist = (struct jfs_ea_list *) ea_buf.xattr;
ealist_end = END_EALIST(ealist);
/* Find the named attribute */ /* Find the named attribute */
for (ea = FIRST_EA(ealist); ea < END_EALIST(ealist); ea = NEXT_EA(ea)) for (ea = FIRST_EA(ealist); ea < ealist_end; ea = NEXT_EA(ea)) {
if (unlikely(ea + 1 > ealist_end) ||
unlikely(NEXT_EA(ea) > ealist_end)) {
size = -EUCLEAN;
goto release;
}
if ((namelen == ea->namelen) && if ((namelen == ea->namelen) &&
memcmp(name, ea->name, namelen) == 0) { memcmp(name, ea->name, namelen) == 0) {
/* Found it */ /* Found it */
...@@ -832,6 +839,7 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data, ...@@ -832,6 +839,7 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
memcpy(data, value, size); memcpy(data, value, size);
goto release; goto release;
} }
}
not_found: not_found:
size = -ENODATA; size = -ENODATA;
release: release:
...@@ -859,7 +867,7 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size) ...@@ -859,7 +867,7 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size)
ssize_t size = 0; ssize_t size = 0;
int xattr_size; int xattr_size;
struct jfs_ea_list *ealist; struct jfs_ea_list *ealist;
struct jfs_ea *ea; struct jfs_ea *ea, *ealist_end;
struct ea_buffer ea_buf; struct ea_buffer ea_buf;
down_read(&JFS_IP(inode)->xattr_sem); down_read(&JFS_IP(inode)->xattr_sem);
...@@ -874,9 +882,16 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size) ...@@ -874,9 +882,16 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size)
goto release; goto release;
ealist = (struct jfs_ea_list *) ea_buf.xattr; ealist = (struct jfs_ea_list *) ea_buf.xattr;
ealist_end = END_EALIST(ealist);
/* compute required size of list */ /* compute required size of list */
for (ea = FIRST_EA(ealist); ea < END_EALIST(ealist); ea = NEXT_EA(ea)) { for (ea = FIRST_EA(ealist); ea < ealist_end; ea = NEXT_EA(ea)) {
if (unlikely(ea + 1 > ealist_end) ||
unlikely(NEXT_EA(ea) > ealist_end)) {
size = -EUCLEAN;
goto release;
}
if (can_list(ea)) if (can_list(ea))
size += name_size(ea) + 1; size += name_size(ea) + 1;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment