hc
2024-02-19 1c055e55a242a33e574e48be530e06770a210dcd
kernel/net/sunrpc/auth_gss/auth_gss.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: BSD-3-Clause
12 /*
23 * linux/net/sunrpc/auth_gss/auth_gss.c
34 *
....@@ -8,33 +9,7 @@
89 *
910 * Dug Song <dugsong@monkey.org>
1011 * Andy Adamson <andros@umich.edu>
11
- *
12
- * Redistribution and use in source and binary forms, with or without
13
- * modification, are permitted provided that the following conditions
14
- * are met:
15
- *
16
- * 1. Redistributions of source code must retain the above copyright
17
- * notice, this list of conditions and the following disclaimer.
18
- * 2. Redistributions in binary form must reproduce the above copyright
19
- * notice, this list of conditions and the following disclaimer in the
20
- * documentation and/or other materials provided with the distribution.
21
- * 3. Neither the name of the University nor the names of its
22
- * contributors may be used to endorse or promote products derived
23
- * from this software without specific prior written permission.
24
- *
25
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
26
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
27
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28
- * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
32
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3612 */
37
-
3813
3914 #include <linux/module.h>
4015 #include <linux/init.h>
....@@ -45,6 +20,7 @@
4520 #include <linux/sunrpc/clnt.h>
4621 #include <linux/sunrpc/auth.h>
4722 #include <linux/sunrpc/auth_gss.h>
23
+#include <linux/sunrpc/gss_krb5.h>
4824 #include <linux/sunrpc/svcauth_gss.h>
4925 #include <linux/sunrpc/gss_err.h>
5026 #include <linux/workqueue.h>
....@@ -55,6 +31,8 @@
5531
5632 #include "auth_gss_internal.h"
5733 #include "../netns.h"
34
+
35
+#include <trace/events/rpcgss.h>
5836
5937 static const struct rpc_authops authgss_ops;
6038
....@@ -232,6 +210,7 @@
232210 }
233211 ret = gss_import_sec_context(p, seclen, gm, &ctx->gc_gss_ctx, NULL, GFP_NOFS);
234212 if (ret < 0) {
213
+ trace_rpcgss_import_ctx(ret);
235214 p = ERR_PTR(ret);
236215 goto err;
237216 }
....@@ -247,12 +226,9 @@
247226 if (IS_ERR(p))
248227 goto err;
249228 done:
250
- dprintk("RPC: %s Success. gc_expiry %lu now %lu timeout %u acceptor %.*s\n",
251
- __func__, ctx->gc_expiry, now, timeout, ctx->gc_acceptor.len,
252
- ctx->gc_acceptor.data);
253
- return p;
229
+ trace_rpcgss_context(window_size, ctx->gc_expiry, now, timeout,
230
+ ctx->gc_acceptor.len, ctx->gc_acceptor.data);
254231 err:
255
- dprintk("RPC: %s returns error %ld\n", __func__, -PTR_ERR(p));
256232 return p;
257233 }
258234
....@@ -266,6 +242,7 @@
266242 struct gss_upcall_msg {
267243 refcount_t count;
268244 kuid_t uid;
245
+ const char *service_name;
269246 struct rpc_pipe_msg msg;
270247 struct list_head list;
271248 struct gss_auth *auth;
....@@ -313,6 +290,7 @@
313290 gss_put_ctx(gss_msg->ctx);
314291 rpc_destroy_wait_queue(&gss_msg->rpc_waitqueue);
315292 gss_put_auth(gss_msg->auth);
293
+ kfree_const(gss_msg->service_name);
316294 kfree(gss_msg);
317295 }
318296
....@@ -323,13 +301,11 @@
323301 list_for_each_entry(pos, &pipe->in_downcall, list) {
324302 if (!uid_eq(pos->uid, uid))
325303 continue;
326
- if (auth && pos->auth->service != auth->service)
304
+ if (pos->auth->service != auth->service)
327305 continue;
328306 refcount_inc(&pos->count);
329
- dprintk("RPC: %s found msg %p\n", __func__, pos);
330307 return pos;
331308 }
332
- dprintk("RPC: %s found nothing\n", __func__);
333309 return NULL;
334310 }
335311
....@@ -409,9 +385,12 @@
409385 gss_release_msg(gss_msg);
410386 }
411387
412
-static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg)
388
+static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg,
389
+ const struct cred *cred)
413390 {
414
- uid_t uid = from_kuid(&init_user_ns, gss_msg->uid);
391
+ struct user_namespace *userns = cred->user_ns;
392
+
393
+ uid_t uid = from_kuid_munged(userns, gss_msg->uid);
415394 memcpy(gss_msg->databuf, &uid, sizeof(uid));
416395 gss_msg->msg.data = gss_msg->databuf;
417396 gss_msg->msg.len = sizeof(uid);
....@@ -419,17 +398,31 @@
419398 BUILD_BUG_ON(sizeof(uid) > sizeof(gss_msg->databuf));
420399 }
421400
401
+static ssize_t
402
+gss_v0_upcall(struct file *file, struct rpc_pipe_msg *msg,
403
+ char __user *buf, size_t buflen)
404
+{
405
+ struct gss_upcall_msg *gss_msg = container_of(msg,
406
+ struct gss_upcall_msg,
407
+ msg);
408
+ if (msg->copied == 0)
409
+ gss_encode_v0_msg(gss_msg, file->f_cred);
410
+ return rpc_pipe_generic_upcall(file, msg, buf, buflen);
411
+}
412
+
422413 static int gss_encode_v1_msg(struct gss_upcall_msg *gss_msg,
423414 const char *service_name,
424
- const char *target_name)
415
+ const char *target_name,
416
+ const struct cred *cred)
425417 {
418
+ struct user_namespace *userns = cred->user_ns;
426419 struct gss_api_mech *mech = gss_msg->auth->mech;
427420 char *p = gss_msg->databuf;
428421 size_t buflen = sizeof(gss_msg->databuf);
429422 int len;
430423
431
- len = scnprintf(p, buflen, "mech=%s uid=%d ", mech->gm_name,
432
- from_kuid(&init_user_ns, gss_msg->uid));
424
+ len = scnprintf(p, buflen, "mech=%s uid=%d", mech->gm_name,
425
+ from_kuid_munged(userns, gss_msg->uid));
433426 buflen -= len;
434427 p += len;
435428 gss_msg->msg.len = len;
....@@ -439,7 +432,7 @@
439432 * identity that we are authenticating to.
440433 */
441434 if (target_name) {
442
- len = scnprintf(p, buflen, "target=%s ", target_name);
435
+ len = scnprintf(p, buflen, " target=%s", target_name);
443436 buflen -= len;
444437 p += len;
445438 gss_msg->msg.len += len;
....@@ -459,11 +452,11 @@
459452 char *c = strchr(service_name, '@');
460453
461454 if (!c)
462
- len = scnprintf(p, buflen, "service=%s ",
455
+ len = scnprintf(p, buflen, " service=%s",
463456 service_name);
464457 else
465458 len = scnprintf(p, buflen,
466
- "service=%.*s srchost=%s ",
459
+ " service=%.*s srchost=%s",
467460 (int)(c - service_name),
468461 service_name, c + 1);
469462 buflen -= len;
....@@ -472,22 +465,41 @@
472465 }
473466
474467 if (mech->gm_upcall_enctypes) {
475
- len = scnprintf(p, buflen, "enctypes=%s ",
468
+ len = scnprintf(p, buflen, " enctypes=%s",
476469 mech->gm_upcall_enctypes);
477470 buflen -= len;
478471 p += len;
479472 gss_msg->msg.len += len;
480473 }
474
+ trace_rpcgss_upcall_msg(gss_msg->databuf);
481475 len = scnprintf(p, buflen, "\n");
482476 if (len == 0)
483477 goto out_overflow;
484478 gss_msg->msg.len += len;
485
-
486479 gss_msg->msg.data = gss_msg->databuf;
487480 return 0;
488481 out_overflow:
489482 WARN_ON_ONCE(1);
490483 return -ENOMEM;
484
+}
485
+
486
+static ssize_t
487
+gss_v1_upcall(struct file *file, struct rpc_pipe_msg *msg,
488
+ char __user *buf, size_t buflen)
489
+{
490
+ struct gss_upcall_msg *gss_msg = container_of(msg,
491
+ struct gss_upcall_msg,
492
+ msg);
493
+ int err;
494
+ if (msg->copied == 0) {
495
+ err = gss_encode_v1_msg(gss_msg,
496
+ gss_msg->service_name,
497
+ gss_msg->auth->target_name,
498
+ file->f_cred);
499
+ if (err)
500
+ return err;
501
+ }
502
+ return rpc_pipe_generic_upcall(file, msg, buf, buflen);
491503 }
492504
493505 static struct gss_upcall_msg *
....@@ -512,16 +524,14 @@
512524 refcount_set(&gss_msg->count, 1);
513525 gss_msg->uid = uid;
514526 gss_msg->auth = gss_auth;
515
- switch (vers) {
516
- case 0:
517
- gss_encode_v0_msg(gss_msg);
518
- break;
519
- default:
520
- err = gss_encode_v1_msg(gss_msg, service_name, gss_auth->target_name);
521
- if (err)
522
- goto err_put_pipe_version;
523
- }
524527 kref_get(&gss_auth->kref);
528
+ if (service_name) {
529
+ gss_msg->service_name = kstrdup_const(service_name, GFP_NOFS);
530
+ if (!gss_msg->service_name) {
531
+ err = -ENOMEM;
532
+ goto err_put_pipe_version;
533
+ }
534
+ }
525535 return gss_msg;
526536 err_put_pipe_version:
527537 put_pipe_version(gss_auth->net);
....@@ -537,7 +547,7 @@
537547 struct gss_cred *gss_cred = container_of(cred,
538548 struct gss_cred, gc_base);
539549 struct gss_upcall_msg *gss_new, *gss_msg;
540
- kuid_t uid = cred->cr_uid;
550
+ kuid_t uid = cred->cr_cred->fsuid;
541551
542552 gss_new = gss_alloc_msg(gss_auth, uid, gss_cred->gc_principal);
543553 if (IS_ERR(gss_new))
....@@ -575,16 +585,15 @@
575585 struct rpc_pipe *pipe;
576586 int err = 0;
577587
578
- dprintk("RPC: %5u %s for uid %u\n",
579
- task->tk_pid, __func__, from_kuid(&init_user_ns, cred->cr_uid));
580588 gss_msg = gss_setup_upcall(gss_auth, cred);
581589 if (PTR_ERR(gss_msg) == -EAGAIN) {
582590 /* XXX: warning on the first, under the assumption we
583591 * shouldn't normally hit this case on a refresh. */
584592 warn_gssd();
585
- task->tk_timeout = 15*HZ;
586
- rpc_sleep_on(&pipe_version_rpc_waitqueue, task, NULL);
587
- return -EAGAIN;
593
+ rpc_sleep_on_timeout(&pipe_version_rpc_waitqueue,
594
+ task, NULL, jiffies + (15 * HZ));
595
+ err = -EAGAIN;
596
+ goto out;
588597 }
589598 if (IS_ERR(gss_msg)) {
590599 err = PTR_ERR(gss_msg);
....@@ -595,7 +604,6 @@
595604 if (gss_cred->gc_upcall != NULL)
596605 rpc_sleep_on(&gss_cred->gc_upcall->rpc_waitqueue, task, NULL);
597606 else if (gss_msg->ctx == NULL && gss_msg->msg.errno >= 0) {
598
- task->tk_timeout = 0;
599607 gss_cred->gc_upcall = gss_msg;
600608 /* gss_upcall_callback will release the reference to gss_upcall_msg */
601609 refcount_inc(&gss_msg->count);
....@@ -607,9 +615,8 @@
607615 spin_unlock(&pipe->lock);
608616 gss_release_msg(gss_msg);
609617 out:
610
- dprintk("RPC: %5u %s for uid %u result %d\n",
611
- task->tk_pid, __func__,
612
- from_kuid(&init_user_ns, cred->cr_uid), err);
618
+ trace_rpcgss_upcall_result(from_kuid(&init_user_ns,
619
+ cred->cr_cred->fsuid), err);
613620 return err;
614621 }
615622
....@@ -624,14 +631,13 @@
624631 DEFINE_WAIT(wait);
625632 int err;
626633
627
- dprintk("RPC: %s for uid %u\n",
628
- __func__, from_kuid(&init_user_ns, cred->cr_uid));
629634 retry:
630635 err = 0;
631636 /* if gssd is down, just skip upcalling altogether */
632637 if (!gssd_running(net)) {
633638 warn_gssd();
634
- return -EACCES;
639
+ err = -EACCES;
640
+ goto out;
635641 }
636642 gss_msg = gss_setup_upcall(gss_auth, cred);
637643 if (PTR_ERR(gss_msg) == -EAGAIN) {
....@@ -663,18 +669,35 @@
663669 }
664670 schedule();
665671 }
666
- if (gss_msg->ctx)
672
+ if (gss_msg->ctx) {
673
+ trace_rpcgss_ctx_init(gss_cred);
667674 gss_cred_set_ctx(cred, gss_msg->ctx);
668
- else
675
+ } else {
669676 err = gss_msg->msg.errno;
677
+ }
670678 spin_unlock(&pipe->lock);
671679 out_intr:
672680 finish_wait(&gss_msg->waitqueue, &wait);
673681 gss_release_msg(gss_msg);
674682 out:
675
- dprintk("RPC: %s for uid %u result %d\n",
676
- __func__, from_kuid(&init_user_ns, cred->cr_uid), err);
683
+ trace_rpcgss_upcall_result(from_kuid(&init_user_ns,
684
+ cred->cr_cred->fsuid), err);
677685 return err;
686
+}
687
+
688
+static struct gss_upcall_msg *
689
+gss_find_downcall(struct rpc_pipe *pipe, kuid_t uid)
690
+{
691
+ struct gss_upcall_msg *pos;
692
+ list_for_each_entry(pos, &pipe->in_downcall, list) {
693
+ if (!uid_eq(pos->uid, uid))
694
+ continue;
695
+ if (!rpc_msg_is_inflight(&pos->msg))
696
+ continue;
697
+ refcount_inc(&pos->count);
698
+ return pos;
699
+ }
700
+ return NULL;
678701 }
679702
680703 #define MSG_BUF_MAXSIZE 1024
....@@ -709,7 +732,7 @@
709732 goto err;
710733 }
711734
712
- uid = make_kuid(&init_user_ns, id);
735
+ uid = make_kuid(current_user_ns(), id);
713736 if (!uid_valid(uid)) {
714737 err = -EINVAL;
715738 goto err;
....@@ -723,7 +746,7 @@
723746 err = -ENOENT;
724747 /* Find a matching upcall */
725748 spin_lock(&pipe->lock);
726
- gss_msg = __gss_find_upcall(pipe, uid, NULL);
749
+ gss_msg = gss_find_downcall(pipe, uid);
727750 if (gss_msg == NULL) {
728751 spin_unlock(&pipe->lock);
729752 goto err_put_ctx;
....@@ -766,7 +789,6 @@
766789 err:
767790 kfree(buf);
768791 out:
769
- dprintk("RPC: %s returning %zd\n", __func__, err);
770792 return err;
771793 }
772794
....@@ -835,8 +857,6 @@
835857 struct gss_upcall_msg *gss_msg = container_of(msg, struct gss_upcall_msg, msg);
836858
837859 if (msg->errno < 0) {
838
- dprintk("RPC: %s releasing msg %p\n",
839
- __func__, gss_msg);
840860 refcount_inc(&gss_msg->count);
841861 gss_unhash_msg(gss_msg);
842862 if (msg->errno == -ETIMEDOUT)
....@@ -996,8 +1016,6 @@
9961016 struct rpc_auth * auth;
9971017 int err = -ENOMEM; /* XXX? */
9981018
999
- dprintk("RPC: creating GSS authenticator for client %p\n", clnt);
1000
-
10011019 if (!try_module_get(THIS_MODULE))
10021020 return ERR_PTR(err);
10031021 if (!(gss_auth = kmalloc(sizeof(*gss_auth), GFP_KERNEL)))
....@@ -1013,10 +1031,8 @@
10131031 gss_auth->net = get_net(rpc_net_ns(clnt));
10141032 err = -EINVAL;
10151033 gss_auth->mech = gss_mech_get_by_pseudoflavor(flavor);
1016
- if (!gss_auth->mech) {
1017
- dprintk("RPC: Pseudoflavor %d not found!\n", flavor);
1034
+ if (!gss_auth->mech)
10181035 goto err_put_net;
1019
- }
10201036 gss_auth->service = gss_pseudoflavor_to_service(gss_auth->mech, flavor);
10211037 if (gss_auth->service == 0)
10221038 goto err_put_mech;
....@@ -1024,13 +1040,15 @@
10241040 goto err_put_mech;
10251041 auth = &gss_auth->rpc_auth;
10261042 auth->au_cslack = GSS_CRED_SLACK >> 2;
1027
- auth->au_rslack = GSS_VERF_SLACK >> 2;
1028
- auth->au_flags = 0;
1043
+ auth->au_rslack = GSS_KRB5_MAX_SLACK_NEEDED >> 2;
1044
+ auth->au_verfsize = GSS_VERF_SLACK >> 2;
1045
+ auth->au_ralign = GSS_VERF_SLACK >> 2;
1046
+ __set_bit(RPCAUTH_AUTH_UPDATE_SLACK, &auth->au_flags);
10291047 auth->au_ops = &authgss_ops;
10301048 auth->au_flavor = flavor;
10311049 if (gss_pseudoflavor_to_datatouch(gss_auth->mech, flavor))
1032
- auth->au_flags |= RPCAUTH_AUTH_DATATOUCH;
1033
- atomic_set(&auth->au_count, 1);
1050
+ __set_bit(RPCAUTH_AUTH_DATATOUCH, &auth->au_flags);
1051
+ refcount_set(&auth->au_count, 1);
10341052 kref_init(&gss_auth->kref);
10351053
10361054 err = rpcauth_init_credcache(auth);
....@@ -1071,6 +1089,7 @@
10711089 kfree(gss_auth);
10721090 out_dec:
10731091 module_put(THIS_MODULE);
1092
+ trace_rpcgss_createauth(flavor, err);
10741093 return ERR_PTR(err);
10751094 }
10761095
....@@ -1106,9 +1125,6 @@
11061125 {
11071126 struct gss_auth *gss_auth = container_of(auth,
11081127 struct gss_auth, rpc_auth);
1109
-
1110
- dprintk("RPC: destroying GSS authenticator %p flavor %d\n",
1111
- auth, auth->au_flavor);
11121128
11131129 if (hash_hashed(&gss_auth->hash)) {
11141130 spin_lock(&gss_auth_hash_lock);
....@@ -1159,7 +1175,7 @@
11591175 if (strcmp(gss_auth->target_name, args->target_name))
11601176 continue;
11611177 }
1162
- if (!atomic_inc_not_zero(&gss_auth->rpc_auth.au_count))
1178
+ if (!refcount_inc_not_zero(&gss_auth->rpc_auth.au_count))
11631179 continue;
11641180 goto out;
11651181 }
....@@ -1211,36 +1227,60 @@
12111227 return &gss_auth->rpc_auth;
12121228 }
12131229
1230
+static struct gss_cred *
1231
+gss_dup_cred(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
1232
+{
1233
+ struct gss_cred *new;
1234
+
1235
+ /* Make a copy of the cred so that we can reference count it */
1236
+ new = kzalloc(sizeof(*gss_cred), GFP_NOFS);
1237
+ if (new) {
1238
+ struct auth_cred acred = {
1239
+ .cred = gss_cred->gc_base.cr_cred,
1240
+ };
1241
+ struct gss_cl_ctx *ctx =
1242
+ rcu_dereference_protected(gss_cred->gc_ctx, 1);
1243
+
1244
+ rpcauth_init_cred(&new->gc_base, &acred,
1245
+ &gss_auth->rpc_auth,
1246
+ &gss_nullops);
1247
+ new->gc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE;
1248
+ new->gc_service = gss_cred->gc_service;
1249
+ new->gc_principal = gss_cred->gc_principal;
1250
+ kref_get(&gss_auth->kref);
1251
+ rcu_assign_pointer(new->gc_ctx, ctx);
1252
+ gss_get_ctx(ctx);
1253
+ }
1254
+ return new;
1255
+}
1256
+
12141257 /*
1215
- * gss_destroying_context will cause the RPCSEC_GSS to send a NULL RPC call
1258
+ * gss_send_destroy_context will cause the RPCSEC_GSS to send a NULL RPC call
12161259 * to the server with the GSS control procedure field set to
12171260 * RPC_GSS_PROC_DESTROY. This should normally cause the server to release
12181261 * all RPCSEC_GSS state associated with that context.
12191262 */
1220
-static int
1221
-gss_destroying_context(struct rpc_cred *cred)
1263
+static void
1264
+gss_send_destroy_context(struct rpc_cred *cred)
12221265 {
12231266 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
12241267 struct gss_auth *gss_auth = container_of(cred->cr_auth, struct gss_auth, rpc_auth);
12251268 struct gss_cl_ctx *ctx = rcu_dereference_protected(gss_cred->gc_ctx, 1);
1269
+ struct gss_cred *new;
12261270 struct rpc_task *task;
12271271
1228
- if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) == 0)
1229
- return 0;
1272
+ new = gss_dup_cred(gss_auth, gss_cred);
1273
+ if (new) {
1274
+ ctx->gc_proc = RPC_GSS_PROC_DESTROY;
12301275
1231
- ctx->gc_proc = RPC_GSS_PROC_DESTROY;
1232
- cred->cr_ops = &gss_nullops;
1276
+ trace_rpcgss_ctx_destroy(gss_cred);
1277
+ task = rpc_call_null(gss_auth->client, &new->gc_base,
1278
+ RPC_TASK_ASYNC);
1279
+ if (!IS_ERR(task))
1280
+ rpc_put_task(task);
12331281
1234
- /* Take a reference to ensure the cred will be destroyed either
1235
- * by the RPC call or by the put_rpccred() below */
1236
- get_rpccred(cred);
1237
-
1238
- task = rpc_call_null(gss_auth->client, cred, RPC_TASK_ASYNC|RPC_TASK_SOFT);
1239
- if (!IS_ERR(task))
1240
- rpc_put_task(task);
1241
-
1242
- put_rpccred(cred);
1243
- return 1;
1282
+ put_rpccred(&new->gc_base);
1283
+ }
12441284 }
12451285
12461286 /* gss_destroy_cred (and gss_free_ctx) are used to clean up after failure
....@@ -1249,8 +1289,6 @@
12491289 static void
12501290 gss_do_free_ctx(struct gss_cl_ctx *ctx)
12511291 {
1252
- dprintk("RPC: %s\n", __func__);
1253
-
12541292 gss_delete_sec_context(&ctx->gc_gss_ctx);
12551293 kfree(ctx->gc_wire_ctx.data);
12561294 kfree(ctx->gc_acceptor.data);
....@@ -1273,7 +1311,6 @@
12731311 static void
12741312 gss_free_cred(struct gss_cred *gss_cred)
12751313 {
1276
- dprintk("RPC: %s cred=%p\n", __func__, gss_cred);
12771314 kfree(gss_cred);
12781315 }
12791316
....@@ -1292,6 +1329,7 @@
12921329 struct gss_cl_ctx *ctx = rcu_dereference_protected(gss_cred->gc_ctx, 1);
12931330
12941331 RCU_INIT_POINTER(gss_cred->gc_ctx, NULL);
1332
+ put_cred(cred->cr_cred);
12951333 call_rcu(&cred->cr_rcu, gss_free_cred_callback);
12961334 if (ctx)
12971335 gss_put_ctx(ctx);
....@@ -1301,16 +1339,15 @@
13011339 static void
13021340 gss_destroy_cred(struct rpc_cred *cred)
13031341 {
1304
-
1305
- if (gss_destroying_context(cred))
1306
- return;
1342
+ if (test_and_clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0)
1343
+ gss_send_destroy_context(cred);
13071344 gss_destroy_nullcred(cred);
13081345 }
13091346
13101347 static int
13111348 gss_hash_cred(struct auth_cred *acred, unsigned int hashbits)
13121349 {
1313
- return hash_64(from_kuid(&init_user_ns, acred->uid), hashbits);
1350
+ return hash_64(from_kuid(&init_user_ns, acred->cred->fsuid), hashbits);
13141351 }
13151352
13161353 /*
....@@ -1329,10 +1366,6 @@
13291366 struct gss_cred *cred = NULL;
13301367 int err = -ENOMEM;
13311368
1332
- dprintk("RPC: %s for uid %d, flavor %d\n",
1333
- __func__, from_kuid(&init_user_ns, acred->uid),
1334
- auth->au_flavor);
1335
-
13361369 if (!(cred = kzalloc(sizeof(*cred), gfp)))
13371370 goto out_err;
13381371
....@@ -1343,14 +1376,11 @@
13431376 */
13441377 cred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_NEW;
13451378 cred->gc_service = gss_auth->service;
1346
- cred->gc_principal = NULL;
1347
- if (acred->machine_cred)
1348
- cred->gc_principal = acred->principal;
1379
+ cred->gc_principal = acred->principal;
13491380 kref_get(&gss_auth->kref);
13501381 return &cred->gc_base;
13511382
13521383 out_err:
1353
- dprintk("RPC: %s failed with error %d\n", __func__, err);
13541384 return ERR_PTR(err);
13551385 }
13561386
....@@ -1467,85 +1497,93 @@
14671497 if (gss_cred->gc_principal == NULL)
14681498 return 0;
14691499 ret = strcmp(acred->principal, gss_cred->gc_principal) == 0;
1470
- goto check_expire;
1471
- }
1472
- if (gss_cred->gc_principal != NULL)
1473
- return 0;
1474
- ret = uid_eq(rc->cr_uid, acred->uid);
1475
-
1476
-check_expire:
1477
- if (ret == 0)
1478
- return ret;
1479
-
1480
- /* Notify acred users of GSS context expiration timeout */
1481
- if (test_bit(RPC_CRED_NOTIFY_TIMEOUT, &acred->ac_flags) &&
1482
- (gss_key_timeout(rc) != 0)) {
1483
- /* test will now be done from generic cred */
1484
- test_and_clear_bit(RPC_CRED_NOTIFY_TIMEOUT, &acred->ac_flags);
1485
- /* tell NFS layer that key will expire soon */
1486
- set_bit(RPC_CRED_KEY_EXPIRE_SOON, &acred->ac_flags);
1500
+ } else {
1501
+ if (gss_cred->gc_principal != NULL)
1502
+ return 0;
1503
+ ret = uid_eq(rc->cr_cred->fsuid, acred->cred->fsuid);
14871504 }
14881505 return ret;
14891506 }
14901507
14911508 /*
1492
-* Marshal credentials.
1493
-* Maybe we should keep a cached credential for performance reasons.
1494
-*/
1495
-static __be32 *
1496
-gss_marshal(struct rpc_task *task, __be32 *p)
1509
+ * Marshal credentials.
1510
+ *
1511
+ * The expensive part is computing the verifier. We can't cache a
1512
+ * pre-computed version of the verifier because the seqno, which
1513
+ * is different every time, is included in the MIC.
1514
+ */
1515
+static int gss_marshal(struct rpc_task *task, struct xdr_stream *xdr)
14971516 {
14981517 struct rpc_rqst *req = task->tk_rqstp;
14991518 struct rpc_cred *cred = req->rq_cred;
15001519 struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
15011520 gc_base);
15021521 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
1503
- __be32 *cred_len;
1522
+ __be32 *p, *cred_len;
15041523 u32 maj_stat = 0;
15051524 struct xdr_netobj mic;
15061525 struct kvec iov;
15071526 struct xdr_buf verf_buf;
1527
+ int status;
15081528
1509
- dprintk("RPC: %5u %s\n", task->tk_pid, __func__);
1529
+ /* Credential */
15101530
1511
- *p++ = htonl(RPC_AUTH_GSS);
1531
+ p = xdr_reserve_space(xdr, 7 * sizeof(*p) +
1532
+ ctx->gc_wire_ctx.len);
1533
+ if (!p)
1534
+ goto marshal_failed;
1535
+ *p++ = rpc_auth_gss;
15121536 cred_len = p++;
15131537
15141538 spin_lock(&ctx->gc_seq_lock);
1515
- req->rq_seqno = ctx->gc_seq++;
1539
+ req->rq_seqno = (ctx->gc_seq < MAXSEQ) ? ctx->gc_seq++ : MAXSEQ;
15161540 spin_unlock(&ctx->gc_seq_lock);
1541
+ if (req->rq_seqno == MAXSEQ)
1542
+ goto expired;
1543
+ trace_rpcgss_seqno(task);
15171544
1518
- *p++ = htonl((u32) RPC_GSS_VERSION);
1519
- *p++ = htonl((u32) ctx->gc_proc);
1520
- *p++ = htonl((u32) req->rq_seqno);
1521
- *p++ = htonl((u32) gss_cred->gc_service);
1545
+ *p++ = cpu_to_be32(RPC_GSS_VERSION);
1546
+ *p++ = cpu_to_be32(ctx->gc_proc);
1547
+ *p++ = cpu_to_be32(req->rq_seqno);
1548
+ *p++ = cpu_to_be32(gss_cred->gc_service);
15221549 p = xdr_encode_netobj(p, &ctx->gc_wire_ctx);
1523
- *cred_len = htonl((p - (cred_len + 1)) << 2);
1550
+ *cred_len = cpu_to_be32((p - (cred_len + 1)) << 2);
1551
+
1552
+ /* Verifier */
15241553
15251554 /* We compute the checksum for the verifier over the xdr-encoded bytes
15261555 * starting with the xid and ending at the end of the credential: */
1527
- iov.iov_base = xprt_skip_transport_header(req->rq_xprt,
1528
- req->rq_snd_buf.head[0].iov_base);
1556
+ iov.iov_base = req->rq_snd_buf.head[0].iov_base;
15291557 iov.iov_len = (u8 *)p - (u8 *)iov.iov_base;
15301558 xdr_buf_from_iov(&iov, &verf_buf);
15311559
1532
- /* set verifier flavor*/
1533
- *p++ = htonl(RPC_AUTH_GSS);
1534
-
1560
+ p = xdr_reserve_space(xdr, sizeof(*p));
1561
+ if (!p)
1562
+ goto marshal_failed;
1563
+ *p++ = rpc_auth_gss;
15351564 mic.data = (u8 *)(p + 1);
15361565 maj_stat = gss_get_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
1537
- if (maj_stat == GSS_S_CONTEXT_EXPIRED) {
1538
- clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
1539
- } else if (maj_stat != 0) {
1540
- printk("gss_marshal: gss_get_mic FAILED (%d)\n", maj_stat);
1541
- goto out_put_ctx;
1542
- }
1543
- p = xdr_encode_opaque(p, NULL, mic.len);
1566
+ if (maj_stat == GSS_S_CONTEXT_EXPIRED)
1567
+ goto expired;
1568
+ else if (maj_stat != 0)
1569
+ goto bad_mic;
1570
+ if (xdr_stream_encode_opaque_inline(xdr, (void **)&p, mic.len) < 0)
1571
+ goto marshal_failed;
1572
+ status = 0;
1573
+out:
15441574 gss_put_ctx(ctx);
1545
- return p;
1546
-out_put_ctx:
1547
- gss_put_ctx(ctx);
1548
- return NULL;
1575
+ return status;
1576
+expired:
1577
+ clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
1578
+ status = -EKEYEXPIRED;
1579
+ goto out;
1580
+marshal_failed:
1581
+ status = -EMSGSIZE;
1582
+ goto out;
1583
+bad_mic:
1584
+ trace_rpcgss_get_mic(task, maj_stat);
1585
+ status = -EIO;
1586
+ goto out;
15491587 }
15501588
15511589 static int gss_renew_cred(struct rpc_task *task)
....@@ -1556,15 +1594,15 @@
15561594 gc_base);
15571595 struct rpc_auth *auth = oldcred->cr_auth;
15581596 struct auth_cred acred = {
1559
- .uid = oldcred->cr_uid,
1597
+ .cred = oldcred->cr_cred,
15601598 .principal = gss_cred->gc_principal,
1561
- .machine_cred = (gss_cred->gc_principal != NULL ? 1 : 0),
15621599 };
15631600 struct rpc_cred *new;
15641601
15651602 new = gss_lookup_cred(auth, &acred, RPCAUTH_LOOKUP_NEW);
15661603 if (IS_ERR(new))
15671604 return PTR_ERR(new);
1605
+
15681606 task->tk_rqstp->rq_cred = new;
15691607 put_rpccred(oldcred);
15701608 return 0;
....@@ -1620,116 +1658,107 @@
16201658 return 0;
16211659 }
16221660
1623
-static __be32 *
1624
-gss_validate(struct rpc_task *task, __be32 *p)
1661
+static int
1662
+gss_validate(struct rpc_task *task, struct xdr_stream *xdr)
16251663 {
16261664 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
16271665 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
1628
- __be32 *seq = NULL;
1666
+ __be32 *p, *seq = NULL;
16291667 struct kvec iov;
16301668 struct xdr_buf verf_buf;
16311669 struct xdr_netobj mic;
1632
- u32 flav,len;
1633
- u32 maj_stat;
1634
- __be32 *ret = ERR_PTR(-EIO);
1670
+ u32 len, maj_stat;
1671
+ int status;
16351672
1636
- dprintk("RPC: %5u %s\n", task->tk_pid, __func__);
1673
+ p = xdr_inline_decode(xdr, 2 * sizeof(*p));
1674
+ if (!p)
1675
+ goto validate_failed;
1676
+ if (*p++ != rpc_auth_gss)
1677
+ goto validate_failed;
1678
+ len = be32_to_cpup(p);
1679
+ if (len > RPC_MAX_AUTH_SIZE)
1680
+ goto validate_failed;
1681
+ p = xdr_inline_decode(xdr, len);
1682
+ if (!p)
1683
+ goto validate_failed;
16371684
1638
- flav = ntohl(*p++);
1639
- if ((len = ntohl(*p++)) > RPC_MAX_AUTH_SIZE)
1640
- goto out_bad;
1641
- if (flav != RPC_AUTH_GSS)
1642
- goto out_bad;
16431685 seq = kmalloc(4, GFP_NOFS);
16441686 if (!seq)
1645
- goto out_bad;
1646
- *seq = htonl(task->tk_rqstp->rq_seqno);
1687
+ goto validate_failed;
1688
+ *seq = cpu_to_be32(task->tk_rqstp->rq_seqno);
16471689 iov.iov_base = seq;
16481690 iov.iov_len = 4;
16491691 xdr_buf_from_iov(&iov, &verf_buf);
16501692 mic.data = (u8 *)p;
16511693 mic.len = len;
1652
-
1653
- ret = ERR_PTR(-EACCES);
16541694 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
16551695 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
16561696 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
1657
- if (maj_stat) {
1658
- dprintk("RPC: %5u %s: gss_verify_mic returned error 0x%08x\n",
1659
- task->tk_pid, __func__, maj_stat);
1660
- goto out_bad;
1661
- }
1697
+ if (maj_stat)
1698
+ goto bad_mic;
1699
+
16621700 /* We leave it to unwrap to calculate au_rslack. For now we just
16631701 * calculate the length of the verifier: */
1664
- cred->cr_auth->au_verfsize = XDR_QUADLEN(len) + 2;
1702
+ if (test_bit(RPCAUTH_AUTH_UPDATE_SLACK, &cred->cr_auth->au_flags))
1703
+ cred->cr_auth->au_verfsize = XDR_QUADLEN(len) + 2;
1704
+ status = 0;
1705
+out:
16651706 gss_put_ctx(ctx);
1666
- dprintk("RPC: %5u %s: gss_verify_mic succeeded.\n",
1667
- task->tk_pid, __func__);
16681707 kfree(seq);
1669
- return p + XDR_QUADLEN(len);
1670
-out_bad:
1671
- gss_put_ctx(ctx);
1672
- dprintk("RPC: %5u %s failed ret %ld.\n", task->tk_pid, __func__,
1673
- PTR_ERR(ret));
1674
- kfree(seq);
1675
- return ret;
1708
+ return status;
1709
+
1710
+validate_failed:
1711
+ status = -EIO;
1712
+ goto out;
1713
+bad_mic:
1714
+ trace_rpcgss_verify_mic(task, maj_stat);
1715
+ status = -EACCES;
1716
+ goto out;
16761717 }
16771718
1678
-static void gss_wrap_req_encode(kxdreproc_t encode, struct rpc_rqst *rqstp,
1679
- __be32 *p, void *obj)
1680
-{
1681
- struct xdr_stream xdr;
1682
-
1683
- xdr_init_encode(&xdr, &rqstp->rq_snd_buf, p);
1684
- encode(rqstp, &xdr, obj);
1685
-}
1686
-
1687
-static inline int
1719
+static noinline_for_stack int
16881720 gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
1689
- kxdreproc_t encode, struct rpc_rqst *rqstp,
1690
- __be32 *p, void *obj)
1721
+ struct rpc_task *task, struct xdr_stream *xdr)
16911722 {
1692
- struct xdr_buf *snd_buf = &rqstp->rq_snd_buf;
1693
- struct xdr_buf integ_buf;
1694
- __be32 *integ_len = NULL;
1723
+ struct rpc_rqst *rqstp = task->tk_rqstp;
1724
+ struct xdr_buf integ_buf, *snd_buf = &rqstp->rq_snd_buf;
16951725 struct xdr_netobj mic;
1696
- u32 offset;
1697
- __be32 *q;
1698
- struct kvec *iov;
1699
- u32 maj_stat = 0;
1700
- int status = -EIO;
1726
+ __be32 *p, *integ_len;
1727
+ u32 offset, maj_stat;
17011728
1729
+ p = xdr_reserve_space(xdr, 2 * sizeof(*p));
1730
+ if (!p)
1731
+ goto wrap_failed;
17021732 integ_len = p++;
1733
+ *p = cpu_to_be32(rqstp->rq_seqno);
1734
+
1735
+ if (rpcauth_wrap_req_encode(task, xdr))
1736
+ goto wrap_failed;
1737
+
17031738 offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
1704
- *p++ = htonl(rqstp->rq_seqno);
1705
-
1706
- gss_wrap_req_encode(encode, rqstp, p, obj);
1707
-
17081739 if (xdr_buf_subsegment(snd_buf, &integ_buf,
17091740 offset, snd_buf->len - offset))
1710
- return status;
1711
- *integ_len = htonl(integ_buf.len);
1741
+ goto wrap_failed;
1742
+ *integ_len = cpu_to_be32(integ_buf.len);
17121743
1713
- /* guess whether we're in the head or the tail: */
1714
- if (snd_buf->page_len || snd_buf->tail[0].iov_len)
1715
- iov = snd_buf->tail;
1716
- else
1717
- iov = snd_buf->head;
1718
- p = iov->iov_base + iov->iov_len;
1744
+ p = xdr_reserve_space(xdr, 0);
1745
+ if (!p)
1746
+ goto wrap_failed;
17191747 mic.data = (u8 *)(p + 1);
1720
-
17211748 maj_stat = gss_get_mic(ctx->gc_gss_ctx, &integ_buf, &mic);
1722
- status = -EIO; /* XXX? */
17231749 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
17241750 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
17251751 else if (maj_stat)
1726
- return status;
1727
- q = xdr_encode_opaque(p, NULL, mic.len);
1728
-
1729
- offset = (u8 *)q - (u8 *)p;
1730
- iov->iov_len += offset;
1731
- snd_buf->len += offset;
1752
+ goto bad_mic;
1753
+ /* Check that the trailing MIC fit in the buffer, after the fact */
1754
+ if (xdr_stream_encode_opaque_inline(xdr, (void **)&p, mic.len) < 0)
1755
+ goto wrap_failed;
17321756 return 0;
1757
+wrap_failed:
1758
+ return -EMSGSIZE;
1759
+bad_mic:
1760
+ trace_rpcgss_get_mic(task, maj_stat);
1761
+ return -EIO;
17331762 }
17341763
17351764 static void
....@@ -1780,224 +1809,348 @@
17801809 return -EAGAIN;
17811810 }
17821811
1783
-static inline int
1812
+static noinline_for_stack int
17841813 gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
1785
- kxdreproc_t encode, struct rpc_rqst *rqstp,
1786
- __be32 *p, void *obj)
1814
+ struct rpc_task *task, struct xdr_stream *xdr)
17871815 {
1816
+ struct rpc_rqst *rqstp = task->tk_rqstp;
17881817 struct xdr_buf *snd_buf = &rqstp->rq_snd_buf;
1789
- u32 offset;
1790
- u32 maj_stat;
1818
+ u32 pad, offset, maj_stat;
17911819 int status;
1792
- __be32 *opaque_len;
1820
+ __be32 *p, *opaque_len;
17931821 struct page **inpages;
17941822 int first;
1795
- int pad;
17961823 struct kvec *iov;
1797
- char *tmp;
17981824
1825
+ status = -EIO;
1826
+ p = xdr_reserve_space(xdr, 2 * sizeof(*p));
1827
+ if (!p)
1828
+ goto wrap_failed;
17991829 opaque_len = p++;
1800
- offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
1801
- *p++ = htonl(rqstp->rq_seqno);
1830
+ *p = cpu_to_be32(rqstp->rq_seqno);
18021831
1803
- gss_wrap_req_encode(encode, rqstp, p, obj);
1832
+ if (rpcauth_wrap_req_encode(task, xdr))
1833
+ goto wrap_failed;
18041834
18051835 status = alloc_enc_pages(rqstp);
1806
- if (status)
1807
- return status;
1836
+ if (unlikely(status))
1837
+ goto wrap_failed;
18081838 first = snd_buf->page_base >> PAGE_SHIFT;
18091839 inpages = snd_buf->pages + first;
18101840 snd_buf->pages = rqstp->rq_enc_pages;
18111841 snd_buf->page_base -= first << PAGE_SHIFT;
18121842 /*
1813
- * Give the tail its own page, in case we need extra space in the
1814
- * head when wrapping:
1843
+ * Move the tail into its own page, in case gss_wrap needs
1844
+ * more space in the head when wrapping.
18151845 *
1816
- * call_allocate() allocates twice the slack space required
1817
- * by the authentication flavor to rq_callsize.
1818
- * For GSS, slack is GSS_CRED_SLACK.
1846
+ * Still... Why can't gss_wrap just slide the tail down?
18191847 */
18201848 if (snd_buf->page_len || snd_buf->tail[0].iov_len) {
1849
+ char *tmp;
1850
+
18211851 tmp = page_address(rqstp->rq_enc_pages[rqstp->rq_enc_pages_num - 1]);
18221852 memcpy(tmp, snd_buf->tail[0].iov_base, snd_buf->tail[0].iov_len);
18231853 snd_buf->tail[0].iov_base = tmp;
18241854 }
1855
+ offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
18251856 maj_stat = gss_wrap(ctx->gc_gss_ctx, offset, snd_buf, inpages);
18261857 /* slack space should prevent this ever happening: */
1827
- BUG_ON(snd_buf->len > snd_buf->buflen);
1828
- status = -EIO;
1858
+ if (unlikely(snd_buf->len > snd_buf->buflen))
1859
+ goto wrap_failed;
18291860 /* We're assuming that when GSS_S_CONTEXT_EXPIRED, the encryption was
18301861 * done anyway, so it's safe to put the request on the wire: */
18311862 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
18321863 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
18331864 else if (maj_stat)
1834
- return status;
1865
+ goto bad_wrap;
18351866
1836
- *opaque_len = htonl(snd_buf->len - offset);
1837
- /* guess whether we're in the head or the tail: */
1867
+ *opaque_len = cpu_to_be32(snd_buf->len - offset);
1868
+ /* guess whether the pad goes into the head or the tail: */
18381869 if (snd_buf->page_len || snd_buf->tail[0].iov_len)
18391870 iov = snd_buf->tail;
18401871 else
18411872 iov = snd_buf->head;
18421873 p = iov->iov_base + iov->iov_len;
1843
- pad = 3 - ((snd_buf->len - offset - 1) & 3);
1874
+ pad = xdr_pad_size(snd_buf->len - offset);
18441875 memset(p, 0, pad);
18451876 iov->iov_len += pad;
18461877 snd_buf->len += pad;
18471878
18481879 return 0;
1880
+wrap_failed:
1881
+ return status;
1882
+bad_wrap:
1883
+ trace_rpcgss_wrap(task, maj_stat);
1884
+ return -EIO;
18491885 }
18501886
1851
-static int
1852
-gss_wrap_req(struct rpc_task *task,
1853
- kxdreproc_t encode, void *rqstp, __be32 *p, void *obj)
1887
+static int gss_wrap_req(struct rpc_task *task, struct xdr_stream *xdr)
18541888 {
18551889 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
18561890 struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
18571891 gc_base);
18581892 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
1859
- int status = -EIO;
1893
+ int status;
18601894
1861
- dprintk("RPC: %5u %s\n", task->tk_pid, __func__);
1895
+ status = -EIO;
18621896 if (ctx->gc_proc != RPC_GSS_PROC_DATA) {
18631897 /* The spec seems a little ambiguous here, but I think that not
18641898 * wrapping context destruction requests makes the most sense.
18651899 */
1866
- gss_wrap_req_encode(encode, rqstp, p, obj);
1867
- status = 0;
1900
+ status = rpcauth_wrap_req_encode(task, xdr);
18681901 goto out;
18691902 }
18701903 switch (gss_cred->gc_service) {
18711904 case RPC_GSS_SVC_NONE:
1872
- gss_wrap_req_encode(encode, rqstp, p, obj);
1873
- status = 0;
1905
+ status = rpcauth_wrap_req_encode(task, xdr);
18741906 break;
18751907 case RPC_GSS_SVC_INTEGRITY:
1876
- status = gss_wrap_req_integ(cred, ctx, encode, rqstp, p, obj);
1908
+ status = gss_wrap_req_integ(cred, ctx, task, xdr);
18771909 break;
18781910 case RPC_GSS_SVC_PRIVACY:
1879
- status = gss_wrap_req_priv(cred, ctx, encode, rqstp, p, obj);
1911
+ status = gss_wrap_req_priv(cred, ctx, task, xdr);
18801912 break;
1913
+ default:
1914
+ status = -EIO;
18811915 }
18821916 out:
18831917 gss_put_ctx(ctx);
1884
- dprintk("RPC: %5u %s returning %d\n", task->tk_pid, __func__, status);
18851918 return status;
18861919 }
18871920
1888
-static inline int
1889
-gss_unwrap_resp_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
1890
- struct rpc_rqst *rqstp, __be32 **p)
1921
+/**
1922
+ * gss_update_rslack - Possibly update RPC receive buffer size estimates
1923
+ * @task: rpc_task for incoming RPC Reply being unwrapped
1924
+ * @cred: controlling rpc_cred for @task
1925
+ * @before: XDR words needed before each RPC Reply message
1926
+ * @after: XDR words needed following each RPC Reply message
1927
+ *
1928
+ */
1929
+static void gss_update_rslack(struct rpc_task *task, struct rpc_cred *cred,
1930
+ unsigned int before, unsigned int after)
18911931 {
1892
- struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf;
1893
- struct xdr_buf integ_buf;
1932
+ struct rpc_auth *auth = cred->cr_auth;
1933
+
1934
+ if (test_and_clear_bit(RPCAUTH_AUTH_UPDATE_SLACK, &auth->au_flags)) {
1935
+ auth->au_ralign = auth->au_verfsize + before;
1936
+ auth->au_rslack = auth->au_verfsize + after;
1937
+ trace_rpcgss_update_slack(task, auth);
1938
+ }
1939
+}
1940
+
1941
+static int
1942
+gss_unwrap_resp_auth(struct rpc_task *task, struct rpc_cred *cred)
1943
+{
1944
+ gss_update_rslack(task, cred, 0, 0);
1945
+ return 0;
1946
+}
1947
+
1948
+/*
1949
+ * RFC 2203, Section 5.3.2.2
1950
+ *
1951
+ * struct rpc_gss_integ_data {
1952
+ * opaque databody_integ<>;
1953
+ * opaque checksum<>;
1954
+ * };
1955
+ *
1956
+ * struct rpc_gss_data_t {
1957
+ * unsigned int seq_num;
1958
+ * proc_req_arg_t arg;
1959
+ * };
1960
+ */
1961
+static noinline_for_stack int
1962
+gss_unwrap_resp_integ(struct rpc_task *task, struct rpc_cred *cred,
1963
+ struct gss_cl_ctx *ctx, struct rpc_rqst *rqstp,
1964
+ struct xdr_stream *xdr)
1965
+{
1966
+ struct xdr_buf gss_data, *rcv_buf = &rqstp->rq_rcv_buf;
1967
+ u32 len, offset, seqno, maj_stat;
18941968 struct xdr_netobj mic;
1895
- u32 data_offset, mic_offset;
1896
- u32 integ_len;
1897
- u32 maj_stat;
1898
- int status = -EIO;
1969
+ int ret;
18991970
1900
- integ_len = ntohl(*(*p)++);
1901
- if (integ_len & 3)
1902
- return status;
1903
- data_offset = (u8 *)(*p) - (u8 *)rcv_buf->head[0].iov_base;
1904
- mic_offset = integ_len + data_offset;
1905
- if (mic_offset > rcv_buf->len)
1906
- return status;
1907
- if (ntohl(*(*p)++) != rqstp->rq_seqno)
1908
- return status;
1971
+ ret = -EIO;
1972
+ mic.data = NULL;
19091973
1910
- if (xdr_buf_subsegment(rcv_buf, &integ_buf, data_offset,
1911
- mic_offset - data_offset))
1912
- return status;
1974
+ /* opaque databody_integ<>; */
1975
+ if (xdr_stream_decode_u32(xdr, &len))
1976
+ goto unwrap_failed;
1977
+ if (len & 3)
1978
+ goto unwrap_failed;
1979
+ offset = rcv_buf->len - xdr_stream_remaining(xdr);
1980
+ if (xdr_stream_decode_u32(xdr, &seqno))
1981
+ goto unwrap_failed;
1982
+ if (seqno != rqstp->rq_seqno)
1983
+ goto bad_seqno;
1984
+ if (xdr_buf_subsegment(rcv_buf, &gss_data, offset, len))
1985
+ goto unwrap_failed;
19131986
1914
- if (xdr_buf_read_netobj(rcv_buf, &mic, mic_offset))
1915
- return status;
1987
+ /*
1988
+ * The xdr_stream now points to the beginning of the
1989
+ * upper layer payload, to be passed below to
1990
+ * rpcauth_unwrap_resp_decode(). The checksum, which
1991
+ * follows the upper layer payload in @rcv_buf, is
1992
+ * located and parsed without updating the xdr_stream.
1993
+ */
19161994
1917
- maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &integ_buf, &mic);
1995
+ /* opaque checksum<>; */
1996
+ offset += len;
1997
+ if (xdr_decode_word(rcv_buf, offset, &len))
1998
+ goto unwrap_failed;
1999
+ offset += sizeof(__be32);
2000
+ if (offset + len > rcv_buf->len)
2001
+ goto unwrap_failed;
2002
+ mic.len = len;
2003
+ mic.data = kmalloc(len, GFP_NOFS);
2004
+ if (!mic.data)
2005
+ goto unwrap_failed;
2006
+ if (read_bytes_from_xdr_buf(rcv_buf, offset, mic.data, mic.len))
2007
+ goto unwrap_failed;
2008
+
2009
+ maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &gss_data, &mic);
19182010 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
19192011 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
19202012 if (maj_stat != GSS_S_COMPLETE)
1921
- return status;
1922
- return 0;
2013
+ goto bad_mic;
2014
+
2015
+ gss_update_rslack(task, cred, 2, 2 + 1 + XDR_QUADLEN(mic.len));
2016
+ ret = 0;
2017
+
2018
+out:
2019
+ kfree(mic.data);
2020
+ return ret;
2021
+
2022
+unwrap_failed:
2023
+ trace_rpcgss_unwrap_failed(task);
2024
+ goto out;
2025
+bad_seqno:
2026
+ trace_rpcgss_bad_seqno(task, rqstp->rq_seqno, seqno);
2027
+ goto out;
2028
+bad_mic:
2029
+ trace_rpcgss_verify_mic(task, maj_stat);
2030
+ goto out;
19232031 }
19242032
1925
-static inline int
1926
-gss_unwrap_resp_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
1927
- struct rpc_rqst *rqstp, __be32 **p)
2033
+static noinline_for_stack int
2034
+gss_unwrap_resp_priv(struct rpc_task *task, struct rpc_cred *cred,
2035
+ struct gss_cl_ctx *ctx, struct rpc_rqst *rqstp,
2036
+ struct xdr_stream *xdr)
19282037 {
1929
- struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf;
1930
- u32 offset;
1931
- u32 opaque_len;
1932
- u32 maj_stat;
1933
- int status = -EIO;
2038
+ struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf;
2039
+ struct kvec *head = rqstp->rq_rcv_buf.head;
2040
+ u32 offset, opaque_len, maj_stat;
2041
+ __be32 *p;
19342042
1935
- opaque_len = ntohl(*(*p)++);
1936
- offset = (u8 *)(*p) - (u8 *)rcv_buf->head[0].iov_base;
2043
+ p = xdr_inline_decode(xdr, 2 * sizeof(*p));
2044
+ if (unlikely(!p))
2045
+ goto unwrap_failed;
2046
+ opaque_len = be32_to_cpup(p++);
2047
+ offset = (u8 *)(p) - (u8 *)head->iov_base;
19372048 if (offset + opaque_len > rcv_buf->len)
1938
- return status;
1939
- /* remove padding: */
1940
- rcv_buf->len = offset + opaque_len;
2049
+ goto unwrap_failed;
19412050
1942
- maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset, rcv_buf);
2051
+ maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset,
2052
+ offset + opaque_len, rcv_buf);
19432053 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
19442054 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
19452055 if (maj_stat != GSS_S_COMPLETE)
1946
- return status;
1947
- if (ntohl(*(*p)++) != rqstp->rq_seqno)
1948
- return status;
2056
+ goto bad_unwrap;
2057
+ /* gss_unwrap decrypted the sequence number */
2058
+ if (be32_to_cpup(p++) != rqstp->rq_seqno)
2059
+ goto bad_seqno;
2060
+
2061
+ /* gss_unwrap redacts the opaque blob from the head iovec.
2062
+ * rcv_buf has changed, thus the stream needs to be reset.
2063
+ */
2064
+ xdr_init_decode(xdr, rcv_buf, p, rqstp);
2065
+
2066
+ gss_update_rslack(task, cred, 2 + ctx->gc_gss_ctx->align,
2067
+ 2 + ctx->gc_gss_ctx->slack);
19492068
19502069 return 0;
2070
+unwrap_failed:
2071
+ trace_rpcgss_unwrap_failed(task);
2072
+ return -EIO;
2073
+bad_seqno:
2074
+ trace_rpcgss_bad_seqno(task, rqstp->rq_seqno, be32_to_cpup(--p));
2075
+ return -EIO;
2076
+bad_unwrap:
2077
+ trace_rpcgss_unwrap(task, maj_stat);
2078
+ return -EIO;
2079
+}
2080
+
2081
+static bool
2082
+gss_seq_is_newer(u32 new, u32 old)
2083
+{
2084
+ return (s32)(new - old) > 0;
2085
+}
2086
+
2087
+static bool
2088
+gss_xmit_need_reencode(struct rpc_task *task)
2089
+{
2090
+ struct rpc_rqst *req = task->tk_rqstp;
2091
+ struct rpc_cred *cred = req->rq_cred;
2092
+ struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
2093
+ u32 win, seq_xmit = 0;
2094
+ bool ret = true;
2095
+
2096
+ if (!ctx)
2097
+ goto out;
2098
+
2099
+ if (gss_seq_is_newer(req->rq_seqno, READ_ONCE(ctx->gc_seq)))
2100
+ goto out_ctx;
2101
+
2102
+ seq_xmit = READ_ONCE(ctx->gc_seq_xmit);
2103
+ while (gss_seq_is_newer(req->rq_seqno, seq_xmit)) {
2104
+ u32 tmp = seq_xmit;
2105
+
2106
+ seq_xmit = cmpxchg(&ctx->gc_seq_xmit, tmp, req->rq_seqno);
2107
+ if (seq_xmit == tmp) {
2108
+ ret = false;
2109
+ goto out_ctx;
2110
+ }
2111
+ }
2112
+
2113
+ win = ctx->gc_win;
2114
+ if (win > 0)
2115
+ ret = !gss_seq_is_newer(req->rq_seqno, seq_xmit - win);
2116
+
2117
+out_ctx:
2118
+ gss_put_ctx(ctx);
2119
+out:
2120
+ trace_rpcgss_need_reencode(task, seq_xmit, ret);
2121
+ return ret;
19512122 }
19522123
19532124 static int
1954
-gss_unwrap_req_decode(kxdrdproc_t decode, struct rpc_rqst *rqstp,
1955
- __be32 *p, void *obj)
2125
+gss_unwrap_resp(struct rpc_task *task, struct xdr_stream *xdr)
19562126 {
1957
- struct xdr_stream xdr;
1958
-
1959
- xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
1960
- return decode(rqstp, &xdr, obj);
1961
-}
1962
-
1963
-static int
1964
-gss_unwrap_resp(struct rpc_task *task,
1965
- kxdrdproc_t decode, void *rqstp, __be32 *p, void *obj)
1966
-{
1967
- struct rpc_cred *cred = task->tk_rqstp->rq_cred;
2127
+ struct rpc_rqst *rqstp = task->tk_rqstp;
2128
+ struct rpc_cred *cred = rqstp->rq_cred;
19682129 struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
19692130 gc_base);
19702131 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
1971
- __be32 *savedp = p;
1972
- struct kvec *head = ((struct rpc_rqst *)rqstp)->rq_rcv_buf.head;
1973
- int savedlen = head->iov_len;
1974
- int status = -EIO;
2132
+ int status = -EIO;
19752133
19762134 if (ctx->gc_proc != RPC_GSS_PROC_DATA)
19772135 goto out_decode;
19782136 switch (gss_cred->gc_service) {
19792137 case RPC_GSS_SVC_NONE:
2138
+ status = gss_unwrap_resp_auth(task, cred);
19802139 break;
19812140 case RPC_GSS_SVC_INTEGRITY:
1982
- status = gss_unwrap_resp_integ(cred, ctx, rqstp, &p);
1983
- if (status)
1984
- goto out;
2141
+ status = gss_unwrap_resp_integ(task, cred, ctx, rqstp, xdr);
19852142 break;
19862143 case RPC_GSS_SVC_PRIVACY:
1987
- status = gss_unwrap_resp_priv(cred, ctx, rqstp, &p);
1988
- if (status)
1989
- goto out;
2144
+ status = gss_unwrap_resp_priv(task, cred, ctx, rqstp, xdr);
19902145 break;
19912146 }
1992
- /* take into account extra slack for integrity and privacy cases: */
1993
- cred->cr_auth->au_rslack = cred->cr_auth->au_verfsize + (p - savedp)
1994
- + (savedlen - head->iov_len);
2147
+ if (status)
2148
+ goto out;
2149
+
19952150 out_decode:
1996
- status = gss_unwrap_req_decode(decode, rqstp, p, obj);
2151
+ status = rpcauth_unwrap_resp_decode(task, xdr);
19972152 out:
19982153 gss_put_ctx(ctx);
1999
- dprintk("RPC: %5u %s returning %d\n",
2000
- task->tk_pid, __func__, status);
20012154 return status;
20022155 }
20032156
....@@ -2010,7 +2163,6 @@
20102163 .hash_cred = gss_hash_cred,
20112164 .lookup_cred = gss_lookup_cred,
20122165 .crcreate = gss_create_cred,
2013
- .list_pseudoflavors = gss_mech_list_pseudoflavors,
20142166 .info2flavor = gss_mech_info2flavor,
20152167 .flavor2info = gss_mech_flavor2info,
20162168 };
....@@ -2019,7 +2171,6 @@
20192171 .cr_name = "AUTH_GSS",
20202172 .crdestroy = gss_destroy_cred,
20212173 .cr_init = gss_cred_init,
2022
- .crbind = rpcauth_generic_bind_cred,
20232174 .crmatch = gss_match,
20242175 .crmarshal = gss_marshal,
20252176 .crrefresh = gss_refresh,
....@@ -2028,12 +2179,12 @@
20282179 .crunwrap_resp = gss_unwrap_resp,
20292180 .crkey_timeout = gss_key_timeout,
20302181 .crstringify_acceptor = gss_stringify_acceptor,
2182
+ .crneed_reencode = gss_xmit_need_reencode,
20312183 };
20322184
20332185 static const struct rpc_credops gss_nullops = {
20342186 .cr_name = "AUTH_GSS",
20352187 .crdestroy = gss_destroy_nullcred,
2036
- .crbind = rpcauth_generic_bind_cred,
20372188 .crmatch = gss_match,
20382189 .crmarshal = gss_marshal,
20392190 .crrefresh = gss_refresh_null,
....@@ -2044,7 +2195,7 @@
20442195 };
20452196
20462197 static const struct rpc_pipe_ops gss_upcall_ops_v0 = {
2047
- .upcall = rpc_pipe_generic_upcall,
2198
+ .upcall = gss_v0_upcall,
20482199 .downcall = gss_pipe_downcall,
20492200 .destroy_msg = gss_pipe_destroy_msg,
20502201 .open_pipe = gss_pipe_open_v0,
....@@ -2052,7 +2203,7 @@
20522203 };
20532204
20542205 static const struct rpc_pipe_ops gss_upcall_ops_v1 = {
2055
- .upcall = rpc_pipe_generic_upcall,
2206
+ .upcall = gss_v1_upcall,
20562207 .downcall = gss_pipe_downcall,
20572208 .destroy_msg = gss_pipe_destroy_msg,
20582209 .open_pipe = gss_pipe_open_v1,