Skip to content

Commit f4435f4

Browse files
LLfamgregkh
authored andcommitted
jfs: don't walk off the end of ealist
commit d0fa70a upstream. Add a check before visiting the members of ea to make sure each ea stays within the ealist. Signed-off-by: lei lu <llfamsec@gmail.com> Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 624b380 commit f4435f4

1 file changed

Lines changed: 19 additions & 4 deletions

File tree

fs/jfs/xattr.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,7 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
797797
size_t buf_size)
798798
{
799799
struct jfs_ea_list *ealist;
800-
struct jfs_ea *ea;
800+
struct jfs_ea *ea, *ealist_end;
801801
struct ea_buffer ea_buf;
802802
int xattr_size;
803803
ssize_t size;
@@ -817,9 +817,16 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
817817
goto not_found;
818818

819819
ealist = (struct jfs_ea_list *) ea_buf.xattr;
820+
ealist_end = END_EALIST(ealist);
820821

821822
/* Find the named attribute */
822-
for (ea = FIRST_EA(ealist); ea < END_EALIST(ealist); ea = NEXT_EA(ea))
823+
for (ea = FIRST_EA(ealist); ea < ealist_end; ea = NEXT_EA(ea)) {
824+
if (unlikely(ea + 1 > ealist_end) ||
825+
unlikely(NEXT_EA(ea) > ealist_end)) {
826+
size = -EUCLEAN;
827+
goto release;
828+
}
829+
823830
if ((namelen == ea->namelen) &&
824831
memcmp(name, ea->name, namelen) == 0) {
825832
/* Found it */
@@ -834,6 +841,7 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
834841
memcpy(data, value, size);
835842
goto release;
836843
}
844+
}
837845
not_found:
838846
size = -ENODATA;
839847
release:
@@ -861,7 +869,7 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size)
861869
ssize_t size = 0;
862870
int xattr_size;
863871
struct jfs_ea_list *ealist;
864-
struct jfs_ea *ea;
872+
struct jfs_ea *ea, *ealist_end;
865873
struct ea_buffer ea_buf;
866874

867875
down_read(&JFS_IP(inode)->xattr_sem);
@@ -876,9 +884,16 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size)
876884
goto release;
877885

878886
ealist = (struct jfs_ea_list *) ea_buf.xattr;
887+
ealist_end = END_EALIST(ealist);
879888

880889
/* compute required size of list */
881-
for (ea = FIRST_EA(ealist); ea < END_EALIST(ealist); ea = NEXT_EA(ea)) {
890+
for (ea = FIRST_EA(ealist); ea < ealist_end; ea = NEXT_EA(ea)) {
891+
if (unlikely(ea + 1 > ealist_end) ||
892+
unlikely(NEXT_EA(ea) > ealist_end)) {
893+
size = -EUCLEAN;
894+
goto release;
895+
}
896+
882897
if (can_list(ea))
883898
size += name_size(ea) + 1;
884899
}

0 commit comments

Comments
 (0)