summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/ceph/xattr.c10
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]);