Browse Source

[PATCH] NFS: Ensure ACL xdr code doesn't overflow.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Trond Myklebust 20 years ago
parent
commit
58fcb8df0b
3 changed files with 3 additions and 0 deletions
  1. 1 0
      fs/nfs_common/nfsacl.c
  2. 1 0
      include/linux/sunrpc/xdr.h
  3. 1 0
      net/sunrpc/xdr.c

+ 1 - 0
fs/nfs_common/nfsacl.c

@@ -239,6 +239,7 @@ nfsacl_decode(struct xdr_buf *buf, unsigned int base, unsigned int *aclcnt,
 	if (xdr_decode_word(buf, base, &entries) ||
 	if (xdr_decode_word(buf, base, &entries) ||
 	    entries > NFS_ACL_MAX_ENTRIES)
 	    entries > NFS_ACL_MAX_ENTRIES)
 		return -EINVAL;
 		return -EINVAL;
+	nfsacl_desc.desc.array_maxlen = entries;
 	err = xdr_decode_array2(buf, base + 4, &nfsacl_desc.desc);
 	err = xdr_decode_array2(buf, base + 4, &nfsacl_desc.desc);
 	if (err)
 	if (err)
 		return err;
 		return err;

+ 1 - 0
include/linux/sunrpc/xdr.h

@@ -177,6 +177,7 @@ typedef int (*xdr_xcode_elem_t)(struct xdr_array2_desc *desc, void *elem);
 struct xdr_array2_desc {
 struct xdr_array2_desc {
 	unsigned int elem_size;
 	unsigned int elem_size;
 	unsigned int array_len;
 	unsigned int array_len;
+	unsigned int array_maxlen;
 	xdr_xcode_elem_t xcode;
 	xdr_xcode_elem_t xcode;
 };
 };
 
 

+ 1 - 0
net/sunrpc/xdr.c

@@ -993,6 +993,7 @@ xdr_xcode_array2(struct xdr_buf *buf, unsigned int base,
 			return -EINVAL;
 			return -EINVAL;
 	} else {
 	} else {
 		if (xdr_decode_word(buf, base, &desc->array_len) != 0 ||
 		if (xdr_decode_word(buf, base, &desc->array_len) != 0 ||
+		    desc->array_len > desc->array_maxlen ||
 		    (unsigned long) base + 4 + desc->array_len *
 		    (unsigned long) base + 4 + desc->array_len *
 				    desc->elem_size > buf->len)
 				    desc->elem_size > buf->len)
 			return -EINVAL;
 			return -EINVAL;