hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/net/sunrpc/svcauth_unix.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 #include <linux/types.h>
23 #include <linux/sched.h>
34 #include <linux/module.h>
....@@ -37,12 +38,18 @@
3738 extern struct auth_ops svcauth_null;
3839 extern struct auth_ops svcauth_unix;
3940
40
-static void svcauth_unix_domain_release(struct auth_domain *dom)
41
+static void svcauth_unix_domain_release_rcu(struct rcu_head *head)
4142 {
43
+ struct auth_domain *dom = container_of(head, struct auth_domain, rcu_head);
4244 struct unix_domain *ud = container_of(dom, struct unix_domain, h);
4345
4446 kfree(dom->name);
4547 kfree(ud);
48
+}
49
+
50
+static void svcauth_unix_domain_release(struct auth_domain *dom)
51
+{
52
+ call_rcu(&dom->rcu_head, svcauth_unix_domain_release_rcu);
4653 }
4754
4855 struct auth_domain *unix_domain_find(char *name)
....@@ -50,7 +57,7 @@
5057 struct auth_domain *rv;
5158 struct unix_domain *new = NULL;
5259
53
- rv = auth_domain_lookup(name, NULL);
60
+ rv = auth_domain_find(name);
5461 while(1) {
5562 if (rv) {
5663 if (new && rv != &new->h)
....@@ -91,6 +98,7 @@
9198 char m_class[8]; /* e.g. "nfsd" */
9299 struct in6_addr m_addr;
93100 struct unix_domain *m_client;
101
+ struct rcu_head m_rcu;
94102 };
95103
96104 static void ip_map_put(struct kref *kref)
....@@ -101,7 +109,7 @@
101109 if (test_bit(CACHE_VALID, &item->flags) &&
102110 !test_bit(CACHE_NEGATIVE, &item->flags))
103111 auth_domain_put(&im->m_client->h);
104
- kfree(im);
112
+ kfree_rcu(im, m_rcu);
105113 }
106114
107115 static inline int hash_ip6(const struct in6_addr *ip)
....@@ -140,6 +148,11 @@
140148 return NULL;
141149 }
142150
151
+static int ip_map_upcall(struct cache_detail *cd, struct cache_head *h)
152
+{
153
+ return sunrpc_cache_pipe_upcall(cd, h);
154
+}
155
+
143156 static void ip_map_request(struct cache_detail *cd,
144157 struct cache_head *h,
145158 char **bpp, int *blen)
....@@ -158,7 +171,7 @@
158171 }
159172
160173 static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class, struct in6_addr *addr);
161
-static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm, struct unix_domain *udom, time_t expiry);
174
+static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm, struct unix_domain *udom, time64_t expiry);
162175
163176 static int ip_map_parse(struct cache_detail *cd,
164177 char *mesg, int mlen)
....@@ -179,7 +192,7 @@
179192
180193 struct ip_map *ipmp;
181194 struct auth_domain *dom;
182
- time_t expiry;
195
+ time64_t expiry;
183196
184197 if (mesg[mlen-1] != '\n')
185198 return -EINVAL;
....@@ -280,9 +293,9 @@
280293
281294 strcpy(ip.m_class, class);
282295 ip.m_addr = *addr;
283
- ch = sunrpc_cache_lookup(cd, &ip.h,
284
- hash_str(class, IP_HASHBITS) ^
285
- hash_ip6(addr));
296
+ ch = sunrpc_cache_lookup_rcu(cd, &ip.h,
297
+ hash_str(class, IP_HASHBITS) ^
298
+ hash_ip6(addr));
286299
287300 if (ch)
288301 return container_of(ch, struct ip_map, h);
....@@ -300,7 +313,7 @@
300313 }
301314
302315 static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm,
303
- struct unix_domain *udom, time_t expiry)
316
+ struct unix_domain *udom, time64_t expiry)
304317 {
305318 struct ip_map ip;
306319 struct cache_head *ch;
....@@ -317,15 +330,6 @@
317330 return -ENOMEM;
318331 cache_put(ch, cd);
319332 return 0;
320
-}
321
-
322
-static inline int ip_map_update(struct net *net, struct ip_map *ipm,
323
- struct unix_domain *udom, time_t expiry)
324
-{
325
- struct sunrpc_net *sn;
326
-
327
- sn = net_generic(net, sunrpc_net_id);
328
- return __ip_map_update(sn->ip_map_cache, ipm, udom, expiry);
329333 }
330334
331335 void svcauth_unix_purge(struct net *net)
....@@ -412,6 +416,7 @@
412416 struct cache_head h;
413417 kuid_t uid;
414418 struct group_info *gi;
419
+ struct rcu_head rcu;
415420 };
416421
417422 static int unix_gid_hash(kuid_t uid)
....@@ -426,7 +431,7 @@
426431 if (test_bit(CACHE_VALID, &item->flags) &&
427432 !test_bit(CACHE_NEGATIVE, &item->flags))
428433 put_group_info(ug->gi);
429
- kfree(ug);
434
+ kfree_rcu(ug, rcu);
430435 }
431436
432437 static int unix_gid_match(struct cache_head *corig, struct cache_head *cnew)
....@@ -458,6 +463,11 @@
458463 return NULL;
459464 }
460465
466
+static int unix_gid_upcall(struct cache_detail *cd, struct cache_head *h)
467
+{
468
+ return sunrpc_cache_pipe_upcall_timeout(cd, h);
469
+}
470
+
461471 static void unix_gid_request(struct cache_detail *cd,
462472 struct cache_head *h,
463473 char **bpp, int *blen)
....@@ -482,7 +492,7 @@
482492 int rv;
483493 int i;
484494 int err;
485
- time_t expiry;
495
+ time64_t expiry;
486496 struct unix_gid ug, *ugp;
487497
488498 if (mesg[mlen - 1] != '\n')
....@@ -492,7 +502,7 @@
492502 rv = get_int(&mesg, &id);
493503 if (rv)
494504 return -EINVAL;
495
- uid = make_kuid(&init_user_ns, id);
505
+ uid = make_kuid(current_user_ns(), id);
496506 ug.uid = uid;
497507
498508 expiry = get_expiry(&mesg);
....@@ -514,7 +524,7 @@
514524 err = -EINVAL;
515525 if (rv)
516526 goto out;
517
- kgid = make_kgid(&init_user_ns, gid);
527
+ kgid = make_kgid(current_user_ns(), gid);
518528 if (!gid_valid(kgid))
519529 goto out;
520530 ug.gi->gid[i] = kgid;
....@@ -547,7 +557,7 @@
547557 struct cache_detail *cd,
548558 struct cache_head *h)
549559 {
550
- struct user_namespace *user_ns = &init_user_ns;
560
+ struct user_namespace *user_ns = m->file->f_cred->user_ns;
551561 struct unix_gid *ug;
552562 int i;
553563 int glen;
....@@ -575,6 +585,7 @@
575585 .hash_size = GID_HASHMAX,
576586 .name = "auth.unix.gid",
577587 .cache_put = unix_gid_put,
588
+ .cache_upcall = unix_gid_upcall,
578589 .cache_request = unix_gid_request,
579590 .cache_parse = unix_gid_parse,
580591 .cache_show = unix_gid_show,
....@@ -619,7 +630,7 @@
619630 struct cache_head *ch;
620631
621632 ug.uid = uid;
622
- ch = sunrpc_cache_lookup(cd, &ug.h, unix_gid_hash(uid));
633
+ ch = sunrpc_cache_lookup_rcu(cd, &ug.h, unix_gid_hash(uid));
623634 if (ch)
624635 return container_of(ch, struct unix_gid, h);
625636 else
....@@ -788,6 +799,7 @@
788799 struct kvec *argv = &rqstp->rq_arg.head[0];
789800 struct kvec *resv = &rqstp->rq_res.head[0];
790801 struct svc_cred *cred = &rqstp->rq_cred;
802
+ struct user_namespace *userns;
791803 u32 slen, i;
792804 int len = argv->iov_len;
793805
....@@ -808,8 +820,10 @@
808820 * (export-specific) anonymous id by nfsd_setuser.
809821 * Supplementary gid's will be left alone.
810822 */
811
- cred->cr_uid = make_kuid(&init_user_ns, svc_getnl(argv)); /* uid */
812
- cred->cr_gid = make_kgid(&init_user_ns, svc_getnl(argv)); /* gid */
823
+ userns = (rqstp->rq_xprt && rqstp->rq_xprt->xpt_cred) ?
824
+ rqstp->rq_xprt->xpt_cred->user_ns : &init_user_ns;
825
+ cred->cr_uid = make_kuid(userns, svc_getnl(argv)); /* uid */
826
+ cred->cr_gid = make_kgid(userns, svc_getnl(argv)); /* gid */
813827 slen = svc_getnl(argv); /* gids length */
814828 if (slen > UNX_NGROUPS || (len -= (slen + 2)*4) < 0)
815829 goto badcred;
....@@ -817,7 +831,7 @@
817831 if (cred->cr_group_info == NULL)
818832 return SVC_CLOSE;
819833 for (i = 0; i < slen; i++) {
820
- kgid_t kgid = make_kgid(&init_user_ns, svc_getnl(argv));
834
+ kgid_t kgid = make_kgid(userns, svc_getnl(argv));
821835 cred->cr_group_info->gid[i] = kgid;
822836 }
823837 groups_sort(cred->cr_group_info);
....@@ -869,6 +883,7 @@
869883 .hash_size = IP_HASHMAX,
870884 .name = "auth.unix.ip",
871885 .cache_put = ip_map_put,
886
+ .cache_upcall = ip_map_upcall,
872887 .cache_request = ip_map_request,
873888 .cache_parse = ip_map_parse,
874889 .cache_show = ip_map_show,