mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
nfsd4: bug in read_buf
When read_buf is called to move over to the next page in the pagelist of an NFSv4 request, it sets argp->end to essentially a random number, certainly not an address within the page which argp->p now points to. So subsequent calls to READ_BUF will think there is much more than a page of spare space (the cast to u32 ensures an unsigned comparison) so we can expect to fall off the end of the second page. We never encountered thsi in testing because typically the only operations which use more than two pages are write-like operations, which have their own decoding logic. Something like a getattr after a write may cross a page boundary, but it would be very unusual for it to cross another boundary after that. Cc: stable@kernel.org Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
This commit is contained in:
parent
0d0fb0f9c5
commit
2bc3c1179c
@ -161,10 +161,10 @@ static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes)
|
||||
argp->p = page_address(argp->pagelist[0]);
|
||||
argp->pagelist++;
|
||||
if (argp->pagelen < PAGE_SIZE) {
|
||||
argp->end = p + (argp->pagelen>>2);
|
||||
argp->end = argp->p + (argp->pagelen>>2);
|
||||
argp->pagelen = 0;
|
||||
} else {
|
||||
argp->end = p + (PAGE_SIZE>>2);
|
||||
argp->end = argp->p + (PAGE_SIZE>>2);
|
||||
argp->pagelen -= PAGE_SIZE;
|
||||
}
|
||||
memcpy(((char*)p)+avail, argp->p, (nbytes - avail));
|
||||
@ -1426,10 +1426,10 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
|
||||
argp->p = page_address(argp->pagelist[0]);
|
||||
argp->pagelist++;
|
||||
if (argp->pagelen < PAGE_SIZE) {
|
||||
argp->end = p + (argp->pagelen>>2);
|
||||
argp->end = argp->p + (argp->pagelen>>2);
|
||||
argp->pagelen = 0;
|
||||
} else {
|
||||
argp->end = p + (PAGE_SIZE>>2);
|
||||
argp->end = argp->p + (PAGE_SIZE>>2);
|
||||
argp->pagelen -= PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user