aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfsxdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfsxdr.c')
-rw-r--r--fs/nfsd/nfsxdr.c53
1 files changed, 37 insertions, 16 deletions
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 0c24b9e24fe8..cb3e7fadb772 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -231,9 +231,10 @@ int
231nfssvc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p, 231nfssvc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p,
232 struct nfsd_sattrargs *args) 232 struct nfsd_sattrargs *args)
233{ 233{
234 if (!(p = decode_fh(p, &args->fh)) 234 p = decode_fh(p, &args->fh);
235 || !(p = decode_sattr(p, &args->attrs))) 235 if (!p)
236 return 0; 236 return 0;
237 p = decode_sattr(p, &args->attrs);
237 238
238 return xdr_argsize_check(rqstp, p); 239 return xdr_argsize_check(rqstp, p);
239} 240}
@@ -284,8 +285,9 @@ int
284nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, 285nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
285 struct nfsd_writeargs *args) 286 struct nfsd_writeargs *args)
286{ 287{
287 unsigned int len; 288 unsigned int len, hdr, dlen;
288 int v; 289 int v;
290
289 if (!(p = decode_fh(p, &args->fh))) 291 if (!(p = decode_fh(p, &args->fh)))
290 return 0; 292 return 0;
291 293
@@ -293,11 +295,30 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
293 args->offset = ntohl(*p++); /* offset */ 295 args->offset = ntohl(*p++); /* offset */
294 p++; /* totalcount */ 296 p++; /* totalcount */
295 len = args->len = ntohl(*p++); 297 len = args->len = ntohl(*p++);
296 rqstp->rq_vec[0].iov_base = (void*)p; 298 /*
297 rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - 299 * The protocol specifies a maximum of 8192 bytes.
298 (((void*)p) - rqstp->rq_arg.head[0].iov_base); 300 */
299 if (len > NFSSVC_MAXBLKSIZE_V2) 301 if (len > NFSSVC_MAXBLKSIZE_V2)
300 len = NFSSVC_MAXBLKSIZE_V2; 302 return 0;
303
304 /*
305 * Check to make sure that we got the right number of
306 * bytes.
307 */
308 hdr = (void*)p - rqstp->rq_arg.head[0].iov_base;
309 dlen = rqstp->rq_arg.head[0].iov_len + rqstp->rq_arg.page_len
310 - hdr;
311
312 /*
313 * Round the length of the data which was specified up to
314 * the next multiple of XDR units and then compare that
315 * against the length which was actually received.
316 */
317 if (dlen != XDR_QUADLEN(len)*4)
318 return 0;
319
320 rqstp->rq_vec[0].iov_base = (void*)p;
321 rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr;
301 v = 0; 322 v = 0;
302 while (len > rqstp->rq_vec[v].iov_len) { 323 while (len > rqstp->rq_vec[v].iov_len) {
303 len -= rqstp->rq_vec[v].iov_len; 324 len -= rqstp->rq_vec[v].iov_len;
@@ -306,18 +327,18 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
306 rqstp->rq_vec[v].iov_len = PAGE_SIZE; 327 rqstp->rq_vec[v].iov_len = PAGE_SIZE;
307 } 328 }
308 rqstp->rq_vec[v].iov_len = len; 329 rqstp->rq_vec[v].iov_len = len;
309 args->vlen = v+1; 330 args->vlen = v + 1;
310 return rqstp->rq_vec[0].iov_len > 0; 331 return 1;
311} 332}
312 333
313int 334int
314nfssvc_decode_createargs(struct svc_rqst *rqstp, __be32 *p, 335nfssvc_decode_createargs(struct svc_rqst *rqstp, __be32 *p,
315 struct nfsd_createargs *args) 336 struct nfsd_createargs *args)
316{ 337{
317 if (!(p = decode_fh(p, &args->fh)) 338 if ( !(p = decode_fh(p, &args->fh))
318 || !(p = decode_filename(p, &args->name, &args->len)) 339 || !(p = decode_filename(p, &args->name, &args->len)))
319 || !(p = decode_sattr(p, &args->attrs)))
320 return 0; 340 return 0;
341 p = decode_sattr(p, &args->attrs);
321 342
322 return xdr_argsize_check(rqstp, p); 343 return xdr_argsize_check(rqstp, p);
323} 344}
@@ -361,11 +382,11 @@ int
361nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p, 382nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p,
362 struct nfsd_symlinkargs *args) 383 struct nfsd_symlinkargs *args)
363{ 384{
364 if (!(p = decode_fh(p, &args->ffh)) 385 if ( !(p = decode_fh(p, &args->ffh))
365 || !(p = decode_filename(p, &args->fname, &args->flen)) 386 || !(p = decode_filename(p, &args->fname, &args->flen))
366 || !(p = decode_pathname(p, &args->tname, &args->tlen)) 387 || !(p = decode_pathname(p, &args->tname, &args->tlen)))
367 || !(p = decode_sattr(p, &args->attrs)))
368 return 0; 388 return 0;
389 p = decode_sattr(p, &args->attrs);
369 390
370 return xdr_argsize_check(rqstp, p); 391 return xdr_argsize_check(rqstp, p);
371} 392}