aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4xdr.c
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2011-10-10 14:37:13 -0400
committerJ. Bruce Fields <bfields@redhat.com>2011-10-11 08:53:12 -0400
commit04f9e664b21c4440daf4d08f31db9b18517e4b8d (patch)
treeea47eaac63adcff1771acc697a76d0635ae4b9a4 /fs/nfsd/nfs4xdr.c
parentc30e92df30d7d5fe65262fbce5d1b7de675fe34e (diff)
nfsd4: move access/deny validity checks to xdr code
I'd rather put more of these sorts of checks into standardized xdr decoders for the various types rather than have them cluttering up the core logic in nfs4proc.c and nfs4state.c. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfs4xdr.c')
-rw-r--r--fs/nfsd/nfs4xdr.c80
1 files changed, 73 insertions, 7 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 5779acde7e7..94da8bb36c8 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -639,6 +639,64 @@ nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup
639 DECODE_TAIL; 639 DECODE_TAIL;
640} 640}
641 641
642static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *x)
643{
644 __be32 *p;
645 u32 w;
646
647 READ_BUF(4);
648 READ32(w);
649 *x = w;
650 switch (w & NFS4_SHARE_ACCESS_MASK) {
651 case NFS4_SHARE_ACCESS_READ:
652 case NFS4_SHARE_ACCESS_WRITE:
653 case NFS4_SHARE_ACCESS_BOTH:
654 break;
655 default:
656 return nfserr_bad_xdr;
657 }
658 w &= !NFS4_SHARE_ACCESS_MASK;
659 if (!w)
660 return nfs_ok;
661 if (!argp->minorversion)
662 return nfserr_bad_xdr;
663 switch (w & NFS4_SHARE_WANT_MASK) {
664 case NFS4_SHARE_WANT_NO_PREFERENCE:
665 case NFS4_SHARE_WANT_READ_DELEG:
666 case NFS4_SHARE_WANT_WRITE_DELEG:
667 case NFS4_SHARE_WANT_ANY_DELEG:
668 case NFS4_SHARE_WANT_NO_DELEG:
669 case NFS4_SHARE_WANT_CANCEL:
670 break;
671 default:
672 return nfserr_bad_xdr;
673 }
674 w &= !NFS4_SHARE_WANT_MASK;
675 if (!w)
676 return nfs_ok;
677 switch (w) {
678 case NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL:
679 case NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED:
680 return nfs_ok;
681 }
682xdr_error:
683 return nfserr_bad_xdr;
684}
685
686static __be32 nfsd4_decode_share_deny(struct nfsd4_compoundargs *argp, u32 *x)
687{
688 __be32 *p;
689
690 READ_BUF(4);
691 READ32(*x);
692 /* Note: unlinke access bits, deny bits may be zero. */
693 if (*x & !NFS4_SHARE_DENY_BOTH)
694 return nfserr_bad_xdr;
695 return nfs_ok;
696xdr_error:
697 return nfserr_bad_xdr;
698}
699
642static __be32 700static __be32
643nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open) 701nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
644{ 702{
@@ -649,10 +707,15 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
649 open->op_openowner = NULL; 707 open->op_openowner = NULL;
650 708
651 /* seqid, share_access, share_deny, clientid, ownerlen */ 709 /* seqid, share_access, share_deny, clientid, ownerlen */
652 READ_BUF(16 + sizeof(clientid_t)); 710 READ_BUF(4);
653 READ32(open->op_seqid); 711 READ32(open->op_seqid);
654 READ32(open->op_share_access); 712 status = nfsd4_decode_share_access(argp, &open->op_share_access);
655 READ32(open->op_share_deny); 713 if (status)
714 goto xdr_error;
715 status = nfsd4_decode_share_deny(argp, &open->op_share_deny);
716 if (status)
717 goto xdr_error;
718 READ_BUF(sizeof(clientid_t) + 4);
656 COPYMEM(&open->op_clientid, sizeof(clientid_t)); 719 COPYMEM(&open->op_clientid, sizeof(clientid_t));
657 READ32(open->op_owner.len); 720 READ32(open->op_owner.len);
658 721
@@ -753,11 +816,14 @@ nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_d
753 status = nfsd4_decode_stateid(argp, &open_down->od_stateid); 816 status = nfsd4_decode_stateid(argp, &open_down->od_stateid);
754 if (status) 817 if (status)
755 return status; 818 return status;
756 READ_BUF(12); 819 READ_BUF(4);
757 READ32(open_down->od_seqid); 820 READ32(open_down->od_seqid);
758 READ32(open_down->od_share_access); 821 status = nfsd4_decode_share_access(argp, &open_down->od_share_access);
759 READ32(open_down->od_share_deny); 822 if (status)
760 823 return status;
824 status = nfsd4_decode_share_deny(argp, &open_down->od_share_deny);
825 if (status)
826 return status;
761 DECODE_TAIL; 827 DECODE_TAIL;
762} 828}
763 829