| .. | .. |
|---|
| 71 | 71 | } |
|---|
| 72 | 72 | |
|---|
| 73 | 73 | static __be32 * |
|---|
| 74 | | -decode_sattr(__be32 *p, struct iattr *iap) |
|---|
| 74 | +decode_sattr(__be32 *p, struct iattr *iap, struct user_namespace *userns) |
|---|
| 75 | 75 | { |
|---|
| 76 | 76 | u32 tmp, tmp1; |
|---|
| 77 | 77 | |
|---|
| .. | .. |
|---|
| 86 | 86 | iap->ia_mode = tmp; |
|---|
| 87 | 87 | } |
|---|
| 88 | 88 | if ((tmp = ntohl(*p++)) != (u32)-1) { |
|---|
| 89 | | - iap->ia_uid = make_kuid(&init_user_ns, tmp); |
|---|
| 89 | + iap->ia_uid = make_kuid(userns, tmp); |
|---|
| 90 | 90 | if (uid_valid(iap->ia_uid)) |
|---|
| 91 | 91 | iap->ia_valid |= ATTR_UID; |
|---|
| 92 | 92 | } |
|---|
| 93 | 93 | if ((tmp = ntohl(*p++)) != (u32)-1) { |
|---|
| 94 | | - iap->ia_gid = make_kgid(&init_user_ns, tmp); |
|---|
| 94 | + iap->ia_gid = make_kgid(userns, tmp); |
|---|
| 95 | 95 | if (gid_valid(iap->ia_gid)) |
|---|
| 96 | 96 | iap->ia_valid |= ATTR_GID; |
|---|
| 97 | 97 | } |
|---|
| .. | .. |
|---|
| 129 | 129 | encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, |
|---|
| 130 | 130 | struct kstat *stat) |
|---|
| 131 | 131 | { |
|---|
| 132 | + struct user_namespace *userns = nfsd_user_namespace(rqstp); |
|---|
| 132 | 133 | struct dentry *dentry = fhp->fh_dentry; |
|---|
| 133 | 134 | int type; |
|---|
| 134 | 135 | struct timespec64 time; |
|---|
| .. | .. |
|---|
| 139 | 140 | *p++ = htonl(nfs_ftypes[type >> 12]); |
|---|
| 140 | 141 | *p++ = htonl((u32) stat->mode); |
|---|
| 141 | 142 | *p++ = htonl((u32) stat->nlink); |
|---|
| 142 | | - *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid)); |
|---|
| 143 | | - *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid)); |
|---|
| 143 | + *p++ = htonl((u32) from_kuid_munged(userns, stat->uid)); |
|---|
| 144 | + *p++ = htonl((u32) from_kgid_munged(userns, stat->gid)); |
|---|
| 144 | 145 | |
|---|
| 145 | 146 | if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) { |
|---|
| 146 | 147 | *p++ = htonl(NFS_MAXPATHLEN); |
|---|
| .. | .. |
|---|
| 216 | 217 | p = decode_fh(p, &args->fh); |
|---|
| 217 | 218 | if (!p) |
|---|
| 218 | 219 | return 0; |
|---|
| 219 | | - p = decode_sattr(p, &args->attrs); |
|---|
| 220 | + p = decode_sattr(p, &args->attrs, nfsd_user_namespace(rqstp)); |
|---|
| 220 | 221 | |
|---|
| 221 | 222 | return xdr_argsize_check(rqstp, p); |
|---|
| 222 | 223 | } |
|---|
| .. | .. |
|---|
| 319 | 320 | if ( !(p = decode_fh(p, &args->fh)) |
|---|
| 320 | 321 | || !(p = decode_filename(p, &args->name, &args->len))) |
|---|
| 321 | 322 | return 0; |
|---|
| 322 | | - p = decode_sattr(p, &args->attrs); |
|---|
| 323 | + p = decode_sattr(p, &args->attrs, nfsd_user_namespace(rqstp)); |
|---|
| 323 | 324 | |
|---|
| 324 | 325 | return xdr_argsize_check(rqstp, p); |
|---|
| 325 | 326 | } |
|---|
| .. | .. |
|---|
| 398 | 399 | return 0; |
|---|
| 399 | 400 | p += xdrlen; |
|---|
| 400 | 401 | } |
|---|
| 401 | | - decode_sattr(p, &args->attrs); |
|---|
| 402 | + decode_sattr(p, &args->attrs, nfsd_user_namespace(rqstp)); |
|---|
| 402 | 403 | |
|---|
| 403 | 404 | return 1; |
|---|
| 404 | 405 | } |
|---|
| .. | .. |
|---|
| 429 | 430 | } |
|---|
| 430 | 431 | |
|---|
| 431 | 432 | int |
|---|
| 433 | +nfssvc_encode_stat(struct svc_rqst *rqstp, __be32 *p) |
|---|
| 434 | +{ |
|---|
| 435 | + struct nfsd_stat *resp = rqstp->rq_resp; |
|---|
| 436 | + |
|---|
| 437 | + *p++ = resp->status; |
|---|
| 438 | + return xdr_ressize_check(rqstp, p); |
|---|
| 439 | +} |
|---|
| 440 | + |
|---|
| 441 | +int |
|---|
| 432 | 442 | nfssvc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p) |
|---|
| 433 | 443 | { |
|---|
| 434 | 444 | struct nfsd_attrstat *resp = rqstp->rq_resp; |
|---|
| 435 | 445 | |
|---|
| 446 | + *p++ = resp->status; |
|---|
| 447 | + if (resp->status != nfs_ok) |
|---|
| 448 | + goto out; |
|---|
| 436 | 449 | p = encode_fattr(rqstp, p, &resp->fh, &resp->stat); |
|---|
| 450 | +out: |
|---|
| 437 | 451 | return xdr_ressize_check(rqstp, p); |
|---|
| 438 | 452 | } |
|---|
| 439 | 453 | |
|---|
| .. | .. |
|---|
| 442 | 456 | { |
|---|
| 443 | 457 | struct nfsd_diropres *resp = rqstp->rq_resp; |
|---|
| 444 | 458 | |
|---|
| 459 | + *p++ = resp->status; |
|---|
| 460 | + if (resp->status != nfs_ok) |
|---|
| 461 | + goto out; |
|---|
| 445 | 462 | p = encode_fh(p, &resp->fh); |
|---|
| 446 | 463 | p = encode_fattr(rqstp, p, &resp->fh, &resp->stat); |
|---|
| 464 | +out: |
|---|
| 447 | 465 | return xdr_ressize_check(rqstp, p); |
|---|
| 448 | 466 | } |
|---|
| 449 | 467 | |
|---|
| .. | .. |
|---|
| 451 | 469 | nfssvc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p) |
|---|
| 452 | 470 | { |
|---|
| 453 | 471 | struct nfsd_readlinkres *resp = rqstp->rq_resp; |
|---|
| 472 | + |
|---|
| 473 | + *p++ = resp->status; |
|---|
| 474 | + if (resp->status != nfs_ok) |
|---|
| 475 | + return xdr_ressize_check(rqstp, p); |
|---|
| 454 | 476 | |
|---|
| 455 | 477 | *p++ = htonl(resp->len); |
|---|
| 456 | 478 | xdr_ressize_check(rqstp, p); |
|---|
| .. | .. |
|---|
| 468 | 490 | nfssvc_encode_readres(struct svc_rqst *rqstp, __be32 *p) |
|---|
| 469 | 491 | { |
|---|
| 470 | 492 | struct nfsd_readres *resp = rqstp->rq_resp; |
|---|
| 493 | + |
|---|
| 494 | + *p++ = resp->status; |
|---|
| 495 | + if (resp->status != nfs_ok) |
|---|
| 496 | + return xdr_ressize_check(rqstp, p); |
|---|
| 471 | 497 | |
|---|
| 472 | 498 | p = encode_fattr(rqstp, p, &resp->fh, &resp->stat); |
|---|
| 473 | 499 | *p++ = htonl(resp->count); |
|---|
| .. | .. |
|---|
| 489 | 515 | { |
|---|
| 490 | 516 | struct nfsd_readdirres *resp = rqstp->rq_resp; |
|---|
| 491 | 517 | |
|---|
| 518 | + *p++ = resp->status; |
|---|
| 519 | + if (resp->status != nfs_ok) |
|---|
| 520 | + return xdr_ressize_check(rqstp, p); |
|---|
| 521 | + |
|---|
| 492 | 522 | xdr_ressize_check(rqstp, p); |
|---|
| 493 | 523 | p = resp->buffer; |
|---|
| 494 | 524 | *p++ = 0; /* no more entries */ |
|---|
| .. | .. |
|---|
| 503 | 533 | { |
|---|
| 504 | 534 | struct nfsd_statfsres *resp = rqstp->rq_resp; |
|---|
| 505 | 535 | struct kstatfs *stat = &resp->stats; |
|---|
| 536 | + |
|---|
| 537 | + *p++ = resp->status; |
|---|
| 538 | + if (resp->status != nfs_ok) |
|---|
| 539 | + return xdr_ressize_check(rqstp, p); |
|---|
| 506 | 540 | |
|---|
| 507 | 541 | *p++ = htonl(NFSSVC_MAXBLKSIZE_V2); /* max transfer size */ |
|---|
| 508 | 542 | *p++ = htonl(stat->f_bsize); |
|---|
| .. | .. |
|---|
| 560 | 594 | /* |
|---|
| 561 | 595 | * XDR release functions |
|---|
| 562 | 596 | */ |
|---|
| 563 | | -void |
|---|
| 564 | | -nfssvc_release_fhandle(struct svc_rqst *rqstp) |
|---|
| 597 | +void nfssvc_release_attrstat(struct svc_rqst *rqstp) |
|---|
| 565 | 598 | { |
|---|
| 566 | | - struct nfsd_fhandle *resp = rqstp->rq_resp; |
|---|
| 599 | + struct nfsd_attrstat *resp = rqstp->rq_resp; |
|---|
| 600 | + |
|---|
| 601 | + fh_put(&resp->fh); |
|---|
| 602 | +} |
|---|
| 603 | + |
|---|
| 604 | +void nfssvc_release_diropres(struct svc_rqst *rqstp) |
|---|
| 605 | +{ |
|---|
| 606 | + struct nfsd_diropres *resp = rqstp->rq_resp; |
|---|
| 607 | + |
|---|
| 608 | + fh_put(&resp->fh); |
|---|
| 609 | +} |
|---|
| 610 | + |
|---|
| 611 | +void nfssvc_release_readres(struct svc_rqst *rqstp) |
|---|
| 612 | +{ |
|---|
| 613 | + struct nfsd_readres *resp = rqstp->rq_resp; |
|---|
| 567 | 614 | |
|---|
| 568 | 615 | fh_put(&resp->fh); |
|---|
| 569 | 616 | } |
|---|