hc
2024-01-04 1543e317f1da31b75942316931e8f491a8920811
kernel/fs/nfs/nfs4idmap.c
....@@ -46,6 +46,7 @@
4646 #include <keys/user-type.h>
4747 #include <keys/request_key_auth-type.h>
4848 #include <linux/module.h>
49
+#include <linux/user_namespace.h>
4950
5051 #include "internal.h"
5152 #include "netns.h"
....@@ -69,7 +70,15 @@
6970 struct rpc_pipe *idmap_pipe;
7071 struct idmap_legacy_upcalldata *idmap_upcall_data;
7172 struct mutex idmap_mutex;
73
+ struct user_namespace *user_ns;
7274 };
75
+
76
+static struct user_namespace *idmap_userns(const struct idmap *idmap)
77
+{
78
+ if (idmap && idmap->user_ns)
79
+ return idmap->user_ns;
80
+ return &init_user_ns;
81
+}
7382
7483 /**
7584 * nfs_fattr_init_names - initialise the nfs_fattr owner_name/group_name fields
....@@ -271,18 +280,19 @@
271280 const char *type, struct idmap *idmap)
272281 {
273282 char *desc;
274
- struct key *rkey;
283
+ struct key *rkey = ERR_PTR(-EAGAIN);
275284 ssize_t ret;
276285
277286 ret = nfs_idmap_get_desc(name, namelen, type, strlen(type), &desc);
278287 if (ret < 0)
279288 return ERR_PTR(ret);
280289
281
- rkey = request_key(&key_type_id_resolver, desc, "");
290
+ if (!idmap->user_ns || idmap->user_ns == &init_user_ns)
291
+ rkey = request_key(&key_type_id_resolver, desc, "");
282292 if (IS_ERR(rkey)) {
283293 mutex_lock(&idmap->idmap_mutex);
284294 rkey = request_key_with_auxdata(&key_type_id_resolver_legacy,
285
- desc, "", 0, idmap);
295
+ desc, NULL, "", 0, idmap);
286296 mutex_unlock(&idmap->idmap_mutex);
287297 }
288298 if (!IS_ERR(rkey))
....@@ -452,6 +462,9 @@
452462 if (idmap == NULL)
453463 return -ENOMEM;
454464
465
+ mutex_init(&idmap->idmap_mutex);
466
+ idmap->user_ns = get_user_ns(clp->cl_rpcclient->cl_cred->user_ns);
467
+
455468 rpc_init_pipe_dir_object(&idmap->idmap_pdo,
456469 &nfs_idmap_pipe_dir_object_ops,
457470 idmap);
....@@ -462,7 +475,6 @@
462475 goto err;
463476 }
464477 idmap->idmap_pipe = pipe;
465
- mutex_init(&idmap->idmap_mutex);
466478
467479 error = rpc_add_pipe_dir_object(clp->cl_net,
468480 &clp->cl_rpcclient->cl_pipedir_objects,
....@@ -475,6 +487,7 @@
475487 err_destroy_pipe:
476488 rpc_destroy_pipe_data(idmap->idmap_pipe);
477489 err:
490
+ put_user_ns(idmap->user_ns);
478491 kfree(idmap);
479492 return error;
480493 }
....@@ -491,6 +504,7 @@
491504 &clp->cl_rpcclient->cl_pipedir_objects,
492505 &idmap->idmap_pdo);
493506 rpc_destroy_pipe_data(idmap->idmap_pipe);
507
+ put_user_ns(idmap->user_ns);
494508 kfree(idmap);
495509 }
496510
....@@ -507,7 +521,7 @@
507521 switch (token) {
508522 case Opt_find_uid:
509523 im->im_type = IDMAP_TYPE_USER;
510
- /* Fall through */
524
+ fallthrough;
511525 case Opt_find_gid:
512526 im->im_conv = IDMAP_CONV_NAMETOID;
513527 ret = match_strlcpy(im->im_name, &substr, IDMAP_NAMESZ);
....@@ -515,7 +529,7 @@
515529
516530 case Opt_find_user:
517531 im->im_type = IDMAP_TYPE_USER;
518
- /* Fall through */
532
+ fallthrough;
519533 case Opt_find_group:
520534 im->im_conv = IDMAP_CONV_IDTONAME;
521535 ret = match_int(&substr, &im->im_id);
....@@ -547,22 +561,20 @@
547561 return true;
548562 }
549563
550
-static void
551
-nfs_idmap_complete_pipe_upcall_locked(struct idmap *idmap, int ret)
564
+static void nfs_idmap_complete_pipe_upcall(struct idmap_legacy_upcalldata *data,
565
+ int ret)
552566 {
553
- struct key *authkey = idmap->idmap_upcall_data->authkey;
554
-
555
- kfree(idmap->idmap_upcall_data);
556
- idmap->idmap_upcall_data = NULL;
557
- complete_request_key(authkey, ret);
558
- key_put(authkey);
567
+ complete_request_key(data->authkey, ret);
568
+ key_put(data->authkey);
569
+ kfree(data);
559570 }
560571
561
-static void
562
-nfs_idmap_abort_pipe_upcall(struct idmap *idmap, int ret)
572
+static void nfs_idmap_abort_pipe_upcall(struct idmap *idmap,
573
+ struct idmap_legacy_upcalldata *data,
574
+ int ret)
563575 {
564
- if (idmap->idmap_upcall_data != NULL)
565
- nfs_idmap_complete_pipe_upcall_locked(idmap, ret);
576
+ if (cmpxchg(&idmap->idmap_upcall_data, data, NULL) == data)
577
+ nfs_idmap_complete_pipe_upcall(data, ret);
566578 }
567579
568580 static int nfs_idmap_legacy_upcall(struct key *authkey, void *aux)
....@@ -599,7 +611,7 @@
599611
600612 ret = rpc_queue_upcall(idmap->idmap_pipe, msg);
601613 if (ret < 0)
602
- nfs_idmap_abort_pipe_upcall(idmap, ret);
614
+ nfs_idmap_abort_pipe_upcall(idmap, data, ret);
603615
604616 return ret;
605617 out2:
....@@ -655,6 +667,7 @@
655667 struct request_key_auth *rka;
656668 struct rpc_inode *rpci = RPC_I(file_inode(filp));
657669 struct idmap *idmap = (struct idmap *)rpci->private;
670
+ struct idmap_legacy_upcalldata *data;
658671 struct key *authkey;
659672 struct idmap_msg im;
660673 size_t namelen_in;
....@@ -664,10 +677,11 @@
664677 * will have been woken up and someone else may now have used
665678 * idmap_key_cons - so after this point we may no longer touch it.
666679 */
667
- if (idmap->idmap_upcall_data == NULL)
680
+ data = xchg(&idmap->idmap_upcall_data, NULL);
681
+ if (data == NULL)
668682 goto out_noupcall;
669683
670
- authkey = idmap->idmap_upcall_data->authkey;
684
+ authkey = data->authkey;
671685 rka = get_request_key_auth(authkey);
672686
673687 if (mlen != sizeof(im)) {
....@@ -689,18 +703,17 @@
689703 if (namelen_in == 0 || namelen_in == IDMAP_NAMESZ) {
690704 ret = -EINVAL;
691705 goto out;
692
-}
706
+ }
693707
694
- ret = nfs_idmap_read_and_verify_message(&im,
695
- &idmap->idmap_upcall_data->idmap_msg,
696
- rka->target_key, authkey);
708
+ ret = nfs_idmap_read_and_verify_message(&im, &data->idmap_msg,
709
+ rka->target_key, authkey);
697710 if (ret >= 0) {
698711 key_set_timeout(rka->target_key, nfs_idmap_cache_timeout);
699712 ret = mlen;
700713 }
701714
702715 out:
703
- nfs_idmap_complete_pipe_upcall_locked(idmap, ret);
716
+ nfs_idmap_complete_pipe_upcall(data, ret);
704717 out_noupcall:
705718 return ret;
706719 }
....@@ -714,7 +727,7 @@
714727 struct idmap *idmap = data->idmap;
715728
716729 if (msg->errno)
717
- nfs_idmap_abort_pipe_upcall(idmap, msg->errno);
730
+ nfs_idmap_abort_pipe_upcall(idmap, data, msg->errno);
718731 }
719732
720733 static void
....@@ -722,8 +735,11 @@
722735 {
723736 struct rpc_inode *rpci = RPC_I(inode);
724737 struct idmap *idmap = (struct idmap *)rpci->private;
738
+ struct idmap_legacy_upcalldata *data;
725739
726
- nfs_idmap_abort_pipe_upcall(idmap, -EPIPE);
740
+ data = xchg(&idmap->idmap_upcall_data, NULL);
741
+ if (data)
742
+ nfs_idmap_complete_pipe_upcall(data, -EPIPE);
727743 }
728744
729745 int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_t namelen, kuid_t *uid)
....@@ -735,7 +751,7 @@
735751 if (!nfs_map_string_to_numeric(name, namelen, &id))
736752 ret = nfs_idmap_lookup_id(name, namelen, "uid", &id, idmap);
737753 if (ret == 0) {
738
- *uid = make_kuid(&init_user_ns, id);
754
+ *uid = make_kuid(idmap_userns(idmap), id);
739755 if (!uid_valid(*uid))
740756 ret = -ERANGE;
741757 }
....@@ -752,7 +768,7 @@
752768 if (!nfs_map_string_to_numeric(name, namelen, &id))
753769 ret = nfs_idmap_lookup_id(name, namelen, "gid", &id, idmap);
754770 if (ret == 0) {
755
- *gid = make_kgid(&init_user_ns, id);
771
+ *gid = make_kgid(idmap_userns(idmap), id);
756772 if (!gid_valid(*gid))
757773 ret = -ERANGE;
758774 }
....@@ -766,7 +782,7 @@
766782 int ret = -EINVAL;
767783 __u32 id;
768784
769
- id = from_kuid(&init_user_ns, uid);
785
+ id = from_kuid_munged(idmap_userns(idmap), uid);
770786 if (!(server->caps & NFS_CAP_UIDGID_NOMAP))
771787 ret = nfs_idmap_lookup_name(id, "user", buf, buflen, idmap);
772788 if (ret < 0)
....@@ -780,7 +796,7 @@
780796 int ret = -EINVAL;
781797 __u32 id;
782798
783
- id = from_kgid(&init_user_ns, gid);
799
+ id = from_kgid_munged(idmap_userns(idmap), gid);
784800 if (!(server->caps & NFS_CAP_UIDGID_NOMAP))
785801 ret = nfs_idmap_lookup_name(id, "group", buf, buflen, idmap);
786802 if (ret < 0)