Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7f91bd0f authored by lei lu's avatar lei lu Committed by Greg Kroah-Hartman
Browse files

jfs: don't walk off the end of ealist



commit d0fa70aca54c8643248e89061da23752506ec0d4 upstream.

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>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 13d38c00
Loading
Loading
Loading
Loading
+19 −4
Original line number Diff line number Diff line
@@ -810,7 +810,7 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
		       size_t buf_size)
{
	struct jfs_ea_list *ealist;
	struct jfs_ea *ea;
	struct jfs_ea *ea, *ealist_end;
	struct ea_buffer ea_buf;
	int xattr_size;
	ssize_t size;
@@ -830,9 +830,16 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
		goto not_found;

	ealist = (struct jfs_ea_list *) ea_buf.xattr;
	ealist_end = END_EALIST(ealist);

	/* 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) &&
		    memcmp(name, ea->name, namelen) == 0) {
			/* Found it */
@@ -847,6 +854,7 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
			memcpy(data, value, size);
			goto release;
		}
	}
      not_found:
	size = -ENODATA;
      release:
@@ -874,7 +882,7 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size)
	ssize_t size = 0;
	int xattr_size;
	struct jfs_ea_list *ealist;
	struct jfs_ea *ea;
	struct jfs_ea *ea, *ealist_end;
	struct ea_buffer ea_buf;

	down_read(&JFS_IP(inode)->xattr_sem);
@@ -889,9 +897,16 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size)
		goto release;

	ealist = (struct jfs_ea_list *) ea_buf.xattr;
	ealist_end = END_EALIST(ealist);

	/* 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))
			size += name_size(ea) + 1;
	}