diff options
author | Jie Liu <jeff.liu@oracle.com> | 2014-01-02 12:30:42 -0500 |
---|---|---|
committer | Dave Kleikamp <dave.kleikamp@oracle.com> | 2014-01-02 12:36:56 -0500 |
commit | 0439e091e3b1fe41a350540c84857a573fde3d72 (patch) | |
tree | 56a720ab70a9ad00c6cb405915bda26f2665d7ba /fs/jfs | |
parent | 9a0bb2966efbf30a71c128c3af63307d8b5f5fc0 (diff) |
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: Jie Liu <jeff.liu@oracle.com>
Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
Diffstat (limited to 'fs/jfs')
-rw-r--r-- | fs/jfs/xattr.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c index d3472f4cd530..9c6904eee0c6 100644 --- a/fs/jfs/xattr.c +++ b/fs/jfs/xattr.c | |||
@@ -860,6 +860,19 @@ int __jfs_setxattr(tid_t tid, struct inode *inode, const char *name, | |||
860 | /* Completely new ea list */ | 860 | /* Completely new ea list */ |
861 | xattr_size = sizeof (struct jfs_ea_list); | 861 | xattr_size = sizeof (struct jfs_ea_list); |
862 | 862 | ||
863 | /* | ||
864 | * The size of EA value is limitted by on-disk format up to | ||
865 | * __le16, there would be an overflow if the size is equal | ||
866 | * to XATTR_SIZE_MAX (65536). In order to avoid this issue, | ||
867 | * we can pre-checkup the value size against USHRT_MAX, and | ||
868 | * return -E2BIG in this case, which is consistent with the | ||
869 | * VFS setxattr interface. | ||
870 | */ | ||
871 | if (value_len >= USHRT_MAX) { | ||
872 | rc = -E2BIG; | ||
873 | goto release; | ||
874 | } | ||
875 | |||
863 | ea = (struct jfs_ea *) ((char *) ealist + xattr_size); | 876 | ea = (struct jfs_ea *) ((char *) ealist + xattr_size); |
864 | ea->flag = 0; | 877 | ea->flag = 0; |
865 | ea->namelen = namelen; | 878 | ea->namelen = namelen; |
@@ -874,7 +887,7 @@ int __jfs_setxattr(tid_t tid, struct inode *inode, const char *name, | |||
874 | /* DEBUG - If we did this right, these number match */ | 887 | /* DEBUG - If we did this right, these number match */ |
875 | if (xattr_size != new_size) { | 888 | if (xattr_size != new_size) { |
876 | printk(KERN_ERR | 889 | printk(KERN_ERR |
877 | "jfs_xsetattr: xattr_size = %d, new_size = %d\n", | 890 | "__jfs_setxattr: xattr_size = %d, new_size = %d\n", |
878 | xattr_size, new_size); | 891 | xattr_size, new_size); |
879 | 892 | ||
880 | rc = -EINVAL; | 893 | rc = -EINVAL; |