hc
2023-12-11 1f93a7dfd1f8d5ff7a5c53246c7534fe2332d6f4
kernel/fs/nfsd/nfsxdr.c
....@@ -71,7 +71,7 @@
7171 }
7272
7373 static __be32 *
74
-decode_sattr(__be32 *p, struct iattr *iap)
74
+decode_sattr(__be32 *p, struct iattr *iap, struct user_namespace *userns)
7575 {
7676 u32 tmp, tmp1;
7777
....@@ -86,12 +86,12 @@
8686 iap->ia_mode = tmp;
8787 }
8888 if ((tmp = ntohl(*p++)) != (u32)-1) {
89
- iap->ia_uid = make_kuid(&init_user_ns, tmp);
89
+ iap->ia_uid = make_kuid(userns, tmp);
9090 if (uid_valid(iap->ia_uid))
9191 iap->ia_valid |= ATTR_UID;
9292 }
9393 if ((tmp = ntohl(*p++)) != (u32)-1) {
94
- iap->ia_gid = make_kgid(&init_user_ns, tmp);
94
+ iap->ia_gid = make_kgid(userns, tmp);
9595 if (gid_valid(iap->ia_gid))
9696 iap->ia_valid |= ATTR_GID;
9797 }
....@@ -129,6 +129,7 @@
129129 encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
130130 struct kstat *stat)
131131 {
132
+ struct user_namespace *userns = nfsd_user_namespace(rqstp);
132133 struct dentry *dentry = fhp->fh_dentry;
133134 int type;
134135 struct timespec64 time;
....@@ -139,8 +140,8 @@
139140 *p++ = htonl(nfs_ftypes[type >> 12]);
140141 *p++ = htonl((u32) stat->mode);
141142 *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));
144145
145146 if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) {
146147 *p++ = htonl(NFS_MAXPATHLEN);
....@@ -216,7 +217,7 @@
216217 p = decode_fh(p, &args->fh);
217218 if (!p)
218219 return 0;
219
- p = decode_sattr(p, &args->attrs);
220
+ p = decode_sattr(p, &args->attrs, nfsd_user_namespace(rqstp));
220221
221222 return xdr_argsize_check(rqstp, p);
222223 }
....@@ -319,7 +320,7 @@
319320 if ( !(p = decode_fh(p, &args->fh))
320321 || !(p = decode_filename(p, &args->name, &args->len)))
321322 return 0;
322
- p = decode_sattr(p, &args->attrs);
323
+ p = decode_sattr(p, &args->attrs, nfsd_user_namespace(rqstp));
323324
324325 return xdr_argsize_check(rqstp, p);
325326 }
....@@ -398,7 +399,7 @@
398399 return 0;
399400 p += xdrlen;
400401 }
401
- decode_sattr(p, &args->attrs);
402
+ decode_sattr(p, &args->attrs, nfsd_user_namespace(rqstp));
402403
403404 return 1;
404405 }
....@@ -429,11 +430,24 @@
429430 }
430431
431432 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
432442 nfssvc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p)
433443 {
434444 struct nfsd_attrstat *resp = rqstp->rq_resp;
435445
446
+ *p++ = resp->status;
447
+ if (resp->status != nfs_ok)
448
+ goto out;
436449 p = encode_fattr(rqstp, p, &resp->fh, &resp->stat);
450
+out:
437451 return xdr_ressize_check(rqstp, p);
438452 }
439453
....@@ -442,8 +456,12 @@
442456 {
443457 struct nfsd_diropres *resp = rqstp->rq_resp;
444458
459
+ *p++ = resp->status;
460
+ if (resp->status != nfs_ok)
461
+ goto out;
445462 p = encode_fh(p, &resp->fh);
446463 p = encode_fattr(rqstp, p, &resp->fh, &resp->stat);
464
+out:
447465 return xdr_ressize_check(rqstp, p);
448466 }
449467
....@@ -451,6 +469,10 @@
451469 nfssvc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p)
452470 {
453471 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);
454476
455477 *p++ = htonl(resp->len);
456478 xdr_ressize_check(rqstp, p);
....@@ -468,6 +490,10 @@
468490 nfssvc_encode_readres(struct svc_rqst *rqstp, __be32 *p)
469491 {
470492 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);
471497
472498 p = encode_fattr(rqstp, p, &resp->fh, &resp->stat);
473499 *p++ = htonl(resp->count);
....@@ -489,6 +515,10 @@
489515 {
490516 struct nfsd_readdirres *resp = rqstp->rq_resp;
491517
518
+ *p++ = resp->status;
519
+ if (resp->status != nfs_ok)
520
+ return xdr_ressize_check(rqstp, p);
521
+
492522 xdr_ressize_check(rqstp, p);
493523 p = resp->buffer;
494524 *p++ = 0; /* no more entries */
....@@ -503,6 +533,10 @@
503533 {
504534 struct nfsd_statfsres *resp = rqstp->rq_resp;
505535 struct kstatfs *stat = &resp->stats;
536
+
537
+ *p++ = resp->status;
538
+ if (resp->status != nfs_ok)
539
+ return xdr_ressize_check(rqstp, p);
506540
507541 *p++ = htonl(NFSSVC_MAXBLKSIZE_V2); /* max transfer size */
508542 *p++ = htonl(stat->f_bsize);
....@@ -560,10 +594,23 @@
560594 /*
561595 * XDR release functions
562596 */
563
-void
564
-nfssvc_release_fhandle(struct svc_rqst *rqstp)
597
+void nfssvc_release_attrstat(struct svc_rqst *rqstp)
565598 {
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;
567614
568615 fh_put(&resp->fh);
569616 }