aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfssvc.c')
-rw-r--r--fs/nfsd/nfssvc.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index ad4e2377dd63..5be1fa6b676d 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -656,6 +656,37 @@ static __be32 map_new_errors(u32 vers, __be32 nfserr)
656 return nfserr; 656 return nfserr;
657} 657}
658 658
659/*
660 * A write procedure can have a large argument, and a read procedure can
661 * have a large reply, but no NFSv2 or NFSv3 procedure has argument and
662 * reply that can both be larger than a page. The xdr code has taken
663 * advantage of this assumption to be a sloppy about bounds checking in
664 * some cases. Pending a rewrite of the NFSv2/v3 xdr code to fix that
665 * problem, we enforce these assumptions here:
666 */
667static bool nfs_request_too_big(struct svc_rqst *rqstp,
668 struct svc_procedure *proc)
669{
670 /*
671 * The ACL code has more careful bounds-checking and is not
672 * susceptible to this problem:
673 */
674 if (rqstp->rq_prog != NFS_PROGRAM)
675 return false;
676 /*
677 * Ditto NFSv4 (which can in theory have argument and reply both
678 * more than a page):
679 */
680 if (rqstp->rq_vers >= 4)
681 return false;
682 /* The reply will be small, we're OK: */
683 if (proc->pc_xdrressize > 0 &&
684 proc->pc_xdrressize < XDR_QUADLEN(PAGE_SIZE))
685 return false;
686
687 return rqstp->rq_arg.len > PAGE_SIZE;
688}
689
659int 690int
660nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) 691nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
661{ 692{
@@ -668,6 +699,11 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
668 rqstp->rq_vers, rqstp->rq_proc); 699 rqstp->rq_vers, rqstp->rq_proc);
669 proc = rqstp->rq_procinfo; 700 proc = rqstp->rq_procinfo;
670 701
702 if (nfs_request_too_big(rqstp, proc)) {
703 dprintk("nfsd: NFSv%d argument too large\n", rqstp->rq_vers);
704 *statp = rpc_garbage_args;
705 return 1;
706 }
671 /* 707 /*
672 * Give the xdr decoder a chance to change this if it wants 708 * Give the xdr decoder a chance to change this if it wants
673 * (necessary in the NFSv4.0 compound case) 709 * (necessary in the NFSv4.0 compound case)