nfsd: Fix handling of negative lengths in read_buf()
The length "nbytes" passed into read_buf should never be negative, but we check only for too-large values of "nbytes", not for too-small values. Make nbytes unsigned, so it's clear that the former tests are sufficient. (Despite this read_buf() currently correctly returns an xdr error in the case of a negative length, thanks to an unsigned comparison with size_of() and bounds-checking in kmalloc(). This seems very fragile, though.) Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
This commit is contained in:
@@ -148,12 +148,12 @@ xdr_error: \
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static __be32 *read_buf(struct nfsd4_compoundargs *argp, int nbytes)
|
static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes)
|
||||||
{
|
{
|
||||||
/* We want more bytes than seem to be available.
|
/* We want more bytes than seem to be available.
|
||||||
* Maybe we need a new page, maybe we have just run out
|
* Maybe we need a new page, maybe we have just run out
|
||||||
*/
|
*/
|
||||||
int avail = (char*)argp->end - (char*)argp->p;
|
unsigned int avail = (char *)argp->end - (char *)argp->p;
|
||||||
__be32 *p;
|
__be32 *p;
|
||||||
if (avail + argp->pagelen < nbytes)
|
if (avail + argp->pagelen < nbytes)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -169,6 +169,11 @@ static __be32 *read_buf(struct nfsd4_compoundargs *argp, int nbytes)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* The following memcpy is safe because read_buf is always
|
||||||
|
* called with nbytes > avail, and the two cases above both
|
||||||
|
* guarantee p points to at least nbytes bytes.
|
||||||
|
*/
|
||||||
memcpy(p, argp->p, avail);
|
memcpy(p, argp->p, avail);
|
||||||
/* step to next page */
|
/* step to next page */
|
||||||
argp->p = page_address(argp->pagelist[0]);
|
argp->p = page_address(argp->pagelist[0]);
|
||||||
|
Reference in New Issue
Block a user