diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfsd/nfs3xdr.c | 55 | ||||
-rw-r--r-- | fs/nfsd/nfsxdr.c | 39 |
2 files changed, 34 insertions, 60 deletions
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 43fb360784b7..10f6e7dcf633 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c | |||
@@ -239,7 +239,7 @@ static __be32 * | |||
239 | encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) | 239 | encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) |
240 | { | 240 | { |
241 | struct dentry *dentry = fhp->fh_dentry; | 241 | struct dentry *dentry = fhp->fh_dentry; |
242 | if (dentry && dentry->d_inode != NULL) { | 242 | if (dentry && dentry->d_inode) { |
243 | int err; | 243 | int err; |
244 | struct kstat stat; | 244 | struct kstat stat; |
245 | 245 | ||
@@ -300,9 +300,9 @@ int | |||
300 | nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p, | 300 | nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p, |
301 | struct nfsd3_sattrargs *args) | 301 | struct nfsd3_sattrargs *args) |
302 | { | 302 | { |
303 | if (!(p = decode_fh(p, &args->fh)) | 303 | if (!(p = decode_fh(p, &args->fh))) |
304 | || !(p = decode_sattr3(p, &args->attrs))) | ||
305 | return 0; | 304 | return 0; |
305 | p = decode_sattr3(p, &args->attrs); | ||
306 | 306 | ||
307 | if ((args->check_guard = ntohl(*p++)) != 0) { | 307 | if ((args->check_guard = ntohl(*p++)) != 0) { |
308 | struct timespec time; | 308 | struct timespec time; |
@@ -343,9 +343,9 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p, | |||
343 | int v,pn; | 343 | int v,pn; |
344 | u32 max_blocksize = svc_max_payload(rqstp); | 344 | u32 max_blocksize = svc_max_payload(rqstp); |
345 | 345 | ||
346 | if (!(p = decode_fh(p, &args->fh)) | 346 | if (!(p = decode_fh(p, &args->fh))) |
347 | || !(p = xdr_decode_hyper(p, &args->offset))) | ||
348 | return 0; | 347 | return 0; |
348 | p = xdr_decode_hyper(p, &args->offset); | ||
349 | 349 | ||
350 | len = args->count = ntohl(*p++); | 350 | len = args->count = ntohl(*p++); |
351 | 351 | ||
@@ -372,9 +372,9 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, | |||
372 | unsigned int len, v, hdr, dlen; | 372 | unsigned int len, v, hdr, dlen; |
373 | u32 max_blocksize = svc_max_payload(rqstp); | 373 | u32 max_blocksize = svc_max_payload(rqstp); |
374 | 374 | ||
375 | if (!(p = decode_fh(p, &args->fh)) | 375 | if (!(p = decode_fh(p, &args->fh))) |
376 | || !(p = xdr_decode_hyper(p, &args->offset))) | ||
377 | return 0; | 376 | return 0; |
377 | p = xdr_decode_hyper(p, &args->offset); | ||
378 | 378 | ||
379 | args->count = ntohl(*p++); | 379 | args->count = ntohl(*p++); |
380 | args->stable = ntohl(*p++); | 380 | args->stable = ntohl(*p++); |
@@ -388,29 +388,16 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, | |||
388 | /* | 388 | /* |
389 | * Check to make sure that we got the right number of | 389 | * Check to make sure that we got the right number of |
390 | * bytes. | 390 | * bytes. |
391 | * | ||
392 | * If more than one page was used, then compute the length | ||
393 | * of the data in the request as the total size of the | ||
394 | * request minus the transport protocol headers minus the | ||
395 | * RPC protocol headers minus the NFS protocol fields | ||
396 | * already consumed. If the request fits into a single | ||
397 | * page, then compete the length of the data as the size | ||
398 | * of the NFS portion of the request minus the NFS | ||
399 | * protocol fields already consumed. | ||
400 | */ | 391 | */ |
401 | hdr = (void*)p - rqstp->rq_arg.head[0].iov_base; | 392 | hdr = (void*)p - rqstp->rq_arg.head[0].iov_base; |
402 | if (rqstp->rq_respages != rqstp->rq_pages + 1) { | 393 | dlen = rqstp->rq_arg.head[0].iov_len + rqstp->rq_arg.page_len |
403 | dlen = rqstp->rq_arg.len - | 394 | - hdr; |
404 | (PAGE_SIZE - rqstp->rq_arg.head[0].iov_len) - hdr; | ||
405 | } else { | ||
406 | dlen = rqstp->rq_arg.head[0].iov_len - hdr; | ||
407 | } | ||
408 | /* | 395 | /* |
409 | * Round the length of the data which was specified up to | 396 | * Round the length of the data which was specified up to |
410 | * the next multiple of XDR units and then compare that | 397 | * the next multiple of XDR units and then compare that |
411 | * against the length which was actually received. | 398 | * against the length which was actually received. |
412 | */ | 399 | */ |
413 | if (dlen != ((len + 3) & ~0x3)) | 400 | if (dlen != XDR_QUADLEN(len)*4) |
414 | return 0; | 401 | return 0; |
415 | 402 | ||
416 | if (args->count > max_blocksize) { | 403 | if (args->count > max_blocksize) { |
@@ -442,8 +429,7 @@ nfs3svc_decode_createargs(struct svc_rqst *rqstp, __be32 *p, | |||
442 | switch (args->createmode = ntohl(*p++)) { | 429 | switch (args->createmode = ntohl(*p++)) { |
443 | case NFS3_CREATE_UNCHECKED: | 430 | case NFS3_CREATE_UNCHECKED: |
444 | case NFS3_CREATE_GUARDED: | 431 | case NFS3_CREATE_GUARDED: |
445 | if (!(p = decode_sattr3(p, &args->attrs))) | 432 | p = decode_sattr3(p, &args->attrs); |
446 | return 0; | ||
447 | break; | 433 | break; |
448 | case NFS3_CREATE_EXCLUSIVE: | 434 | case NFS3_CREATE_EXCLUSIVE: |
449 | args->verf = p; | 435 | args->verf = p; |
@@ -459,10 +445,10 @@ int | |||
459 | nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, __be32 *p, | 445 | nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, __be32 *p, |
460 | struct nfsd3_createargs *args) | 446 | struct nfsd3_createargs *args) |
461 | { | 447 | { |
462 | if (!(p = decode_fh(p, &args->fh)) | 448 | if (!(p = decode_fh(p, &args->fh)) || |
463 | || !(p = decode_filename(p, &args->name, &args->len)) | 449 | !(p = decode_filename(p, &args->name, &args->len))) |
464 | || !(p = decode_sattr3(p, &args->attrs))) | ||
465 | return 0; | 450 | return 0; |
451 | p = decode_sattr3(p, &args->attrs); | ||
466 | 452 | ||
467 | return xdr_argsize_check(rqstp, p); | 453 | return xdr_argsize_check(rqstp, p); |
468 | } | 454 | } |
@@ -476,11 +462,12 @@ nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p, | |||
476 | char *old, *new; | 462 | char *old, *new; |
477 | struct kvec *vec; | 463 | struct kvec *vec; |
478 | 464 | ||
479 | if (!(p = decode_fh(p, &args->ffh)) | 465 | if (!(p = decode_fh(p, &args->ffh)) || |
480 | || !(p = decode_filename(p, &args->fname, &args->flen)) | 466 | !(p = decode_filename(p, &args->fname, &args->flen)) |
481 | || !(p = decode_sattr3(p, &args->attrs)) | ||
482 | ) | 467 | ) |
483 | return 0; | 468 | return 0; |
469 | p = decode_sattr3(p, &args->attrs); | ||
470 | |||
484 | /* now decode the pathname, which might be larger than the first page. | 471 | /* now decode the pathname, which might be larger than the first page. |
485 | * As we have to check for nul's anyway, we copy it into a new page | 472 | * As we have to check for nul's anyway, we copy it into a new page |
486 | * This page appears in the rq_res.pages list, but as pages_len is always | 473 | * This page appears in the rq_res.pages list, but as pages_len is always |
@@ -530,10 +517,8 @@ nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, __be32 *p, | |||
530 | args->ftype = ntohl(*p++); | 517 | args->ftype = ntohl(*p++); |
531 | 518 | ||
532 | if (args->ftype == NF3BLK || args->ftype == NF3CHR | 519 | if (args->ftype == NF3BLK || args->ftype == NF3CHR |
533 | || args->ftype == NF3SOCK || args->ftype == NF3FIFO) { | 520 | || args->ftype == NF3SOCK || args->ftype == NF3FIFO) |
534 | if (!(p = decode_sattr3(p, &args->attrs))) | 521 | p = decode_sattr3(p, &args->attrs); |
535 | return 0; | ||
536 | } | ||
537 | 522 | ||
538 | if (args->ftype == NF3BLK || args->ftype == NF3CHR) { | 523 | if (args->ftype == NF3BLK || args->ftype == NF3CHR) { |
539 | args->major = ntohl(*p++); | 524 | args->major = ntohl(*p++); |
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c index 6035e03655c6..cb3e7fadb772 100644 --- a/fs/nfsd/nfsxdr.c +++ b/fs/nfsd/nfsxdr.c | |||
@@ -231,9 +231,10 @@ int | |||
231 | nfssvc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p, | 231 | nfssvc_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 | } |
@@ -303,29 +304,17 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, | |||
303 | /* | 304 | /* |
304 | * Check to make sure that we got the right number of | 305 | * Check to make sure that we got the right number of |
305 | * bytes. | 306 | * bytes. |
306 | * | ||
307 | * If more than one page was used, then compute the length | ||
308 | * of the data in the request as the total size of the | ||
309 | * request minus the transport protocol headers minus the | ||
310 | * RPC protocol headers minus the NFS protocol fields | ||
311 | * already consumed. If the request fits into a single | ||
312 | * page, then compete the length of the data as the size | ||
313 | * of the NFS portion of the request minus the NFS | ||
314 | * protocol fields already consumed. | ||
315 | */ | 307 | */ |
316 | hdr = (void*)p - rqstp->rq_arg.head[0].iov_base; | 308 | hdr = (void*)p - rqstp->rq_arg.head[0].iov_base; |
317 | if (rqstp->rq_respages != rqstp->rq_pages + 1) { | 309 | dlen = rqstp->rq_arg.head[0].iov_len + rqstp->rq_arg.page_len |
318 | dlen = rqstp->rq_arg.len - | 310 | - hdr; |
319 | (PAGE_SIZE - rqstp->rq_arg.head[0].iov_len) - hdr; | 311 | |
320 | } else { | ||
321 | dlen = rqstp->rq_arg.head[0].iov_len - hdr; | ||
322 | } | ||
323 | /* | 312 | /* |
324 | * Round the length of the data which was specified up to | 313 | * Round the length of the data which was specified up to |
325 | * the next multiple of XDR units and then compare that | 314 | * the next multiple of XDR units and then compare that |
326 | * against the length which was actually received. | 315 | * against the length which was actually received. |
327 | */ | 316 | */ |
328 | if (dlen != ((len + 3) & ~0x3)) | 317 | if (dlen != XDR_QUADLEN(len)*4) |
329 | return 0; | 318 | return 0; |
330 | 319 | ||
331 | rqstp->rq_vec[0].iov_base = (void*)p; | 320 | rqstp->rq_vec[0].iov_base = (void*)p; |
@@ -346,10 +335,10 @@ int | |||
346 | nfssvc_decode_createargs(struct svc_rqst *rqstp, __be32 *p, | 335 | nfssvc_decode_createargs(struct svc_rqst *rqstp, __be32 *p, |
347 | struct nfsd_createargs *args) | 336 | struct nfsd_createargs *args) |
348 | { | 337 | { |
349 | if (!(p = decode_fh(p, &args->fh)) | 338 | if ( !(p = decode_fh(p, &args->fh)) |
350 | || !(p = decode_filename(p, &args->name, &args->len)) | 339 | || !(p = decode_filename(p, &args->name, &args->len))) |
351 | || !(p = decode_sattr(p, &args->attrs))) | ||
352 | return 0; | 340 | return 0; |
341 | p = decode_sattr(p, &args->attrs); | ||
353 | 342 | ||
354 | return xdr_argsize_check(rqstp, p); | 343 | return xdr_argsize_check(rqstp, p); |
355 | } | 344 | } |
@@ -393,11 +382,11 @@ int | |||
393 | nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p, | 382 | nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p, |
394 | struct nfsd_symlinkargs *args) | 383 | struct nfsd_symlinkargs *args) |
395 | { | 384 | { |
396 | if (!(p = decode_fh(p, &args->ffh)) | 385 | if ( !(p = decode_fh(p, &args->ffh)) |
397 | || !(p = decode_filename(p, &args->fname, &args->flen)) | 386 | || !(p = decode_filename(p, &args->fname, &args->flen)) |
398 | || !(p = decode_pathname(p, &args->tname, &args->tlen)) | 387 | || !(p = decode_pathname(p, &args->tname, &args->tlen))) |
399 | || !(p = decode_sattr(p, &args->attrs))) | ||
400 | return 0; | 388 | return 0; |
389 | p = decode_sattr(p, &args->attrs); | ||
401 | 390 | ||
402 | return xdr_argsize_check(rqstp, p); | 391 | return xdr_argsize_check(rqstp, p); |
403 | } | 392 | } |