Commit 0439e091 authored by Jie Liu's avatar Jie Liu Committed by Dave Kleikamp

jfs: fix xattr value size overflow in __jfs_setxattr

There is a potential overflow if the specified EA value size is
greater than USHRT_MAX because the size of value is limited by
the on-disk format (i.e, __le16), this issue could be reflected
via the tests below:
 # touch /jfs/testfile
 # setfattr -n user.comment -v `perl -e 'print "A"x65536'` /jfs/testfile
   setfattr: /jfs/testfile: Invalid argument

Syslog:
 ... jfs_xsetattr: xattr_size = 21, new_size = 65557

This patch add pre-checkups of EA value size against USHRT_MAX to
avoid this problem, and return -E2BIG which is consistent with the
VFS setxattr interface.  Moreover, fix the debug code to print the
correct function name.

With this fix:
 setfattr: /jfs/testfile: Argument list too long
Signed-off-by: default avatarJie Liu <jeff.liu@oracle.com>
Signed-off-by: default avatarDave Kleikamp <dave.kleikamp@oracle.com>
parent 9a0bb296
...@@ -860,6 +860,19 @@ int __jfs_setxattr(tid_t tid, struct inode *inode, const char *name, ...@@ -860,6 +860,19 @@ int __jfs_setxattr(tid_t tid, struct inode *inode, const char *name,
/* Completely new ea list */ /* Completely new ea list */
xattr_size = sizeof (struct jfs_ea_list); xattr_size = sizeof (struct jfs_ea_list);
/*
* The size of EA value is limitted by on-disk format up to
* __le16, there would be an overflow if the size is equal
* to XATTR_SIZE_MAX (65536). In order to avoid this issue,
* we can pre-checkup the value size against USHRT_MAX, and
* return -E2BIG in this case, which is consistent with the
* VFS setxattr interface.
*/
if (value_len >= USHRT_MAX) {
rc = -E2BIG;
goto release;
}
ea = (struct jfs_ea *) ((char *) ealist + xattr_size); ea = (struct jfs_ea *) ((char *) ealist + xattr_size);
ea->flag = 0; ea->flag = 0;
ea->namelen = namelen; ea->namelen = namelen;
...@@ -874,7 +887,7 @@ int __jfs_setxattr(tid_t tid, struct inode *inode, const char *name, ...@@ -874,7 +887,7 @@ int __jfs_setxattr(tid_t tid, struct inode *inode, const char *name,
/* DEBUG - If we did this right, these number match */ /* DEBUG - If we did this right, these number match */
if (xattr_size != new_size) { if (xattr_size != new_size) {
printk(KERN_ERR printk(KERN_ERR
"jfs_xsetattr: xattr_size = %d, new_size = %d\n", "__jfs_setxattr: xattr_size = %d, new_size = %d\n",
xattr_size, new_size); xattr_size, new_size);
rc = -EINVAL; rc = -EINVAL;
......
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