hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
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)
....@@ -419,14 +424,23 @@
419424 return hash_long(from_kuid(&init_user_ns, uid), GID_HASHBITS);
420425 }
421426
422
-static void unix_gid_put(struct kref *kref)
427
+static void unix_gid_free(struct rcu_head *rcu)
423428 {
424
- struct cache_head *item = container_of(kref, struct cache_head, ref);
425
- struct unix_gid *ug = container_of(item, struct unix_gid, h);
429
+ struct unix_gid *ug = container_of(rcu, struct unix_gid, rcu);
430
+ struct cache_head *item = &ug->h;
431
+
426432 if (test_bit(CACHE_VALID, &item->flags) &&
427433 !test_bit(CACHE_NEGATIVE, &item->flags))
428434 put_group_info(ug->gi);
429435 kfree(ug);
436
+}
437
+
438
+static void unix_gid_put(struct kref *kref)
439
+{
440
+ struct cache_head *item = container_of(kref, struct cache_head, ref);
441
+ struct unix_gid *ug = container_of(item, struct unix_gid, h);
442
+
443
+ call_rcu(&ug->rcu, unix_gid_free);
430444 }
431445
432446 static int unix_gid_match(struct cache_head *corig, struct cache_head *cnew)
....@@ -458,6 +472,11 @@
458472 return NULL;
459473 }
460474
475
+static int unix_gid_upcall(struct cache_detail *cd, struct cache_head *h)
476
+{
477
+ return sunrpc_cache_pipe_upcall_timeout(cd, h);
478
+}
479
+
461480 static void unix_gid_request(struct cache_detail *cd,
462481 struct cache_head *h,
463482 char **bpp, int *blen)
....@@ -482,7 +501,7 @@
482501 int rv;
483502 int i;
484503 int err;
485
- time_t expiry;
504
+ time64_t expiry;
486505 struct unix_gid ug, *ugp;
487506
488507 if (mesg[mlen - 1] != '\n')
....@@ -492,7 +511,7 @@
492511 rv = get_int(&mesg, &id);
493512 if (rv)
494513 return -EINVAL;
495
- uid = make_kuid(&init_user_ns, id);
514
+ uid = make_kuid(current_user_ns(), id);
496515 ug.uid = uid;
497516
498517 expiry = get_expiry(&mesg);
....@@ -514,7 +533,7 @@
514533 err = -EINVAL;
515534 if (rv)
516535 goto out;
517
- kgid = make_kgid(&init_user_ns, gid);
536
+ kgid = make_kgid(current_user_ns(), gid);
518537 if (!gid_valid(kgid))
519538 goto out;
520539 ug.gi->gid[i] = kgid;
....@@ -547,7 +566,7 @@
547566 struct cache_detail *cd,
548567 struct cache_head *h)
549568 {
550
- struct user_namespace *user_ns = &init_user_ns;
569
+ struct user_namespace *user_ns = m->file->f_cred->user_ns;
551570 struct unix_gid *ug;
552571 int i;
553572 int glen;
....@@ -575,6 +594,7 @@
575594 .hash_size = GID_HASHMAX,
576595 .name = "auth.unix.gid",
577596 .cache_put = unix_gid_put,
597
+ .cache_upcall = unix_gid_upcall,
578598 .cache_request = unix_gid_request,
579599 .cache_parse = unix_gid_parse,
580600 .cache_show = unix_gid_show,
....@@ -619,7 +639,7 @@
619639 struct cache_head *ch;
620640
621641 ug.uid = uid;
622
- ch = sunrpc_cache_lookup(cd, &ug.h, unix_gid_hash(uid));
642
+ ch = sunrpc_cache_lookup_rcu(cd, &ug.h, unix_gid_hash(uid));
623643 if (ch)
624644 return container_of(ch, struct unix_gid, h);
625645 else
....@@ -788,6 +808,7 @@
788808 struct kvec *argv = &rqstp->rq_arg.head[0];
789809 struct kvec *resv = &rqstp->rq_res.head[0];
790810 struct svc_cred *cred = &rqstp->rq_cred;
811
+ struct user_namespace *userns;
791812 u32 slen, i;
792813 int len = argv->iov_len;
793814
....@@ -808,8 +829,10 @@
808829 * (export-specific) anonymous id by nfsd_setuser.
809830 * Supplementary gid's will be left alone.
810831 */
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 */
832
+ userns = (rqstp->rq_xprt && rqstp->rq_xprt->xpt_cred) ?
833
+ rqstp->rq_xprt->xpt_cred->user_ns : &init_user_ns;
834
+ cred->cr_uid = make_kuid(userns, svc_getnl(argv)); /* uid */
835
+ cred->cr_gid = make_kgid(userns, svc_getnl(argv)); /* gid */
813836 slen = svc_getnl(argv); /* gids length */
814837 if (slen > UNX_NGROUPS || (len -= (slen + 2)*4) < 0)
815838 goto badcred;
....@@ -817,7 +840,7 @@
817840 if (cred->cr_group_info == NULL)
818841 return SVC_CLOSE;
819842 for (i = 0; i < slen; i++) {
820
- kgid_t kgid = make_kgid(&init_user_ns, svc_getnl(argv));
843
+ kgid_t kgid = make_kgid(userns, svc_getnl(argv));
821844 cred->cr_group_info->gid[i] = kgid;
822845 }
823846 groups_sort(cred->cr_group_info);
....@@ -869,6 +892,7 @@
869892 .hash_size = IP_HASHMAX,
870893 .name = "auth.unix.ip",
871894 .cache_put = ip_map_put,
895
+ .cache_upcall = ip_map_upcall,
872896 .cache_request = ip_map_request,
873897 .cache_parse = ip_map_parse,
874898 .cache_show = ip_map_show,