summaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/export.c18
-rw-r--r--fs/nfsd/nfs3xdr.c21
-rw-r--r--fs/nfsd/nfs4idmap.c8
-rw-r--r--fs/nfsd/nfs4xdr.c5
-rw-r--r--fs/nfsd/nfsd.h7
-rw-r--r--fs/nfsd/nfsxdr.c17
6 files changed, 44 insertions, 32 deletions
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 802993d8912f..baa01956a5b3 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -570,13 +570,13 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
570 err = get_int(&mesg, &an_int); 570 err = get_int(&mesg, &an_int);
571 if (err) 571 if (err)
572 goto out3; 572 goto out3;
573 exp.ex_anon_uid= make_kuid(&init_user_ns, an_int); 573 exp.ex_anon_uid= make_kuid(current_user_ns(), an_int);
574 574
575 /* anon gid */ 575 /* anon gid */
576 err = get_int(&mesg, &an_int); 576 err = get_int(&mesg, &an_int);
577 if (err) 577 if (err)
578 goto out3; 578 goto out3;
579 exp.ex_anon_gid= make_kgid(&init_user_ns, an_int); 579 exp.ex_anon_gid= make_kgid(current_user_ns(), an_int);
580 580
581 /* fsid */ 581 /* fsid */
582 err = get_int(&mesg, &an_int); 582 err = get_int(&mesg, &an_int);
@@ -1170,15 +1170,17 @@ static void show_secinfo(struct seq_file *m, struct svc_export *exp)
1170static void exp_flags(struct seq_file *m, int flag, int fsid, 1170static void exp_flags(struct seq_file *m, int flag, int fsid,
1171 kuid_t anonu, kgid_t anong, struct nfsd4_fs_locations *fsloc) 1171 kuid_t anonu, kgid_t anong, struct nfsd4_fs_locations *fsloc)
1172{ 1172{
1173 struct user_namespace *userns = m->file->f_cred->user_ns;
1174
1173 show_expflags(m, flag, NFSEXP_ALLFLAGS); 1175 show_expflags(m, flag, NFSEXP_ALLFLAGS);
1174 if (flag & NFSEXP_FSID) 1176 if (flag & NFSEXP_FSID)
1175 seq_printf(m, ",fsid=%d", fsid); 1177 seq_printf(m, ",fsid=%d", fsid);
1176 if (!uid_eq(anonu, make_kuid(&init_user_ns, (uid_t)-2)) && 1178 if (!uid_eq(anonu, make_kuid(userns, (uid_t)-2)) &&
1177 !uid_eq(anonu, make_kuid(&init_user_ns, 0x10000-2))) 1179 !uid_eq(anonu, make_kuid(userns, 0x10000-2)))
1178 seq_printf(m, ",anonuid=%u", from_kuid(&init_user_ns, anonu)); 1180 seq_printf(m, ",anonuid=%u", from_kuid_munged(userns, anonu));
1179 if (!gid_eq(anong, make_kgid(&init_user_ns, (gid_t)-2)) && 1181 if (!gid_eq(anong, make_kgid(userns, (gid_t)-2)) &&
1180 !gid_eq(anong, make_kgid(&init_user_ns, 0x10000-2))) 1182 !gid_eq(anong, make_kgid(userns, 0x10000-2)))
1181 seq_printf(m, ",anongid=%u", from_kgid(&init_user_ns, anong)); 1183 seq_printf(m, ",anongid=%u", from_kgid_munged(userns, anong));
1182 if (fsloc && fsloc->locations_count > 0) { 1184 if (fsloc && fsloc->locations_count > 0) {
1183 char *loctype = (fsloc->migrated) ? "refer" : "replicas"; 1185 char *loctype = (fsloc->migrated) ? "refer" : "replicas";
1184 int i; 1186 int i;
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 8d789124ed3c..fcf31822c74c 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -96,7 +96,7 @@ decode_filename(__be32 *p, char **namp, unsigned int *lenp)
96} 96}
97 97
98static __be32 * 98static __be32 *
99decode_sattr3(__be32 *p, struct iattr *iap) 99decode_sattr3(__be32 *p, struct iattr *iap, struct user_namespace *userns)
100{ 100{
101 u32 tmp; 101 u32 tmp;
102 102
@@ -107,12 +107,12 @@ decode_sattr3(__be32 *p, struct iattr *iap)
107 iap->ia_mode = ntohl(*p++); 107 iap->ia_mode = ntohl(*p++);
108 } 108 }
109 if (*p++) { 109 if (*p++) {
110 iap->ia_uid = make_kuid(&init_user_ns, ntohl(*p++)); 110 iap->ia_uid = make_kuid(userns, ntohl(*p++));
111 if (uid_valid(iap->ia_uid)) 111 if (uid_valid(iap->ia_uid))
112 iap->ia_valid |= ATTR_UID; 112 iap->ia_valid |= ATTR_UID;
113 } 113 }
114 if (*p++) { 114 if (*p++) {
115 iap->ia_gid = make_kgid(&init_user_ns, ntohl(*p++)); 115 iap->ia_gid = make_kgid(userns, ntohl(*p++));
116 if (gid_valid(iap->ia_gid)) 116 if (gid_valid(iap->ia_gid))
117 iap->ia_valid |= ATTR_GID; 117 iap->ia_valid |= ATTR_GID;
118 } 118 }
@@ -165,12 +165,13 @@ static __be32 *
165encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, 165encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
166 struct kstat *stat) 166 struct kstat *stat)
167{ 167{
168 struct user_namespace *userns = nfsd_user_namespace(rqstp);
168 struct timespec ts; 169 struct timespec ts;
169 *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]); 170 *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
170 *p++ = htonl((u32) (stat->mode & S_IALLUGO)); 171 *p++ = htonl((u32) (stat->mode & S_IALLUGO));
171 *p++ = htonl((u32) stat->nlink); 172 *p++ = htonl((u32) stat->nlink);
172 *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid)); 173 *p++ = htonl((u32) from_kuid_munged(userns, stat->uid));
173 *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid)); 174 *p++ = htonl((u32) from_kgid_munged(userns, stat->gid));
174 if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) { 175 if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) {
175 p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN); 176 p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
176 } else { 177 } else {
@@ -325,7 +326,7 @@ nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p)
325 p = decode_fh(p, &args->fh); 326 p = decode_fh(p, &args->fh);
326 if (!p) 327 if (!p)
327 return 0; 328 return 0;
328 p = decode_sattr3(p, &args->attrs); 329 p = decode_sattr3(p, &args->attrs, nfsd_user_namespace(rqstp));
329 330
330 if ((args->check_guard = ntohl(*p++)) != 0) { 331 if ((args->check_guard = ntohl(*p++)) != 0) {
331 struct timespec time; 332 struct timespec time;
@@ -455,7 +456,7 @@ nfs3svc_decode_createargs(struct svc_rqst *rqstp, __be32 *p)
455 switch (args->createmode = ntohl(*p++)) { 456 switch (args->createmode = ntohl(*p++)) {
456 case NFS3_CREATE_UNCHECKED: 457 case NFS3_CREATE_UNCHECKED:
457 case NFS3_CREATE_GUARDED: 458 case NFS3_CREATE_GUARDED:
458 p = decode_sattr3(p, &args->attrs); 459 p = decode_sattr3(p, &args->attrs, nfsd_user_namespace(rqstp));
459 break; 460 break;
460 case NFS3_CREATE_EXCLUSIVE: 461 case NFS3_CREATE_EXCLUSIVE:
461 args->verf = p; 462 args->verf = p;
@@ -476,7 +477,7 @@ nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, __be32 *p)
476 if (!(p = decode_fh(p, &args->fh)) || 477 if (!(p = decode_fh(p, &args->fh)) ||
477 !(p = decode_filename(p, &args->name, &args->len))) 478 !(p = decode_filename(p, &args->name, &args->len)))
478 return 0; 479 return 0;
479 p = decode_sattr3(p, &args->attrs); 480 p = decode_sattr3(p, &args->attrs, nfsd_user_namespace(rqstp));
480 481
481 return xdr_argsize_check(rqstp, p); 482 return xdr_argsize_check(rqstp, p);
482} 483}
@@ -491,7 +492,7 @@ nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p)
491 if (!(p = decode_fh(p, &args->ffh)) || 492 if (!(p = decode_fh(p, &args->ffh)) ||
492 !(p = decode_filename(p, &args->fname, &args->flen))) 493 !(p = decode_filename(p, &args->fname, &args->flen)))
493 return 0; 494 return 0;
494 p = decode_sattr3(p, &args->attrs); 495 p = decode_sattr3(p, &args->attrs, nfsd_user_namespace(rqstp));
495 496
496 args->tlen = ntohl(*p++); 497 args->tlen = ntohl(*p++);
497 498
@@ -519,7 +520,7 @@ nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, __be32 *p)
519 520
520 if (args->ftype == NF3BLK || args->ftype == NF3CHR 521 if (args->ftype == NF3BLK || args->ftype == NF3CHR
521 || args->ftype == NF3SOCK || args->ftype == NF3FIFO) 522 || args->ftype == NF3SOCK || args->ftype == NF3FIFO)
522 p = decode_sattr3(p, &args->attrs); 523 p = decode_sattr3(p, &args->attrs, nfsd_user_namespace(rqstp));
523 524
524 if (args->ftype == NF3BLK || args->ftype == NF3CHR) { 525 if (args->ftype == NF3BLK || args->ftype == NF3CHR) {
525 args->major = ntohl(*p++); 526 args->major = ntohl(*p++);
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c
index bf137fec33ff..2961016097ac 100644
--- a/fs/nfsd/nfs4idmap.c
+++ b/fs/nfsd/nfs4idmap.c
@@ -634,7 +634,7 @@ nfsd_map_name_to_uid(struct svc_rqst *rqstp, const char *name, size_t namelen,
634 return nfserr_inval; 634 return nfserr_inval;
635 635
636 status = do_name_to_id(rqstp, IDMAP_TYPE_USER, name, namelen, &id); 636 status = do_name_to_id(rqstp, IDMAP_TYPE_USER, name, namelen, &id);
637 *uid = make_kuid(&init_user_ns, id); 637 *uid = make_kuid(nfsd_user_namespace(rqstp), id);
638 if (!uid_valid(*uid)) 638 if (!uid_valid(*uid))
639 status = nfserr_badowner; 639 status = nfserr_badowner;
640 return status; 640 return status;
@@ -651,7 +651,7 @@ nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name, size_t namelen,
651 return nfserr_inval; 651 return nfserr_inval;
652 652
653 status = do_name_to_id(rqstp, IDMAP_TYPE_GROUP, name, namelen, &id); 653 status = do_name_to_id(rqstp, IDMAP_TYPE_GROUP, name, namelen, &id);
654 *gid = make_kgid(&init_user_ns, id); 654 *gid = make_kgid(nfsd_user_namespace(rqstp), id);
655 if (!gid_valid(*gid)) 655 if (!gid_valid(*gid))
656 status = nfserr_badowner; 656 status = nfserr_badowner;
657 return status; 657 return status;
@@ -660,13 +660,13 @@ nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name, size_t namelen,
660__be32 nfsd4_encode_user(struct xdr_stream *xdr, struct svc_rqst *rqstp, 660__be32 nfsd4_encode_user(struct xdr_stream *xdr, struct svc_rqst *rqstp,
661 kuid_t uid) 661 kuid_t uid)
662{ 662{
663 u32 id = from_kuid(&init_user_ns, uid); 663 u32 id = from_kuid_munged(nfsd_user_namespace(rqstp), uid);
664 return encode_name_from_id(xdr, rqstp, IDMAP_TYPE_USER, id); 664 return encode_name_from_id(xdr, rqstp, IDMAP_TYPE_USER, id);
665} 665}
666 666
667__be32 nfsd4_encode_group(struct xdr_stream *xdr, struct svc_rqst *rqstp, 667__be32 nfsd4_encode_group(struct xdr_stream *xdr, struct svc_rqst *rqstp,
668 kgid_t gid) 668 kgid_t gid)
669{ 669{
670 u32 id = from_kgid(&init_user_ns, gid); 670 u32 id = from_kgid_munged(nfsd_user_namespace(rqstp), gid);
671 return encode_name_from_id(xdr, rqstp, IDMAP_TYPE_GROUP, id); 671 return encode_name_from_id(xdr, rqstp, IDMAP_TYPE_GROUP, id);
672} 672}
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index a3a3455826aa..52c4f6daa649 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -521,6 +521,7 @@ nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access
521static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_cb_sec *cbs) 521static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_cb_sec *cbs)
522{ 522{
523 DECODE_HEAD; 523 DECODE_HEAD;
524 struct user_namespace *userns = nfsd_user_namespace(argp->rqstp);
524 u32 dummy, uid, gid; 525 u32 dummy, uid, gid;
525 char *machine_name; 526 char *machine_name;
526 int i; 527 int i;
@@ -563,8 +564,8 @@ static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_
563 dummy = be32_to_cpup(p++); 564 dummy = be32_to_cpup(p++);
564 READ_BUF(dummy * 4); 565 READ_BUF(dummy * 4);
565 if (cbs->flavor == (u32)(-1)) { 566 if (cbs->flavor == (u32)(-1)) {
566 kuid_t kuid = make_kuid(&init_user_ns, uid); 567 kuid_t kuid = make_kuid(userns, uid);
567 kgid_t kgid = make_kgid(&init_user_ns, gid); 568 kgid_t kgid = make_kgid(userns, gid);
568 if (uid_valid(kuid) && gid_valid(kgid)) { 569 if (uid_valid(kuid) && gid_valid(kgid)) {
569 cbs->uid = kuid; 570 cbs->uid = kuid;
570 cbs->gid = kgid; 571 cbs->gid = kgid;
diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
index d200c8680259..24187b5dd638 100644
--- a/fs/nfsd/nfsd.h
+++ b/fs/nfsd/nfsd.h
@@ -17,6 +17,7 @@
17#include <linux/nfs3.h> 17#include <linux/nfs3.h>
18#include <linux/nfs4.h> 18#include <linux/nfs4.h>
19#include <linux/sunrpc/svc.h> 19#include <linux/sunrpc/svc.h>
20#include <linux/sunrpc/svc_xprt.h>
20#include <linux/sunrpc/msg_prot.h> 21#include <linux/sunrpc/msg_prot.h>
21 22
22#include <uapi/linux/nfsd/debug.h> 23#include <uapi/linux/nfsd/debug.h>
@@ -112,6 +113,12 @@ static inline int nfsd_v4client(struct svc_rqst *rq)
112{ 113{
113 return rq->rq_prog == NFS_PROGRAM && rq->rq_vers == 4; 114 return rq->rq_prog == NFS_PROGRAM && rq->rq_vers == 4;
114} 115}
116static inline struct user_namespace *
117nfsd_user_namespace(const struct svc_rqst *rqstp)
118{
119 const struct cred *cred = rqstp->rq_xprt->xpt_cred;
120 return cred ? cred->user_ns : &init_user_ns;
121}
115 122
116/* 123/*
117 * NFSv4 State 124 * NFSv4 State
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 6b2e8b73d36e..b51fe515f06f 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -71,7 +71,7 @@ decode_filename(__be32 *p, char **namp, unsigned int *lenp)
71} 71}
72 72
73static __be32 * 73static __be32 *
74decode_sattr(__be32 *p, struct iattr *iap) 74decode_sattr(__be32 *p, struct iattr *iap, struct user_namespace *userns)
75{ 75{
76 u32 tmp, tmp1; 76 u32 tmp, tmp1;
77 77
@@ -86,12 +86,12 @@ decode_sattr(__be32 *p, struct iattr *iap)
86 iap->ia_mode = tmp; 86 iap->ia_mode = tmp;
87 } 87 }
88 if ((tmp = ntohl(*p++)) != (u32)-1) { 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 if (uid_valid(iap->ia_uid)) 90 if (uid_valid(iap->ia_uid))
91 iap->ia_valid |= ATTR_UID; 91 iap->ia_valid |= ATTR_UID;
92 } 92 }
93 if ((tmp = ntohl(*p++)) != (u32)-1) { 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 if (gid_valid(iap->ia_gid)) 95 if (gid_valid(iap->ia_gid))
96 iap->ia_valid |= ATTR_GID; 96 iap->ia_valid |= ATTR_GID;
97 } 97 }
@@ -129,6 +129,7 @@ static __be32 *
129encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, 129encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
130 struct kstat *stat) 130 struct kstat *stat)
131{ 131{
132 struct user_namespace *userns = nfsd_user_namespace(rqstp);
132 struct dentry *dentry = fhp->fh_dentry; 133 struct dentry *dentry = fhp->fh_dentry;
133 int type; 134 int type;
134 struct timespec64 time; 135 struct timespec64 time;
@@ -139,8 +140,8 @@ encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
139 *p++ = htonl(nfs_ftypes[type >> 12]); 140 *p++ = htonl(nfs_ftypes[type >> 12]);
140 *p++ = htonl((u32) stat->mode); 141 *p++ = htonl((u32) stat->mode);
141 *p++ = htonl((u32) stat->nlink); 142 *p++ = htonl((u32) stat->nlink);
142 *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid)); 143 *p++ = htonl((u32) from_kuid_munged(userns, stat->uid));
143 *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid)); 144 *p++ = htonl((u32) from_kgid_munged(userns, stat->gid));
144 145
145 if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) { 146 if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) {
146 *p++ = htonl(NFS_MAXPATHLEN); 147 *p++ = htonl(NFS_MAXPATHLEN);
@@ -216,7 +217,7 @@ nfssvc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p)
216 p = decode_fh(p, &args->fh); 217 p = decode_fh(p, &args->fh);
217 if (!p) 218 if (!p)
218 return 0; 219 return 0;
219 p = decode_sattr(p, &args->attrs); 220 p = decode_sattr(p, &args->attrs, nfsd_user_namespace(rqstp));
220 221
221 return xdr_argsize_check(rqstp, p); 222 return xdr_argsize_check(rqstp, p);
222} 223}
@@ -319,7 +320,7 @@ nfssvc_decode_createargs(struct svc_rqst *rqstp, __be32 *p)
319 if ( !(p = decode_fh(p, &args->fh)) 320 if ( !(p = decode_fh(p, &args->fh))
320 || !(p = decode_filename(p, &args->name, &args->len))) 321 || !(p = decode_filename(p, &args->name, &args->len)))
321 return 0; 322 return 0;
322 p = decode_sattr(p, &args->attrs); 323 p = decode_sattr(p, &args->attrs, nfsd_user_namespace(rqstp));
323 324
324 return xdr_argsize_check(rqstp, p); 325 return xdr_argsize_check(rqstp, p);
325} 326}
@@ -398,7 +399,7 @@ nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p)
398 return 0; 399 return 0;
399 p += xdrlen; 400 p += xdrlen;
400 } 401 }
401 decode_sattr(p, &args->attrs); 402 decode_sattr(p, &args->attrs, nfsd_user_namespace(rqstp));
402 403
403 return 1; 404 return 1;
404} 405}