diff options
| -rw-r--r-- | fs/ceph/xattr.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 1da6deea2c24..bdd280856d86 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -11,6 +11,7 @@ #include <linux/security.h> #include <linux/posix_acl_xattr.h> #include <linux/slab.h> +#include <linux/overflow.h> #define XATTR_CEPH_PREFIX "ceph." #define XATTR_CEPH_PREFIX_LEN (sizeof (XATTR_CEPH_PREFIX) - 1) @@ -843,14 +844,23 @@ start: } err = -EIO; while (numattr--) { + int names_size, vals_size; + ceph_decode_32_safe(&p, end, len, bad); namelen = len; name = p; + ceph_decode_need(&p, end, namelen, bad); p += len; ceph_decode_32_safe(&p, end, len, bad); ceph_decode_need(&p, end, len, bad); val = p; p += len; + if (namelen > INT_MAX || len > INT_MAX || + check_add_overflow(ci->i_xattrs.names_size, + (int)namelen, &names_size) || + check_add_overflow(ci->i_xattrs.vals_size, + (int)len, &vals_size)) + goto bad; err = __set_xattr(ci, name, namelen, val, len, 0, 0, &xattrs[numattr]); |
