diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 8c16b7d10290..19eba711b32f 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -7933,7 +7933,7 @@ static bool numeric_name_to_id(const char *name, u32 namelen, unsigned long long static int nfs4_decode_nfsace4(void **data, size_t *remaining, struct nfs4_ace *ace) { u32 *p = *data; - u32 length; + u32 length, length_incl_padding; int error = 0; /* @@ -7963,16 +7963,15 @@ static int nfs4_decode_nfsace4(void **data, size_t *remaining, struct nfs4_ace * ace->flag = ntohl(*(p++)); ace->access_mask = ntohl(*(p++)); length = ntohl(*(p++)); + length_incl_padding = XDR_QUADLEN(length) << 2; /* * Now that we have the length, check remaining again. * - * There could be an argument that we check against: - * (NFSACE4_HEADER_BYTES + XDR_QUADLEN(length)) - * however since we won't actually access any of those trailing - * padding bytes in this call, it doesn't really matter. + * The input buffer includes both the string and null + * padding (if necessary to align things). */ - if (*remaining < (NFSACE4_HEADER_BYTES + length)) { + if (*remaining < (NFSACE4_HEADER_BYTES + length_incl_padding)) { pr_err("NFS: %s buffer not large enough to contain ACE who", __func__); return -EOVERFLOW; } @@ -8022,7 +8021,7 @@ static int nfs4_decode_nfsace4(void **data, size_t *remaining, struct nfs4_ace * p += XDR_QUADLEN(length); *data = p; /* Reduce remaining by initial 4 uint32_t + the string (incl padding) */ - *remaining -= (NFSACE4_HEADER_BYTES + length); + *remaining -= (NFSACE4_HEADER_BYTES + length_incl_padding); } return error; }