Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

nfsd: knfsd must use the container user namespace

Convert knfsd to use the user namespace of the container that started
the server processes.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>

authored by

Trond Myklebust and committed by
J. Bruce Fields
e45d1a18 e6667c73

+44 -32
+10 -8
fs/nfsd/export.c
··· 570 570 err = get_int(&mesg, &an_int); 571 571 if (err) 572 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 575 /* anon gid */ 576 576 err = get_int(&mesg, &an_int); 577 577 if (err) 578 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 581 /* fsid */ 582 582 err = get_int(&mesg, &an_int); ··· 1170 1170 static void exp_flags(struct seq_file *m, int flag, int fsid, 1171 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 1175 show_expflags(m, flag, NFSEXP_ALLFLAGS); 1174 1176 if (flag & NFSEXP_FSID) 1175 1177 seq_printf(m, ",fsid=%d", fsid); 1176 - if (!uid_eq(anonu, make_kuid(&init_user_ns, (uid_t)-2)) && 1177 - !uid_eq(anonu, make_kuid(&init_user_ns, 0x10000-2))) 1178 - seq_printf(m, ",anonuid=%u", from_kuid(&init_user_ns, anonu)); 1179 - if (!gid_eq(anong, make_kgid(&init_user_ns, (gid_t)-2)) && 1180 - !gid_eq(anong, make_kgid(&init_user_ns, 0x10000-2))) 1181 - seq_printf(m, ",anongid=%u", from_kgid(&init_user_ns, anong)); 1178 + if (!uid_eq(anonu, make_kuid(userns, (uid_t)-2)) && 1179 + !uid_eq(anonu, make_kuid(userns, 0x10000-2))) 1180 + seq_printf(m, ",anonuid=%u", from_kuid_munged(userns, anonu)); 1181 + if (!gid_eq(anong, make_kgid(userns, (gid_t)-2)) && 1182 + !gid_eq(anong, make_kgid(userns, 0x10000-2))) 1183 + seq_printf(m, ",anongid=%u", from_kgid_munged(userns, anong)); 1182 1184 if (fsloc && fsloc->locations_count > 0) { 1183 1185 char *loctype = (fsloc->migrated) ? "refer" : "replicas"; 1184 1186 int i;
+11 -10
fs/nfsd/nfs3xdr.c
··· 96 96 } 97 97 98 98 static __be32 * 99 - decode_sattr3(__be32 *p, struct iattr *iap) 99 + decode_sattr3(__be32 *p, struct iattr *iap, struct user_namespace *userns) 100 100 { 101 101 u32 tmp; 102 102 ··· 107 107 iap->ia_mode = ntohl(*p++); 108 108 } 109 109 if (*p++) { 110 - iap->ia_uid = make_kuid(&init_user_ns, ntohl(*p++)); 110 + iap->ia_uid = make_kuid(userns, ntohl(*p++)); 111 111 if (uid_valid(iap->ia_uid)) 112 112 iap->ia_valid |= ATTR_UID; 113 113 } 114 114 if (*p++) { 115 - iap->ia_gid = make_kgid(&init_user_ns, ntohl(*p++)); 115 + iap->ia_gid = make_kgid(userns, ntohl(*p++)); 116 116 if (gid_valid(iap->ia_gid)) 117 117 iap->ia_valid |= ATTR_GID; 118 118 } ··· 165 165 encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, 166 166 struct kstat *stat) 167 167 { 168 + struct user_namespace *userns = nfsd_user_namespace(rqstp); 168 169 struct timespec ts; 169 170 *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]); 170 171 *p++ = htonl((u32) (stat->mode & S_IALLUGO)); 171 172 *p++ = htonl((u32) stat->nlink); 172 - *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid)); 173 - *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid)); 173 + *p++ = htonl((u32) from_kuid_munged(userns, stat->uid)); 174 + *p++ = htonl((u32) from_kgid_munged(userns, stat->gid)); 174 175 if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) { 175 176 p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN); 176 177 } else { ··· 326 325 p = decode_fh(p, &args->fh); 327 326 if (!p) 328 327 return 0; 329 - p = decode_sattr3(p, &args->attrs); 328 + p = decode_sattr3(p, &args->attrs, nfsd_user_namespace(rqstp)); 330 329 331 330 if ((args->check_guard = ntohl(*p++)) != 0) { 332 331 struct timespec time; ··· 456 455 switch (args->createmode = ntohl(*p++)) { 457 456 case NFS3_CREATE_UNCHECKED: 458 457 case NFS3_CREATE_GUARDED: 459 - p = decode_sattr3(p, &args->attrs); 458 + p = decode_sattr3(p, &args->attrs, nfsd_user_namespace(rqstp)); 460 459 break; 461 460 case NFS3_CREATE_EXCLUSIVE: 462 461 args->verf = p; ··· 477 476 if (!(p = decode_fh(p, &args->fh)) || 478 477 !(p = decode_filename(p, &args->name, &args->len))) 479 478 return 0; 480 - p = decode_sattr3(p, &args->attrs); 479 + p = decode_sattr3(p, &args->attrs, nfsd_user_namespace(rqstp)); 481 480 482 481 return xdr_argsize_check(rqstp, p); 483 482 } ··· 492 491 if (!(p = decode_fh(p, &args->ffh)) || 493 492 !(p = decode_filename(p, &args->fname, &args->flen))) 494 493 return 0; 495 - p = decode_sattr3(p, &args->attrs); 494 + p = decode_sattr3(p, &args->attrs, nfsd_user_namespace(rqstp)); 496 495 497 496 args->tlen = ntohl(*p++); 498 497 ··· 520 519 521 520 if (args->ftype == NF3BLK || args->ftype == NF3CHR 522 521 || args->ftype == NF3SOCK || args->ftype == NF3FIFO) 523 - p = decode_sattr3(p, &args->attrs); 522 + p = decode_sattr3(p, &args->attrs, nfsd_user_namespace(rqstp)); 524 523 525 524 if (args->ftype == NF3BLK || args->ftype == NF3CHR) { 526 525 args->major = ntohl(*p++);
+4 -4
fs/nfsd/nfs4idmap.c
··· 634 634 return nfserr_inval; 635 635 636 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 638 if (!uid_valid(*uid)) 639 639 status = nfserr_badowner; 640 640 return status; ··· 651 651 return nfserr_inval; 652 652 653 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 655 if (!gid_valid(*gid)) 656 656 status = nfserr_badowner; 657 657 return status; ··· 660 660 __be32 nfsd4_encode_user(struct xdr_stream *xdr, struct svc_rqst *rqstp, 661 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 664 return encode_name_from_id(xdr, rqstp, IDMAP_TYPE_USER, id); 665 665 } 666 666 667 667 __be32 nfsd4_encode_group(struct xdr_stream *xdr, struct svc_rqst *rqstp, 668 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 671 return encode_name_from_id(xdr, rqstp, IDMAP_TYPE_GROUP, id); 672 672 }
+3 -2
fs/nfsd/nfs4xdr.c
··· 521 521 static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_cb_sec *cbs) 522 522 { 523 523 DECODE_HEAD; 524 + struct user_namespace *userns = nfsd_user_namespace(argp->rqstp); 524 525 u32 dummy, uid, gid; 525 526 char *machine_name; 526 527 int i; ··· 564 563 dummy = be32_to_cpup(p++); 565 564 READ_BUF(dummy * 4); 566 565 if (cbs->flavor == (u32)(-1)) { 567 - kuid_t kuid = make_kuid(&init_user_ns, uid); 568 - kgid_t kgid = make_kgid(&init_user_ns, gid); 566 + kuid_t kuid = make_kuid(userns, uid); 567 + kgid_t kgid = make_kgid(userns, gid); 569 568 if (uid_valid(kuid) && gid_valid(kgid)) { 570 569 cbs->uid = kuid; 571 570 cbs->gid = kgid;
+7
fs/nfsd/nfsd.h
··· 17 17 #include <linux/nfs3.h> 18 18 #include <linux/nfs4.h> 19 19 #include <linux/sunrpc/svc.h> 20 + #include <linux/sunrpc/svc_xprt.h> 20 21 #include <linux/sunrpc/msg_prot.h> 21 22 22 23 #include <uapi/linux/nfsd/debug.h> ··· 112 111 static inline int nfsd_v4client(struct svc_rqst *rq) 113 112 { 114 113 return rq->rq_prog == NFS_PROGRAM && rq->rq_vers == 4; 114 + } 115 + static inline struct user_namespace * 116 + nfsd_user_namespace(const struct svc_rqst *rqstp) 117 + { 118 + const struct cred *cred = rqstp->rq_xprt->xpt_cred; 119 + return cred ? cred->user_ns : &init_user_ns; 115 120 } 116 121 117 122 /*
+9 -8
fs/nfsd/nfsxdr.c
··· 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; ··· 140 139 *p++ = htonl(nfs_ftypes[type >> 12]); 141 140 *p++ = htonl((u32) stat->mode); 142 141 *p++ = htonl((u32) stat->nlink); 143 - *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid)); 144 - *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid)); 142 + *p++ = htonl((u32) from_kuid_munged(userns, stat->uid)); 143 + *p++ = htonl((u32) from_kgid_munged(userns, stat->gid)); 145 144 146 145 if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) { 147 146 *p++ = htonl(NFS_MAXPATHLEN); ··· 217 216 p = decode_fh(p, &args->fh); 218 217 if (!p) 219 218 return 0; 220 - p = decode_sattr(p, &args->attrs); 219 + p = decode_sattr(p, &args->attrs, nfsd_user_namespace(rqstp)); 221 220 222 221 return xdr_argsize_check(rqstp, p); 223 222 } ··· 320 319 if ( !(p = decode_fh(p, &args->fh)) 321 320 || !(p = decode_filename(p, &args->name, &args->len))) 322 321 return 0; 323 - p = decode_sattr(p, &args->attrs); 322 + p = decode_sattr(p, &args->attrs, nfsd_user_namespace(rqstp)); 324 323 325 324 return xdr_argsize_check(rqstp, p); 326 325 } ··· 399 398 return 0; 400 399 p += xdrlen; 401 400 } 402 - decode_sattr(p, &args->attrs); 401 + decode_sattr(p, &args->attrs, nfsd_user_namespace(rqstp)); 403 402 404 403 return 1; 405 404 }