@@ -186,28 +186,6 @@ svcxdr_dupstr(struct nfsd4_compoundargs *argp, void *buf, u32 len)
186186 return p ;
187187}
188188
189- /**
190- * savemem - duplicate a chunk of memory for later processing
191- * @argp: NFSv4 compound argument structure to be freed with
192- * @p: pointer to be duplicated
193- * @nbytes: length to be duplicated
194- *
195- * Returns a pointer to a copy of @nbytes bytes of memory at @p
196- * that are preserved until processing of the NFSv4 compound
197- * operation described by @argp finishes.
198- */
199- static char * savemem (struct nfsd4_compoundargs * argp , __be32 * p , int nbytes )
200- {
201- void * ret ;
202-
203- ret = svcxdr_tmpalloc (argp , nbytes );
204- if (!ret )
205- return NULL ;
206- memcpy (ret , p , nbytes );
207- return ret ;
208- }
209-
210-
211189/*
212190 * NFSv4 basic data type decoders
213191 */
@@ -2372,43 +2350,54 @@ nfsd4_opnum_in_range(struct nfsd4_compoundargs *argp, struct nfsd4_op *op)
23722350 return true;
23732351}
23742352
2375- static __be32
2353+ static int
23762354nfsd4_decode_compound (struct nfsd4_compoundargs * argp )
23772355{
2378- DECODE_HEAD ;
23792356 struct nfsd4_op * op ;
23802357 bool cachethis = false;
23812358 int auth_slack = argp -> rqstp -> rq_auth_slack ;
23822359 int max_reply = auth_slack + 8 ; /* opcnt, status */
23832360 int readcount = 0 ;
23842361 int readbytes = 0 ;
2362+ __be32 * p ;
23852363 int i ;
23862364
2387- READ_BUF (4 );
2388- argp -> taglen = be32_to_cpup (p ++ );
2389- READ_BUF (argp -> taglen );
2390- SAVEMEM (argp -> tag , argp -> taglen );
2391- READ_BUF (8 );
2392- argp -> minorversion = be32_to_cpup (p ++ );
2393- argp -> opcnt = be32_to_cpup (p ++ );
2394- max_reply += 4 + (XDR_QUADLEN (argp -> taglen ) << 2 );
2395-
2396- if (argp -> taglen > NFSD4_MAX_TAGLEN )
2397- goto xdr_error ;
2365+ if (xdr_stream_decode_u32 (argp -> xdr , & argp -> taglen ) < 0 )
2366+ return 0 ;
2367+ max_reply += XDR_UNIT ;
2368+ argp -> tag = NULL ;
2369+ if (unlikely (argp -> taglen )) {
2370+ if (argp -> taglen > NFSD4_MAX_TAGLEN )
2371+ return 0 ;
2372+ p = xdr_inline_decode (argp -> xdr , argp -> taglen );
2373+ if (!p )
2374+ return 0 ;
2375+ argp -> tag = svcxdr_tmpalloc (argp , argp -> taglen );
2376+ if (!argp -> tag )
2377+ return 0 ;
2378+ memcpy (argp -> tag , p , argp -> taglen );
2379+ max_reply += xdr_align_size (argp -> taglen );
2380+ }
2381+
2382+ if (xdr_stream_decode_u32 (argp -> xdr , & argp -> minorversion ) < 0 )
2383+ return 0 ;
2384+ if (xdr_stream_decode_u32 (argp -> xdr , & argp -> opcnt ) < 0 )
2385+ return 0 ;
2386+
23982387 /*
23992388 * NFS4ERR_RESOURCE is a more helpful error than GARBAGE_ARGS
24002389 * here, so we return success at the xdr level so that
24012390 * nfsd4_proc can handle this is an NFS-level error.
24022391 */
24032392 if (argp -> opcnt > NFSD_MAX_OPS_PER_COMPOUND )
2404- return 0 ;
2393+ return 1 ;
24052394
24062395 if (argp -> opcnt > ARRAY_SIZE (argp -> iops )) {
24072396 argp -> ops = kzalloc (argp -> opcnt * sizeof (* argp -> ops ), GFP_KERNEL );
24082397 if (!argp -> ops ) {
24092398 argp -> ops = argp -> iops ;
24102399 dprintk ("nfsd: couldn't allocate room for COMPOUND\n" );
2411- goto xdr_error ;
2400+ return 0 ;
24122401 }
24132402 }
24142403
@@ -2420,7 +2409,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
24202409 op -> replay = NULL ;
24212410
24222411 if (xdr_stream_decode_u32 (argp -> xdr , & op -> opnum ) < 0 )
2423- return nfserr_bad_xdr ;
2412+ return 0 ;
24242413 if (nfsd4_opnum_in_range (argp , op )) {
24252414 op -> status = nfsd4_dec_ops [op -> opnum ](argp , & op -> u );
24262415 if (op -> status != nfs_ok )
@@ -2467,7 +2456,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
24672456 if (readcount > 1 || max_reply > PAGE_SIZE - auth_slack )
24682457 clear_bit (RQ_SPLICE_OK , & argp -> rqstp -> rq_flags );
24692458
2470- DECODE_TAIL ;
2459+ return 1 ;
24712460}
24722461
24732462static __be32 * encode_change (__be32 * p , struct kstat * stat , struct inode * inode ,
@@ -5479,7 +5468,7 @@ nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p)
54795468 args -> ops = args -> iops ;
54805469 args -> rqstp = rqstp ;
54815470
5482- return ! nfsd4_decode_compound (args );
5471+ return nfsd4_decode_compound (args );
54835472}
54845473
54855474int
0 commit comments