aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2011-10-10 15:07:40 -0400
committerJ. Bruce Fields <bfields@redhat.com>2011-10-11 12:15:01 -0400
commita084daf512bb66fa3c8e21c7027daea521179cd0 (patch)
treeae3432178013d3b474adac890dad3fb7262f9746 /fs/nfsd
parent04f9e664b21c4440daf4d08f31db9b18517e4b8d (diff)
nfsd4: move name-length checks to xdr
Again, these checks are better in the xdr code. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfs4state.c24
-rw-r--r--fs/nfsd/nfs4xdr.c45
-rw-r--r--fs/nfsd/xdr4.h3
3 files changed, 33 insertions, 39 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 6bfa293e1c91..5f35f35a2da0 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1189,17 +1189,6 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir,
1189 return clp; 1189 return clp;
1190} 1190}
1191 1191
1192static int check_name(struct xdr_netobj name)
1193{
1194 if (name.len == 0)
1195 return 0;
1196 if (name.len > NFS4_OPAQUE_LIMIT) {
1197 dprintk("NFSD: check_name: name too long(%d)!\n", name.len);
1198 return 0;
1199 }
1200 return 1;
1201}
1202
1203static void 1192static void
1204add_to_unconfirmed(struct nfs4_client *clp, unsigned int strhashval) 1193add_to_unconfirmed(struct nfs4_client *clp, unsigned int strhashval)
1205{ 1194{
@@ -1442,7 +1431,7 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
1442 __func__, rqstp, exid, exid->clname.len, exid->clname.data, 1431 __func__, rqstp, exid, exid->clname.len, exid->clname.data,
1443 addr_str, exid->flags, exid->spa_how); 1432 addr_str, exid->flags, exid->spa_how);
1444 1433
1445 if (!check_name(exid->clname) || (exid->flags & ~EXCHGID4_FLAG_MASK_A)) 1434 if (exid->flags & ~EXCHGID4_FLAG_MASK_A)
1446 return nfserr_inval; 1435 return nfserr_inval;
1447 1436
1448 /* Currently only support SP4_NONE */ 1437 /* Currently only support SP4_NONE */
@@ -1992,19 +1981,13 @@ __be32
1992nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 1981nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1993 struct nfsd4_setclientid *setclid) 1982 struct nfsd4_setclientid *setclid)
1994{ 1983{
1995 struct xdr_netobj clname = { 1984 struct xdr_netobj clname = setclid->se_name;
1996 .len = setclid->se_namelen,
1997 .data = setclid->se_name,
1998 };
1999 nfs4_verifier clverifier = setclid->se_verf; 1985 nfs4_verifier clverifier = setclid->se_verf;
2000 unsigned int strhashval; 1986 unsigned int strhashval;
2001 struct nfs4_client *conf, *unconf, *new; 1987 struct nfs4_client *conf, *unconf, *new;
2002 __be32 status; 1988 __be32 status;
2003 char dname[HEXDIR_LEN]; 1989 char dname[HEXDIR_LEN];
2004 1990
2005 if (!check_name(clname))
2006 return nfserr_inval;
2007
2008 status = nfs4_make_rec_clidname(dname, &clname); 1991 status = nfs4_make_rec_clidname(dname, &clname);
2009 if (status) 1992 if (status)
2010 return status; 1993 return status;
@@ -2523,9 +2506,6 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate,
2523 struct nfs4_openowner *oo = NULL; 2506 struct nfs4_openowner *oo = NULL;
2524 __be32 status; 2507 __be32 status;
2525 2508
2526 if (!check_name(open->op_owner))
2527 return nfserr_inval;
2528
2529 if (STALE_CLIENTID(&open->op_clientid)) 2509 if (STALE_CLIENTID(&open->op_clientid))
2530 return nfserr_stale_clientid; 2510 return nfserr_stale_clientid;
2531 2511
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 94da8bb36c85..2cab33cc3238 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -697,6 +697,23 @@ xdr_error:
697 return nfserr_bad_xdr; 697 return nfserr_bad_xdr;
698} 698}
699 699
700static __be32 nfsd4_decode_opaque(struct nfsd4_compoundargs *argp, struct xdr_netobj *o)
701{
702 __be32 *p;
703
704 READ_BUF(4);
705 READ32(o->len);
706
707 if (o->len == 0 || o->len > NFS4_OPAQUE_LIMIT)
708 return nfserr_bad_xdr;
709
710 READ_BUF(o->len);
711 SAVEMEM(o->data, o->len);
712 return nfs_ok;
713xdr_error:
714 return nfserr_bad_xdr;
715}
716
700static __be32 717static __be32
701nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open) 718nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
702{ 719{
@@ -715,13 +732,12 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
715 status = nfsd4_decode_share_deny(argp, &open->op_share_deny); 732 status = nfsd4_decode_share_deny(argp, &open->op_share_deny);
716 if (status) 733 if (status)
717 goto xdr_error; 734 goto xdr_error;
718 READ_BUF(sizeof(clientid_t) + 4); 735 READ_BUF(sizeof(clientid_t));
719 COPYMEM(&open->op_clientid, sizeof(clientid_t)); 736 COPYMEM(&open->op_clientid, sizeof(clientid_t));
720 READ32(open->op_owner.len); 737 status = nfsd4_decode_opaque(argp, &open->op_owner);
721 738 if (status)
722 /* owner, open_flag */ 739 goto xdr_error;
723 READ_BUF(open->op_owner.len + 4); 740 READ_BUF(4);
724 SAVEMEM(open->op_owner.data, open->op_owner.len);
725 READ32(open->op_create); 741 READ32(open->op_create);
726 switch (open->op_create) { 742 switch (open->op_create) {
727 case NFS4_OPEN_NOCREATE: 743 case NFS4_OPEN_NOCREATE:
@@ -964,12 +980,13 @@ nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclient
964{ 980{
965 DECODE_HEAD; 981 DECODE_HEAD;
966 982
967 READ_BUF(12); 983 READ_BUF(8);
968 COPYMEM(setclientid->se_verf.data, 8); 984 COPYMEM(setclientid->se_verf.data, 8);
969 READ32(setclientid->se_namelen);
970 985
971 READ_BUF(setclientid->se_namelen + 8); 986 status = nfsd4_decode_opaque(argp, &setclientid->se_name);
972 SAVEMEM(setclientid->se_name, setclientid->se_namelen); 987 if (status)
988 return nfserr_bad_xdr;
989 READ_BUF(8);
973 READ32(setclientid->se_callback_prog); 990 READ32(setclientid->se_callback_prog);
974 READ32(setclientid->se_callback_netid_len); 991 READ32(setclientid->se_callback_netid_len);
975 992
@@ -1112,11 +1129,9 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
1112 READ_BUF(NFS4_VERIFIER_SIZE); 1129 READ_BUF(NFS4_VERIFIER_SIZE);
1113 COPYMEM(exid->verifier.data, NFS4_VERIFIER_SIZE); 1130 COPYMEM(exid->verifier.data, NFS4_VERIFIER_SIZE);
1114 1131
1115 READ_BUF(4); 1132 status = nfsd4_decode_opaque(argp, &exid->clname);
1116 READ32(exid->clname.len); 1133 if (status)
1117 1134 return nfserr_bad_xdr;
1118 READ_BUF(exid->clname.len);
1119 SAVEMEM(exid->clname.data, exid->clname.len);
1120 1135
1121 READ_BUF(4); 1136 READ_BUF(4);
1122 READ32(exid->flags); 1137 READ32(exid->flags);
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index c9012149637c..4c8a7ec3f25d 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -317,8 +317,7 @@ struct nfsd4_setattr {
317 317
318struct nfsd4_setclientid { 318struct nfsd4_setclientid {
319 nfs4_verifier se_verf; /* request */ 319 nfs4_verifier se_verf; /* request */
320 u32 se_namelen; /* request */ 320 struct xdr_netobj se_name;
321 char * se_name; /* request */
322 u32 se_callback_prog; /* request */ 321 u32 se_callback_prog; /* request */
323 u32 se_callback_netid_len; /* request */ 322 u32 se_callback_netid_len; /* request */
324 char * se_callback_netid_val; /* request */ 323 char * se_callback_netid_val; /* request */