diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-08-10 18:15:12 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-08-16 08:52:11 -0700 |
commit | 58fcb8df0bf663bb6b8f46cd3010bfe8d13d97cf (patch) | |
tree | 24edbecfb5875cf6c602b1fd5126c7dfce9ae127 | |
parent | 75cd968ab251ac84dd3a5dc252af7036dc4a64f4 (diff) | |
download | linux-58fcb8df0bf663bb6b8f46cd3010bfe8d13d97cf.tar.gz linux-58fcb8df0bf663bb6b8f46cd3010bfe8d13d97cf.tar.bz2 linux-58fcb8df0bf663bb6b8f46cd3010bfe8d13d97cf.zip |
[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>
-rw-r--r-- | fs/nfs_common/nfsacl.c | 1 | ||||
-rw-r--r-- | include/linux/sunrpc/xdr.h | 1 | ||||
-rw-r--r-- | net/sunrpc/xdr.c | 1 |
3 files changed, 3 insertions, 0 deletions
diff --git a/fs/nfs_common/nfsacl.c b/fs/nfs_common/nfsacl.c index 18c58c32e326..251e5a1bb1c4 100644 --- a/fs/nfs_common/nfsacl.c +++ b/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) || entries > NFS_ACL_MAX_ENTRIES) return -EINVAL; + nfsacl_desc.desc.array_maxlen = entries; err = xdr_decode_array2(buf, base + 4, &nfsacl_desc.desc); if (err) return err; diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index 34ec3e8d99b3..23448d0fb5bc 100644 --- a/include/linux/sunrpc/xdr.h +++ b/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 { unsigned int elem_size; unsigned int array_len; + unsigned int array_maxlen; xdr_xcode_elem_t xcode; }; diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 8a4d9c106af1..fde16f40a581 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -993,6 +993,7 @@ xdr_xcode_array2(struct xdr_buf *buf, unsigned int base, return -EINVAL; } else { if (xdr_decode_word(buf, base, &desc->array_len) != 0 || + desc->array_len > desc->array_maxlen || (unsigned long) base + 4 + desc->array_len * desc->elem_size > buf->len) return -EINVAL; |