summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-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 31e1f9593457..59979f0bbd4b 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -747,6 +747,37 @@ static __be32 map_new_errors(u32 vers, __be32 nfserr)
747 return nfserr; 747 return nfserr;
748} 748}
749 749
750/*
751 * A write procedure can have a large argument, and a read procedure can
752 * have a large reply, but no NFSv2 or NFSv3 procedure has argument and
753 * reply that can both be larger than a page. The xdr code has taken
754 * advantage of this assumption to be a sloppy about bounds checking in
755 * some cases. Pending a rewrite of the NFSv2/v3 xdr code to fix that
756 * problem, we enforce these assumptions here:
757 */
758static bool nfs_request_too_big(struct svc_rqst *rqstp,
759 struct svc_procedure *proc)
760{
761 /*
762 * The ACL code has more careful bounds-checking and is not
763 * susceptible to this problem:
764 */
765 if (rqstp->rq_prog != NFS_PROGRAM)
766 return false;
767 /*
768 * Ditto NFSv4 (which can in theory have argument and reply both
769 * more than a page):
770 */
771 if (rqstp->rq_vers >= 4)
772 return false;
773 /* The reply will be small, we're OK: */
774 if (proc->pc_xdrressize > 0 &&
775 proc->pc_xdrressize < XDR_QUADLEN(PAGE_SIZE))
776 return false;
777
778 return rqstp->rq_arg.len > PAGE_SIZE;
779}
780
750int 781int
751nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) 782nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
752{ 783{
@@ -759,6 +790,11 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
759 rqstp->rq_vers, rqstp->rq_proc); 790 rqstp->rq_vers, rqstp->rq_proc);
760 proc = rqstp->rq_procinfo; 791 proc = rqstp->rq_procinfo;
761 792
793 if (nfs_request_too_big(rqstp, proc)) {
794 dprintk("nfsd: NFSv%d argument too large\n", rqstp->rq_vers);
795 *statp = rpc_garbage_args;
796 return 1;
797 }
762 /* 798 /*
763 * Give the xdr decoder a chance to change this if it wants 799 * Give the xdr decoder a chance to change this if it wants
764 * (necessary in the NFSv4.0 compound case) 800 * (necessary in the NFSv4.0 compound case)