hc
2024-05-16 8d2a02b24d66aa359e83eebc1ed3c0f85367a1cb
kernel/net/sunrpc/auth_gss/svcauth_gss.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /*
23 * Neil Brown <neilb@cse.unsw.edu.au>
34 * J. Bruce Fields <bfields@umich.edu>
....@@ -48,12 +49,11 @@
4849 #include <linux/sunrpc/svcauth.h>
4950 #include <linux/sunrpc/svcauth_gss.h>
5051 #include <linux/sunrpc/cache.h>
52
+
53
+#include <trace/events/rpcgss.h>
54
+
5155 #include "gss_rpc_upcall.h"
5256
53
-
54
-#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
55
-# define RPCDBG_FACILITY RPCDBG_AUTH
56
-#endif
5757
5858 /* The rpcsec_init cache is used for mapping RPCSEC_GSS_{,CONT_}INIT requests
5959 * into replies.
....@@ -76,6 +76,7 @@
7676 struct xdr_netobj in_handle, in_token;
7777 struct xdr_netobj out_handle, out_token;
7878 int major_status, minor_status;
79
+ struct rcu_head rcu_head;
7980 };
8081
8182 static struct rsi *rsi_update(struct cache_detail *cd, struct rsi *new, struct rsi *old);
....@@ -89,11 +90,19 @@
8990 kfree(rsii->out_token.data);
9091 }
9192
93
+static void rsi_free_rcu(struct rcu_head *head)
94
+{
95
+ struct rsi *rsii = container_of(head, struct rsi, rcu_head);
96
+
97
+ rsi_free(rsii);
98
+ kfree(rsii);
99
+}
100
+
92101 static void rsi_put(struct kref *ref)
93102 {
94103 struct rsi *rsii = container_of(ref, struct rsi, h.ref);
95
- rsi_free(rsii);
96
- kfree(rsii);
104
+
105
+ call_rcu(&rsii->rcu_head, rsi_free_rcu);
97106 }
98107
99108 static inline int rsi_hash(struct rsi *item)
....@@ -171,6 +180,11 @@
171180 return NULL;
172181 }
173182
183
+static int rsi_upcall(struct cache_detail *cd, struct cache_head *h)
184
+{
185
+ return sunrpc_cache_pipe_upcall_timeout(cd, h);
186
+}
187
+
174188 static void rsi_request(struct cache_detail *cd,
175189 struct cache_head *h,
176190 char **bpp, int *blen)
....@@ -190,7 +204,7 @@
190204 char *ep;
191205 int len;
192206 struct rsi rsii, *rsip = NULL;
193
- time_t expiry;
207
+ time64_t expiry;
194208 int status = -EINVAL;
195209
196210 memset(&rsii, 0, sizeof(rsii));
....@@ -269,6 +283,7 @@
269283 .hash_size = RSI_HASHMAX,
270284 .name = "auth.rpcsec.init",
271285 .cache_put = rsi_put,
286
+ .cache_upcall = rsi_upcall,
272287 .cache_request = rsi_request,
273288 .cache_parse = rsi_parse,
274289 .match = rsi_match,
....@@ -282,7 +297,7 @@
282297 struct cache_head *ch;
283298 int hash = rsi_hash(item);
284299
285
- ch = sunrpc_cache_lookup(cd, &item->h, hash);
300
+ ch = sunrpc_cache_lookup_rcu(cd, &item->h, hash);
286301 if (ch)
287302 return container_of(ch, struct rsi, h);
288303 else
....@@ -317,7 +332,7 @@
317332
318333 struct gss_svc_seq_data {
319334 /* highest seq number seen so far: */
320
- int sd_max;
335
+ u32 sd_max;
321336 /* for i such that sd_max-GSS_SEQ_WIN < i <= sd_max, the i-th bit of
322337 * sd_win is nonzero iff sequence number i has been seen already: */
323338 unsigned long sd_win[GSS_SEQ_WIN/BITS_PER_LONG];
....@@ -330,6 +345,7 @@
330345 struct svc_cred cred;
331346 struct gss_svc_seq_data seqdata;
332347 struct gss_ctx *mechctx;
348
+ struct rcu_head rcu_head;
333349 };
334350
335351 static struct rsc *rsc_update(struct cache_detail *cd, struct rsc *new, struct rsc *old);
....@@ -343,12 +359,22 @@
343359 free_svc_cred(&rsci->cred);
344360 }
345361
362
+static void rsc_free_rcu(struct rcu_head *head)
363
+{
364
+ struct rsc *rsci = container_of(head, struct rsc, rcu_head);
365
+
366
+ kfree(rsci->handle.data);
367
+ kfree(rsci);
368
+}
369
+
346370 static void rsc_put(struct kref *ref)
347371 {
348372 struct rsc *rsci = container_of(ref, struct rsc, h.ref);
349373
350
- rsc_free(rsci);
351
- kfree(rsci);
374
+ if (rsci->mechctx)
375
+ gss_delete_sec_context(&rsci->mechctx);
376
+ free_svc_cred(&rsci->cred);
377
+ call_rcu(&rsci->rcu_head, rsc_free_rcu);
352378 }
353379
354380 static inline int
....@@ -404,6 +430,11 @@
404430 return NULL;
405431 }
406432
433
+static int rsc_upcall(struct cache_detail *cd, struct cache_head *h)
434
+{
435
+ return -EINVAL;
436
+}
437
+
407438 static int rsc_parse(struct cache_detail *cd,
408439 char *mesg, int mlen)
409440 {
....@@ -412,7 +443,7 @@
412443 int id;
413444 int len, rv;
414445 struct rsc rsci, *rscp = NULL;
415
- time_t expiry;
446
+ time64_t expiry;
416447 int status = -EINVAL;
417448 struct gss_api_mech *gm = NULL;
418449
....@@ -453,12 +484,12 @@
453484 * treatment so are checked for validity here.)
454485 */
455486 /* uid */
456
- rsci.cred.cr_uid = make_kuid(&init_user_ns, id);
487
+ rsci.cred.cr_uid = make_kuid(current_user_ns(), id);
457488
458489 /* gid */
459490 if (get_int(&mesg, &id))
460491 goto out;
461
- rsci.cred.cr_gid = make_kgid(&init_user_ns, id);
492
+ rsci.cred.cr_gid = make_kgid(current_user_ns(), id);
462493
463494 /* number of additional gid's */
464495 if (get_int(&mesg, &N))
....@@ -476,7 +507,7 @@
476507 kgid_t kgid;
477508 if (get_int(&mesg, &id))
478509 goto out;
479
- kgid = make_kgid(&init_user_ns, id);
510
+ kgid = make_kgid(current_user_ns(), id);
480511 if (!gid_valid(kgid))
481512 goto out;
482513 rsci.cred.cr_group_info->gid[i] = kgid;
....@@ -530,6 +561,7 @@
530561 .hash_size = RSC_HASHMAX,
531562 .name = "auth.rpcsec.context",
532563 .cache_put = rsc_put,
564
+ .cache_upcall = rsc_upcall,
533565 .cache_parse = rsc_parse,
534566 .match = rsc_match,
535567 .init = rsc_init,
....@@ -542,7 +574,7 @@
542574 struct cache_head *ch;
543575 int hash = rsc_hash(item);
544576
545
- ch = sunrpc_cache_lookup(cd, &item->h, hash);
577
+ ch = sunrpc_cache_lookup_rcu(cd, &item->h, hash);
546578 if (ch)
547579 return container_of(ch, struct rsc, h);
548580 else
....@@ -581,16 +613,29 @@
581613 return found;
582614 }
583615
584
-/* Implements sequence number algorithm as specified in RFC 2203. */
585
-static int
586
-gss_check_seq_num(struct rsc *rsci, int seq_num)
616
+/**
617
+ * gss_check_seq_num - GSS sequence number window check
618
+ * @rqstp: RPC Call to use when reporting errors
619
+ * @rsci: cached GSS context state (updated on return)
620
+ * @seq_num: sequence number to check
621
+ *
622
+ * Implements sequence number algorithm as specified in
623
+ * RFC 2203, Section 5.3.3.1. "Context Management".
624
+ *
625
+ * Return values:
626
+ * %true: @rqstp's GSS sequence number is inside the window
627
+ * %false: @rqstp's GSS sequence number is outside the window
628
+ */
629
+static bool gss_check_seq_num(const struct svc_rqst *rqstp, struct rsc *rsci,
630
+ u32 seq_num)
587631 {
588632 struct gss_svc_seq_data *sd = &rsci->seqdata;
633
+ bool result = false;
589634
590635 spin_lock(&sd->sd_lock);
591636 if (seq_num > sd->sd_max) {
592637 if (seq_num >= sd->sd_max + GSS_SEQ_WIN) {
593
- memset(sd->sd_win,0,sizeof(sd->sd_win));
638
+ memset(sd->sd_win, 0, sizeof(sd->sd_win));
594639 sd->sd_max = seq_num;
595640 } else while (sd->sd_max < seq_num) {
596641 sd->sd_max++;
....@@ -598,18 +643,26 @@
598643 }
599644 __set_bit(seq_num % GSS_SEQ_WIN, sd->sd_win);
600645 goto ok;
601
- } else if (seq_num <= sd->sd_max - GSS_SEQ_WIN) {
602
- goto drop;
646
+ } else if (seq_num + GSS_SEQ_WIN <= sd->sd_max) {
647
+ goto toolow;
603648 }
604
- /* sd_max - GSS_SEQ_WIN < seq_num <= sd_max */
605649 if (__test_and_set_bit(seq_num % GSS_SEQ_WIN, sd->sd_win))
606
- goto drop;
650
+ goto alreadyseen;
651
+
607652 ok:
653
+ result = true;
654
+out:
608655 spin_unlock(&sd->sd_lock);
609
- return 1;
610
-drop:
611
- spin_unlock(&sd->sd_lock);
612
- return 0;
656
+ return result;
657
+
658
+toolow:
659
+ trace_rpcgss_svc_seqno_low(rqstp, seq_num,
660
+ sd->sd_max - GSS_SEQ_WIN,
661
+ sd->sd_max);
662
+ goto out;
663
+alreadyseen:
664
+ trace_rpcgss_svc_seqno_seen(rqstp, seq_num);
665
+ goto out;
613666 }
614667
615668 static inline u32 round_up_to_quad(u32 i)
....@@ -689,16 +742,12 @@
689742 }
690743
691744 if (gc->gc_seq > MAXSEQ) {
692
- dprintk("RPC: svcauth_gss: discarding request with "
693
- "large sequence number %d\n", gc->gc_seq);
745
+ trace_rpcgss_svc_seqno_large(rqstp, gc->gc_seq);
694746 *authp = rpcsec_gsserr_ctxproblem;
695747 return SVC_DENIED;
696748 }
697
- if (!gss_check_seq_num(rsci, gc->gc_seq)) {
698
- dprintk("RPC: svcauth_gss: discarding request with "
699
- "old sequence number %d\n", gc->gc_seq);
749
+ if (!gss_check_seq_num(rqstp, rsci, gc->gc_seq))
700750 return SVC_DROP;
701
- }
702751 return SVC_OK;
703752 }
704753
....@@ -836,10 +885,12 @@
836885 static int
837886 unwrap_integ_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx)
838887 {
888
+ u32 integ_len, rseqno, maj_stat;
839889 int stat = -EINVAL;
840
- u32 integ_len, maj_stat;
841890 struct xdr_netobj mic;
842891 struct xdr_buf integ_buf;
892
+
893
+ mic.data = NULL;
843894
844895 /* NFS READ normally uses splice to send data in-place. However
845896 * the data in cache can change after the reply's MIC is computed
....@@ -855,34 +906,44 @@
855906
856907 integ_len = svc_getnl(&buf->head[0]);
857908 if (integ_len & 3)
858
- return stat;
909
+ goto unwrap_failed;
859910 if (integ_len > buf->len)
860
- return stat;
861
- if (xdr_buf_subsegment(buf, &integ_buf, 0, integ_len)) {
862
- WARN_ON_ONCE(1);
863
- return stat;
864
- }
911
+ goto unwrap_failed;
912
+ if (xdr_buf_subsegment(buf, &integ_buf, 0, integ_len))
913
+ goto unwrap_failed;
914
+
865915 /* copy out mic... */
866916 if (read_u32_from_xdr_buf(buf, integ_len, &mic.len))
867
- return stat;
917
+ goto unwrap_failed;
868918 if (mic.len > RPC_MAX_AUTH_SIZE)
869
- return stat;
919
+ goto unwrap_failed;
870920 mic.data = kmalloc(mic.len, GFP_KERNEL);
871921 if (!mic.data)
872
- return stat;
922
+ goto unwrap_failed;
873923 if (read_bytes_from_xdr_buf(buf, integ_len + 4, mic.data, mic.len))
874
- goto out;
924
+ goto unwrap_failed;
875925 maj_stat = gss_verify_mic(ctx, &integ_buf, &mic);
876926 if (maj_stat != GSS_S_COMPLETE)
877
- goto out;
878
- if (svc_getnl(&buf->head[0]) != seq)
879
- goto out;
927
+ goto bad_mic;
928
+ rseqno = svc_getnl(&buf->head[0]);
929
+ if (rseqno != seq)
930
+ goto bad_seqno;
880931 /* trim off the mic and padding at the end before returning */
881932 xdr_buf_trim(buf, round_up_to_quad(mic.len) + 4);
882933 stat = 0;
883934 out:
884935 kfree(mic.data);
885936 return stat;
937
+
938
+unwrap_failed:
939
+ trace_rpcgss_svc_unwrap_failed(rqstp);
940
+ goto out;
941
+bad_seqno:
942
+ trace_rpcgss_svc_seqno_bad(rqstp, seq, rseqno);
943
+ goto out;
944
+bad_mic:
945
+ trace_rpcgss_svc_mic(rqstp, maj_stat);
946
+ goto out;
886947 }
887948
888949 static inline int
....@@ -906,7 +967,8 @@
906967 unwrap_priv_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx)
907968 {
908969 u32 priv_len, maj_stat;
909
- int pad, saved_len, remaining_len, offset;
970
+ int pad, remaining_len, offset;
971
+ u32 rseqno;
910972
911973 clear_bit(RQ_SPLICE_OK, &rqstp->rq_flags);
912974
....@@ -921,36 +983,42 @@
921983 * not yet read from the head, so these two values are different: */
922984 remaining_len = total_buf_len(buf);
923985 if (priv_len > remaining_len)
924
- return -EINVAL;
986
+ goto unwrap_failed;
925987 pad = remaining_len - priv_len;
926988 buf->len -= pad;
927989 fix_priv_head(buf, pad);
928990
929
- /* Maybe it would be better to give gss_unwrap a length parameter: */
930
- saved_len = buf->len;
931
- buf->len = priv_len;
932
- maj_stat = gss_unwrap(ctx, 0, buf);
991
+ maj_stat = gss_unwrap(ctx, 0, priv_len, buf);
933992 pad = priv_len - buf->len;
934
- buf->len = saved_len;
935
- buf->len -= pad;
936993 /* The upper layers assume the buffer is aligned on 4-byte boundaries.
937994 * In the krb5p case, at least, the data ends up offset, so we need to
938995 * move it around. */
939996 /* XXX: This is very inefficient. It would be better to either do
940997 * this while we encrypt, or maybe in the receive code, if we can peak
941998 * ahead and work out the service and mechanism there. */
942
- offset = buf->head[0].iov_len % 4;
999
+ offset = xdr_pad_size(buf->head[0].iov_len);
9431000 if (offset) {
9441001 buf->buflen = RPCSVC_MAXPAYLOAD;
9451002 xdr_shift_buf(buf, offset);
9461003 fix_priv_head(buf, pad);
9471004 }
9481005 if (maj_stat != GSS_S_COMPLETE)
949
- return -EINVAL;
1006
+ goto bad_unwrap;
9501007 out_seq:
951
- if (svc_getnl(&buf->head[0]) != seq)
952
- return -EINVAL;
1008
+ rseqno = svc_getnl(&buf->head[0]);
1009
+ if (rseqno != seq)
1010
+ goto bad_seqno;
9531011 return 0;
1012
+
1013
+unwrap_failed:
1014
+ trace_rpcgss_svc_unwrap_failed(rqstp);
1015
+ return -EINVAL;
1016
+bad_seqno:
1017
+ trace_rpcgss_svc_seqno_bad(rqstp, seq, rseqno);
1018
+ return -EINVAL;
1019
+bad_unwrap:
1020
+ trace_rpcgss_svc_unwrap(rqstp, maj_stat);
1021
+ return -EINVAL;
9541022 }
9551023
9561024 struct gss_svc_data {
....@@ -1088,18 +1156,23 @@
10881156 return res;
10891157
10901158 inlen = svc_getnl(argv);
1091
- if (inlen > (argv->iov_len + rqstp->rq_arg.page_len))
1159
+ if (inlen > (argv->iov_len + rqstp->rq_arg.page_len)) {
1160
+ kfree(in_handle->data);
10921161 return SVC_DENIED;
1162
+ }
10931163
10941164 pages = DIV_ROUND_UP(inlen, PAGE_SIZE);
10951165 in_token->pages = kcalloc(pages, sizeof(struct page *), GFP_KERNEL);
1096
- if (!in_token->pages)
1166
+ if (!in_token->pages) {
1167
+ kfree(in_handle->data);
10971168 return SVC_DENIED;
1169
+ }
10981170 in_token->page_base = 0;
10991171 in_token->page_len = inlen;
11001172 for (i = 0; i < pages; i++) {
11011173 in_token->pages[i] = alloc_page(GFP_KERNEL);
11021174 if (!in_token->pages[i]) {
1175
+ kfree(in_handle->data);
11031176 gss_free_in_token_pages(in_token);
11041177 return SVC_DENIED;
11051178 }
....@@ -1206,7 +1279,7 @@
12061279 static atomic64_t ctxhctr;
12071280 long long ctxh;
12081281 struct gss_api_mech *gm = NULL;
1209
- time_t expiry;
1282
+ time64_t expiry;
12101283 int status = -EINVAL;
12111284
12121285 memset(&rsci, 0, sizeof(rsci));
....@@ -1230,7 +1303,6 @@
12301303 if (!ud->found_creds) {
12311304 /* userspace seem buggy, we should always get at least a
12321305 * mapping to nobody */
1233
- dprintk("RPC: No creds found!\n");
12341306 goto out;
12351307 } else {
12361308 struct timespec64 boot;
....@@ -1296,9 +1368,7 @@
12961368 if (status)
12971369 goto out;
12981370
1299
- dprintk("RPC: svcauth_gss: gss major status = %d "
1300
- "minor status = %d\n",
1301
- ud.major_status, ud.minor_status);
1371
+ trace_rpcgss_svc_accept_upcall(rqstp, ud.major_status, ud.minor_status);
13021372
13031373 switch (ud.major_status) {
13041374 case GSS_S_CONTINUE_NEEDED:
....@@ -1306,31 +1376,23 @@
13061376 break;
13071377 case GSS_S_COMPLETE:
13081378 status = gss_proxy_save_rsc(sn->rsc_cache, &ud, &handle);
1309
- if (status) {
1310
- pr_info("%s: gss_proxy_save_rsc failed (%d)\n",
1311
- __func__, status);
1379
+ if (status)
13121380 goto out;
1313
- }
13141381 cli_handle.data = (u8 *)&handle;
13151382 cli_handle.len = sizeof(handle);
13161383 break;
13171384 default:
1318
- ret = SVC_CLOSE;
13191385 goto out;
13201386 }
13211387
13221388 /* Got an answer to the upcall; use it: */
13231389 if (gss_write_init_verf(sn->rsc_cache, rqstp,
1324
- &cli_handle, &ud.major_status)) {
1325
- pr_info("%s: gss_write_init_verf failed\n", __func__);
1390
+ &cli_handle, &ud.major_status))
13261391 goto out;
1327
- }
13281392 if (gss_write_resv(resv, PAGE_SIZE,
13291393 &cli_handle, &ud.out_token,
1330
- ud.major_status, ud.minor_status)) {
1331
- pr_info("%s: gss_write_resv failed\n", __func__);
1394
+ ud.major_status, ud.minor_status))
13321395 goto out;
1333
- }
13341396
13351397 ret = SVC_COMPLETE;
13361398 out:
....@@ -1418,10 +1480,10 @@
14181480 return len;
14191481 }
14201482
1421
-static const struct file_operations use_gss_proxy_ops = {
1422
- .open = nonseekable_open,
1423
- .write = write_gssp,
1424
- .read = read_gssp,
1483
+static const struct proc_ops use_gss_proxy_proc_ops = {
1484
+ .proc_open = nonseekable_open,
1485
+ .proc_write = write_gssp,
1486
+ .proc_read = read_gssp,
14251487 };
14261488
14271489 static int create_use_gss_proxy_proc_entry(struct net *net)
....@@ -1432,7 +1494,7 @@
14321494 sn->use_gss_proxy = -1;
14331495 *p = proc_create_data("use-gss-proxy", S_IFREG | 0600,
14341496 sn->proc_net_rpc,
1435
- &use_gss_proxy_ops, net);
1497
+ &use_gss_proxy_proc_ops, net);
14361498 if (!*p)
14371499 return -ENOMEM;
14381500 init_gssp_clnt(sn);
....@@ -1480,9 +1542,6 @@
14801542 __be32 *reject_stat = resv->iov_base + resv->iov_len;
14811543 int ret;
14821544 struct sunrpc_net *sn = net_generic(SVC_NET(rqstp), sunrpc_net_id);
1483
-
1484
- dprintk("RPC: svcauth_gss: argv->iov_len = %zd\n",
1485
- argv->iov_len);
14861545
14871546 *authp = rpc_autherr_badcred;
14881547 if (!svcdata)
....@@ -1600,6 +1659,7 @@
16001659 GSS_C_QOP_DEFAULT,
16011660 gc->gc_svc);
16021661 ret = SVC_OK;
1662
+ trace_rpcgss_svc_authenticate(rqstp, gc);
16031663 goto out;
16041664 }
16051665 garbage_args:
....@@ -1666,7 +1726,8 @@
16661726 goto out;
16671727 integ_offset = (u8 *)(p + 1) - (u8 *)resbuf->head[0].iov_base;
16681728 integ_len = resbuf->len - integ_offset;
1669
- BUG_ON(integ_len % 4);
1729
+ if (integ_len & 3)
1730
+ goto out;
16701731 *p++ = htonl(integ_len);
16711732 *p++ = htonl(gc->gc_seq);
16721733 if (xdr_buf_subsegment(resbuf, &integ_buf, integ_offset, integ_len)) {
....@@ -1690,7 +1751,8 @@
16901751 resv->iov_len += XDR_QUADLEN(mic.len) << 2;
16911752 /* not strictly required: */
16921753 resbuf->len += XDR_QUADLEN(mic.len) << 2;
1693
- BUG_ON(resv->iov_len > PAGE_SIZE);
1754
+ if (resv->iov_len > PAGE_SIZE)
1755
+ goto out_err;
16941756 out:
16951757 stat = 0;
16961758 out_err:
....@@ -1726,9 +1788,11 @@
17261788 * both the head and tail.
17271789 */
17281790 if (resbuf->tail[0].iov_base) {
1729
- BUG_ON(resbuf->tail[0].iov_base >= resbuf->head[0].iov_base
1730
- + PAGE_SIZE);
1731
- BUG_ON(resbuf->tail[0].iov_base < resbuf->head[0].iov_base);
1791
+ if (resbuf->tail[0].iov_base >=
1792
+ resbuf->head[0].iov_base + PAGE_SIZE)
1793
+ return -EINVAL;
1794
+ if (resbuf->tail[0].iov_base < resbuf->head[0].iov_base)
1795
+ return -EINVAL;
17321796 if (resbuf->tail[0].iov_len + resbuf->head[0].iov_len
17331797 + 2 * RPC_MAX_AUTH_SIZE > PAGE_SIZE)
17341798 return -ENOMEM;
....@@ -1822,14 +1886,21 @@
18221886 }
18231887
18241888 static void
1825
-svcauth_gss_domain_release(struct auth_domain *dom)
1889
+svcauth_gss_domain_release_rcu(struct rcu_head *head)
18261890 {
1891
+ struct auth_domain *dom = container_of(head, struct auth_domain, rcu_head);
18271892 struct gss_domain *gd = container_of(dom, struct gss_domain, h);
18281893
18291894 kfree(dom->name);
18301895 kfree(gd);
18311896 }
18321897
1898
+static void
1899
+svcauth_gss_domain_release(struct auth_domain *dom)
1900
+{
1901
+ call_rcu(&dom->rcu_head, svcauth_gss_domain_release_rcu);
1902
+}
1903
+
18331904 static struct auth_ops svcauthops_gss = {
18341905 .name = "rpcsec_gss",
18351906 .owner = THIS_MODULE,