forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
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
....@@ -326,10 +304,8 @@
326304 if (auth && 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,17 +669,19 @@
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;
678686 }
679687
....@@ -709,7 +717,7 @@
709717 goto err;
710718 }
711719
712
- uid = make_kuid(&init_user_ns, id);
720
+ uid = make_kuid(current_user_ns(), id);
713721 if (!uid_valid(uid)) {
714722 err = -EINVAL;
715723 goto err;
....@@ -766,7 +774,6 @@
766774 err:
767775 kfree(buf);
768776 out:
769
- dprintk("RPC: %s returning %zd\n", __func__, err);
770777 return err;
771778 }
772779
....@@ -835,8 +842,6 @@
835842 struct gss_upcall_msg *gss_msg = container_of(msg, struct gss_upcall_msg, msg);
836843
837844 if (msg->errno < 0) {
838
- dprintk("RPC: %s releasing msg %p\n",
839
- __func__, gss_msg);
840845 refcount_inc(&gss_msg->count);
841846 gss_unhash_msg(gss_msg);
842847 if (msg->errno == -ETIMEDOUT)
....@@ -996,8 +1001,6 @@
9961001 struct rpc_auth * auth;
9971002 int err = -ENOMEM; /* XXX? */
9981003
999
- dprintk("RPC: creating GSS authenticator for client %p\n", clnt);
1000
-
10011004 if (!try_module_get(THIS_MODULE))
10021005 return ERR_PTR(err);
10031006 if (!(gss_auth = kmalloc(sizeof(*gss_auth), GFP_KERNEL)))
....@@ -1013,10 +1016,8 @@
10131016 gss_auth->net = get_net(rpc_net_ns(clnt));
10141017 err = -EINVAL;
10151018 gss_auth->mech = gss_mech_get_by_pseudoflavor(flavor);
1016
- if (!gss_auth->mech) {
1017
- dprintk("RPC: Pseudoflavor %d not found!\n", flavor);
1019
+ if (!gss_auth->mech)
10181020 goto err_put_net;
1019
- }
10201021 gss_auth->service = gss_pseudoflavor_to_service(gss_auth->mech, flavor);
10211022 if (gss_auth->service == 0)
10221023 goto err_put_mech;
....@@ -1024,13 +1025,15 @@
10241025 goto err_put_mech;
10251026 auth = &gss_auth->rpc_auth;
10261027 auth->au_cslack = GSS_CRED_SLACK >> 2;
1027
- auth->au_rslack = GSS_VERF_SLACK >> 2;
1028
- auth->au_flags = 0;
1028
+ auth->au_rslack = GSS_KRB5_MAX_SLACK_NEEDED >> 2;
1029
+ auth->au_verfsize = GSS_VERF_SLACK >> 2;
1030
+ auth->au_ralign = GSS_VERF_SLACK >> 2;
1031
+ __set_bit(RPCAUTH_AUTH_UPDATE_SLACK, &auth->au_flags);
10291032 auth->au_ops = &authgss_ops;
10301033 auth->au_flavor = flavor;
10311034 if (gss_pseudoflavor_to_datatouch(gss_auth->mech, flavor))
1032
- auth->au_flags |= RPCAUTH_AUTH_DATATOUCH;
1033
- atomic_set(&auth->au_count, 1);
1035
+ __set_bit(RPCAUTH_AUTH_DATATOUCH, &auth->au_flags);
1036
+ refcount_set(&auth->au_count, 1);
10341037 kref_init(&gss_auth->kref);
10351038
10361039 err = rpcauth_init_credcache(auth);
....@@ -1071,6 +1074,7 @@
10711074 kfree(gss_auth);
10721075 out_dec:
10731076 module_put(THIS_MODULE);
1077
+ trace_rpcgss_createauth(flavor, err);
10741078 return ERR_PTR(err);
10751079 }
10761080
....@@ -1106,9 +1110,6 @@
11061110 {
11071111 struct gss_auth *gss_auth = container_of(auth,
11081112 struct gss_auth, rpc_auth);
1109
-
1110
- dprintk("RPC: destroying GSS authenticator %p flavor %d\n",
1111
- auth, auth->au_flavor);
11121113
11131114 if (hash_hashed(&gss_auth->hash)) {
11141115 spin_lock(&gss_auth_hash_lock);
....@@ -1159,7 +1160,7 @@
11591160 if (strcmp(gss_auth->target_name, args->target_name))
11601161 continue;
11611162 }
1162
- if (!atomic_inc_not_zero(&gss_auth->rpc_auth.au_count))
1163
+ if (!refcount_inc_not_zero(&gss_auth->rpc_auth.au_count))
11631164 continue;
11641165 goto out;
11651166 }
....@@ -1211,36 +1212,60 @@
12111212 return &gss_auth->rpc_auth;
12121213 }
12131214
1215
+static struct gss_cred *
1216
+gss_dup_cred(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
1217
+{
1218
+ struct gss_cred *new;
1219
+
1220
+ /* Make a copy of the cred so that we can reference count it */
1221
+ new = kzalloc(sizeof(*gss_cred), GFP_NOFS);
1222
+ if (new) {
1223
+ struct auth_cred acred = {
1224
+ .cred = gss_cred->gc_base.cr_cred,
1225
+ };
1226
+ struct gss_cl_ctx *ctx =
1227
+ rcu_dereference_protected(gss_cred->gc_ctx, 1);
1228
+
1229
+ rpcauth_init_cred(&new->gc_base, &acred,
1230
+ &gss_auth->rpc_auth,
1231
+ &gss_nullops);
1232
+ new->gc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE;
1233
+ new->gc_service = gss_cred->gc_service;
1234
+ new->gc_principal = gss_cred->gc_principal;
1235
+ kref_get(&gss_auth->kref);
1236
+ rcu_assign_pointer(new->gc_ctx, ctx);
1237
+ gss_get_ctx(ctx);
1238
+ }
1239
+ return new;
1240
+}
1241
+
12141242 /*
1215
- * gss_destroying_context will cause the RPCSEC_GSS to send a NULL RPC call
1243
+ * gss_send_destroy_context will cause the RPCSEC_GSS to send a NULL RPC call
12161244 * to the server with the GSS control procedure field set to
12171245 * RPC_GSS_PROC_DESTROY. This should normally cause the server to release
12181246 * all RPCSEC_GSS state associated with that context.
12191247 */
1220
-static int
1221
-gss_destroying_context(struct rpc_cred *cred)
1248
+static void
1249
+gss_send_destroy_context(struct rpc_cred *cred)
12221250 {
12231251 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
12241252 struct gss_auth *gss_auth = container_of(cred->cr_auth, struct gss_auth, rpc_auth);
12251253 struct gss_cl_ctx *ctx = rcu_dereference_protected(gss_cred->gc_ctx, 1);
1254
+ struct gss_cred *new;
12261255 struct rpc_task *task;
12271256
1228
- if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) == 0)
1229
- return 0;
1257
+ new = gss_dup_cred(gss_auth, gss_cred);
1258
+ if (new) {
1259
+ ctx->gc_proc = RPC_GSS_PROC_DESTROY;
12301260
1231
- ctx->gc_proc = RPC_GSS_PROC_DESTROY;
1232
- cred->cr_ops = &gss_nullops;
1261
+ trace_rpcgss_ctx_destroy(gss_cred);
1262
+ task = rpc_call_null(gss_auth->client, &new->gc_base,
1263
+ RPC_TASK_ASYNC);
1264
+ if (!IS_ERR(task))
1265
+ rpc_put_task(task);
12331266
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;
1267
+ put_rpccred(&new->gc_base);
1268
+ }
12441269 }
12451270
12461271 /* gss_destroy_cred (and gss_free_ctx) are used to clean up after failure
....@@ -1249,8 +1274,6 @@
12491274 static void
12501275 gss_do_free_ctx(struct gss_cl_ctx *ctx)
12511276 {
1252
- dprintk("RPC: %s\n", __func__);
1253
-
12541277 gss_delete_sec_context(&ctx->gc_gss_ctx);
12551278 kfree(ctx->gc_wire_ctx.data);
12561279 kfree(ctx->gc_acceptor.data);
....@@ -1273,7 +1296,6 @@
12731296 static void
12741297 gss_free_cred(struct gss_cred *gss_cred)
12751298 {
1276
- dprintk("RPC: %s cred=%p\n", __func__, gss_cred);
12771299 kfree(gss_cred);
12781300 }
12791301
....@@ -1292,6 +1314,7 @@
12921314 struct gss_cl_ctx *ctx = rcu_dereference_protected(gss_cred->gc_ctx, 1);
12931315
12941316 RCU_INIT_POINTER(gss_cred->gc_ctx, NULL);
1317
+ put_cred(cred->cr_cred);
12951318 call_rcu(&cred->cr_rcu, gss_free_cred_callback);
12961319 if (ctx)
12971320 gss_put_ctx(ctx);
....@@ -1301,16 +1324,15 @@
13011324 static void
13021325 gss_destroy_cred(struct rpc_cred *cred)
13031326 {
1304
-
1305
- if (gss_destroying_context(cred))
1306
- return;
1327
+ if (test_and_clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0)
1328
+ gss_send_destroy_context(cred);
13071329 gss_destroy_nullcred(cred);
13081330 }
13091331
13101332 static int
13111333 gss_hash_cred(struct auth_cred *acred, unsigned int hashbits)
13121334 {
1313
- return hash_64(from_kuid(&init_user_ns, acred->uid), hashbits);
1335
+ return hash_64(from_kuid(&init_user_ns, acred->cred->fsuid), hashbits);
13141336 }
13151337
13161338 /*
....@@ -1329,10 +1351,6 @@
13291351 struct gss_cred *cred = NULL;
13301352 int err = -ENOMEM;
13311353
1332
- dprintk("RPC: %s for uid %d, flavor %d\n",
1333
- __func__, from_kuid(&init_user_ns, acred->uid),
1334
- auth->au_flavor);
1335
-
13361354 if (!(cred = kzalloc(sizeof(*cred), gfp)))
13371355 goto out_err;
13381356
....@@ -1343,14 +1361,11 @@
13431361 */
13441362 cred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_NEW;
13451363 cred->gc_service = gss_auth->service;
1346
- cred->gc_principal = NULL;
1347
- if (acred->machine_cred)
1348
- cred->gc_principal = acred->principal;
1364
+ cred->gc_principal = acred->principal;
13491365 kref_get(&gss_auth->kref);
13501366 return &cred->gc_base;
13511367
13521368 out_err:
1353
- dprintk("RPC: %s failed with error %d\n", __func__, err);
13541369 return ERR_PTR(err);
13551370 }
13561371
....@@ -1467,85 +1482,93 @@
14671482 if (gss_cred->gc_principal == NULL)
14681483 return 0;
14691484 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);
1485
+ } else {
1486
+ if (gss_cred->gc_principal != NULL)
1487
+ return 0;
1488
+ ret = uid_eq(rc->cr_cred->fsuid, acred->cred->fsuid);
14871489 }
14881490 return ret;
14891491 }
14901492
14911493 /*
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)
1494
+ * Marshal credentials.
1495
+ *
1496
+ * The expensive part is computing the verifier. We can't cache a
1497
+ * pre-computed version of the verifier because the seqno, which
1498
+ * is different every time, is included in the MIC.
1499
+ */
1500
+static int gss_marshal(struct rpc_task *task, struct xdr_stream *xdr)
14971501 {
14981502 struct rpc_rqst *req = task->tk_rqstp;
14991503 struct rpc_cred *cred = req->rq_cred;
15001504 struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
15011505 gc_base);
15021506 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
1503
- __be32 *cred_len;
1507
+ __be32 *p, *cred_len;
15041508 u32 maj_stat = 0;
15051509 struct xdr_netobj mic;
15061510 struct kvec iov;
15071511 struct xdr_buf verf_buf;
1512
+ int status;
15081513
1509
- dprintk("RPC: %5u %s\n", task->tk_pid, __func__);
1514
+ /* Credential */
15101515
1511
- *p++ = htonl(RPC_AUTH_GSS);
1516
+ p = xdr_reserve_space(xdr, 7 * sizeof(*p) +
1517
+ ctx->gc_wire_ctx.len);
1518
+ if (!p)
1519
+ goto marshal_failed;
1520
+ *p++ = rpc_auth_gss;
15121521 cred_len = p++;
15131522
15141523 spin_lock(&ctx->gc_seq_lock);
1515
- req->rq_seqno = ctx->gc_seq++;
1524
+ req->rq_seqno = (ctx->gc_seq < MAXSEQ) ? ctx->gc_seq++ : MAXSEQ;
15161525 spin_unlock(&ctx->gc_seq_lock);
1526
+ if (req->rq_seqno == MAXSEQ)
1527
+ goto expired;
1528
+ trace_rpcgss_seqno(task);
15171529
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);
1530
+ *p++ = cpu_to_be32(RPC_GSS_VERSION);
1531
+ *p++ = cpu_to_be32(ctx->gc_proc);
1532
+ *p++ = cpu_to_be32(req->rq_seqno);
1533
+ *p++ = cpu_to_be32(gss_cred->gc_service);
15221534 p = xdr_encode_netobj(p, &ctx->gc_wire_ctx);
1523
- *cred_len = htonl((p - (cred_len + 1)) << 2);
1535
+ *cred_len = cpu_to_be32((p - (cred_len + 1)) << 2);
1536
+
1537
+ /* Verifier */
15241538
15251539 /* We compute the checksum for the verifier over the xdr-encoded bytes
15261540 * 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);
1541
+ iov.iov_base = req->rq_snd_buf.head[0].iov_base;
15291542 iov.iov_len = (u8 *)p - (u8 *)iov.iov_base;
15301543 xdr_buf_from_iov(&iov, &verf_buf);
15311544
1532
- /* set verifier flavor*/
1533
- *p++ = htonl(RPC_AUTH_GSS);
1534
-
1545
+ p = xdr_reserve_space(xdr, sizeof(*p));
1546
+ if (!p)
1547
+ goto marshal_failed;
1548
+ *p++ = rpc_auth_gss;
15351549 mic.data = (u8 *)(p + 1);
15361550 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);
1551
+ if (maj_stat == GSS_S_CONTEXT_EXPIRED)
1552
+ goto expired;
1553
+ else if (maj_stat != 0)
1554
+ goto bad_mic;
1555
+ if (xdr_stream_encode_opaque_inline(xdr, (void **)&p, mic.len) < 0)
1556
+ goto marshal_failed;
1557
+ status = 0;
1558
+out:
15441559 gss_put_ctx(ctx);
1545
- return p;
1546
-out_put_ctx:
1547
- gss_put_ctx(ctx);
1548
- return NULL;
1560
+ return status;
1561
+expired:
1562
+ clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
1563
+ status = -EKEYEXPIRED;
1564
+ goto out;
1565
+marshal_failed:
1566
+ status = -EMSGSIZE;
1567
+ goto out;
1568
+bad_mic:
1569
+ trace_rpcgss_get_mic(task, maj_stat);
1570
+ status = -EIO;
1571
+ goto out;
15491572 }
15501573
15511574 static int gss_renew_cred(struct rpc_task *task)
....@@ -1556,15 +1579,15 @@
15561579 gc_base);
15571580 struct rpc_auth *auth = oldcred->cr_auth;
15581581 struct auth_cred acred = {
1559
- .uid = oldcred->cr_uid,
1582
+ .cred = oldcred->cr_cred,
15601583 .principal = gss_cred->gc_principal,
1561
- .machine_cred = (gss_cred->gc_principal != NULL ? 1 : 0),
15621584 };
15631585 struct rpc_cred *new;
15641586
15651587 new = gss_lookup_cred(auth, &acred, RPCAUTH_LOOKUP_NEW);
15661588 if (IS_ERR(new))
15671589 return PTR_ERR(new);
1590
+
15681591 task->tk_rqstp->rq_cred = new;
15691592 put_rpccred(oldcred);
15701593 return 0;
....@@ -1620,116 +1643,107 @@
16201643 return 0;
16211644 }
16221645
1623
-static __be32 *
1624
-gss_validate(struct rpc_task *task, __be32 *p)
1646
+static int
1647
+gss_validate(struct rpc_task *task, struct xdr_stream *xdr)
16251648 {
16261649 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
16271650 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
1628
- __be32 *seq = NULL;
1651
+ __be32 *p, *seq = NULL;
16291652 struct kvec iov;
16301653 struct xdr_buf verf_buf;
16311654 struct xdr_netobj mic;
1632
- u32 flav,len;
1633
- u32 maj_stat;
1634
- __be32 *ret = ERR_PTR(-EIO);
1655
+ u32 len, maj_stat;
1656
+ int status;
16351657
1636
- dprintk("RPC: %5u %s\n", task->tk_pid, __func__);
1658
+ p = xdr_inline_decode(xdr, 2 * sizeof(*p));
1659
+ if (!p)
1660
+ goto validate_failed;
1661
+ if (*p++ != rpc_auth_gss)
1662
+ goto validate_failed;
1663
+ len = be32_to_cpup(p);
1664
+ if (len > RPC_MAX_AUTH_SIZE)
1665
+ goto validate_failed;
1666
+ p = xdr_inline_decode(xdr, len);
1667
+ if (!p)
1668
+ goto validate_failed;
16371669
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;
16431670 seq = kmalloc(4, GFP_NOFS);
16441671 if (!seq)
1645
- goto out_bad;
1646
- *seq = htonl(task->tk_rqstp->rq_seqno);
1672
+ goto validate_failed;
1673
+ *seq = cpu_to_be32(task->tk_rqstp->rq_seqno);
16471674 iov.iov_base = seq;
16481675 iov.iov_len = 4;
16491676 xdr_buf_from_iov(&iov, &verf_buf);
16501677 mic.data = (u8 *)p;
16511678 mic.len = len;
1652
-
1653
- ret = ERR_PTR(-EACCES);
16541679 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
16551680 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
16561681 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
- }
1682
+ if (maj_stat)
1683
+ goto bad_mic;
1684
+
16621685 /* We leave it to unwrap to calculate au_rslack. For now we just
16631686 * calculate the length of the verifier: */
1664
- cred->cr_auth->au_verfsize = XDR_QUADLEN(len) + 2;
1687
+ if (test_bit(RPCAUTH_AUTH_UPDATE_SLACK, &cred->cr_auth->au_flags))
1688
+ cred->cr_auth->au_verfsize = XDR_QUADLEN(len) + 2;
1689
+ status = 0;
1690
+out:
16651691 gss_put_ctx(ctx);
1666
- dprintk("RPC: %5u %s: gss_verify_mic succeeded.\n",
1667
- task->tk_pid, __func__);
16681692 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;
1693
+ return status;
1694
+
1695
+validate_failed:
1696
+ status = -EIO;
1697
+ goto out;
1698
+bad_mic:
1699
+ trace_rpcgss_verify_mic(task, maj_stat);
1700
+ status = -EACCES;
1701
+ goto out;
16761702 }
16771703
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
1704
+static noinline_for_stack int
16881705 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)
1706
+ struct rpc_task *task, struct xdr_stream *xdr)
16911707 {
1692
- struct xdr_buf *snd_buf = &rqstp->rq_snd_buf;
1693
- struct xdr_buf integ_buf;
1694
- __be32 *integ_len = NULL;
1708
+ struct rpc_rqst *rqstp = task->tk_rqstp;
1709
+ struct xdr_buf integ_buf, *snd_buf = &rqstp->rq_snd_buf;
16951710 struct xdr_netobj mic;
1696
- u32 offset;
1697
- __be32 *q;
1698
- struct kvec *iov;
1699
- u32 maj_stat = 0;
1700
- int status = -EIO;
1711
+ __be32 *p, *integ_len;
1712
+ u32 offset, maj_stat;
17011713
1714
+ p = xdr_reserve_space(xdr, 2 * sizeof(*p));
1715
+ if (!p)
1716
+ goto wrap_failed;
17021717 integ_len = p++;
1718
+ *p = cpu_to_be32(rqstp->rq_seqno);
1719
+
1720
+ if (rpcauth_wrap_req_encode(task, xdr))
1721
+ goto wrap_failed;
1722
+
17031723 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
-
17081724 if (xdr_buf_subsegment(snd_buf, &integ_buf,
17091725 offset, snd_buf->len - offset))
1710
- return status;
1711
- *integ_len = htonl(integ_buf.len);
1726
+ goto wrap_failed;
1727
+ *integ_len = cpu_to_be32(integ_buf.len);
17121728
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;
1729
+ p = xdr_reserve_space(xdr, 0);
1730
+ if (!p)
1731
+ goto wrap_failed;
17191732 mic.data = (u8 *)(p + 1);
1720
-
17211733 maj_stat = gss_get_mic(ctx->gc_gss_ctx, &integ_buf, &mic);
1722
- status = -EIO; /* XXX? */
17231734 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
17241735 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
17251736 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;
1737
+ goto bad_mic;
1738
+ /* Check that the trailing MIC fit in the buffer, after the fact */
1739
+ if (xdr_stream_encode_opaque_inline(xdr, (void **)&p, mic.len) < 0)
1740
+ goto wrap_failed;
17321741 return 0;
1742
+wrap_failed:
1743
+ return -EMSGSIZE;
1744
+bad_mic:
1745
+ trace_rpcgss_get_mic(task, maj_stat);
1746
+ return -EIO;
17331747 }
17341748
17351749 static void
....@@ -1780,224 +1794,348 @@
17801794 return -EAGAIN;
17811795 }
17821796
1783
-static inline int
1797
+static noinline_for_stack int
17841798 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)
1799
+ struct rpc_task *task, struct xdr_stream *xdr)
17871800 {
1801
+ struct rpc_rqst *rqstp = task->tk_rqstp;
17881802 struct xdr_buf *snd_buf = &rqstp->rq_snd_buf;
1789
- u32 offset;
1790
- u32 maj_stat;
1803
+ u32 pad, offset, maj_stat;
17911804 int status;
1792
- __be32 *opaque_len;
1805
+ __be32 *p, *opaque_len;
17931806 struct page **inpages;
17941807 int first;
1795
- int pad;
17961808 struct kvec *iov;
1797
- char *tmp;
17981809
1810
+ status = -EIO;
1811
+ p = xdr_reserve_space(xdr, 2 * sizeof(*p));
1812
+ if (!p)
1813
+ goto wrap_failed;
17991814 opaque_len = p++;
1800
- offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
1801
- *p++ = htonl(rqstp->rq_seqno);
1815
+ *p = cpu_to_be32(rqstp->rq_seqno);
18021816
1803
- gss_wrap_req_encode(encode, rqstp, p, obj);
1817
+ if (rpcauth_wrap_req_encode(task, xdr))
1818
+ goto wrap_failed;
18041819
18051820 status = alloc_enc_pages(rqstp);
1806
- if (status)
1807
- return status;
1821
+ if (unlikely(status))
1822
+ goto wrap_failed;
18081823 first = snd_buf->page_base >> PAGE_SHIFT;
18091824 inpages = snd_buf->pages + first;
18101825 snd_buf->pages = rqstp->rq_enc_pages;
18111826 snd_buf->page_base -= first << PAGE_SHIFT;
18121827 /*
1813
- * Give the tail its own page, in case we need extra space in the
1814
- * head when wrapping:
1828
+ * Move the tail into its own page, in case gss_wrap needs
1829
+ * more space in the head when wrapping.
18151830 *
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.
1831
+ * Still... Why can't gss_wrap just slide the tail down?
18191832 */
18201833 if (snd_buf->page_len || snd_buf->tail[0].iov_len) {
1834
+ char *tmp;
1835
+
18211836 tmp = page_address(rqstp->rq_enc_pages[rqstp->rq_enc_pages_num - 1]);
18221837 memcpy(tmp, snd_buf->tail[0].iov_base, snd_buf->tail[0].iov_len);
18231838 snd_buf->tail[0].iov_base = tmp;
18241839 }
1840
+ offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
18251841 maj_stat = gss_wrap(ctx->gc_gss_ctx, offset, snd_buf, inpages);
18261842 /* slack space should prevent this ever happening: */
1827
- BUG_ON(snd_buf->len > snd_buf->buflen);
1828
- status = -EIO;
1843
+ if (unlikely(snd_buf->len > snd_buf->buflen))
1844
+ goto wrap_failed;
18291845 /* We're assuming that when GSS_S_CONTEXT_EXPIRED, the encryption was
18301846 * done anyway, so it's safe to put the request on the wire: */
18311847 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
18321848 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
18331849 else if (maj_stat)
1834
- return status;
1850
+ goto bad_wrap;
18351851
1836
- *opaque_len = htonl(snd_buf->len - offset);
1837
- /* guess whether we're in the head or the tail: */
1852
+ *opaque_len = cpu_to_be32(snd_buf->len - offset);
1853
+ /* guess whether the pad goes into the head or the tail: */
18381854 if (snd_buf->page_len || snd_buf->tail[0].iov_len)
18391855 iov = snd_buf->tail;
18401856 else
18411857 iov = snd_buf->head;
18421858 p = iov->iov_base + iov->iov_len;
1843
- pad = 3 - ((snd_buf->len - offset - 1) & 3);
1859
+ pad = xdr_pad_size(snd_buf->len - offset);
18441860 memset(p, 0, pad);
18451861 iov->iov_len += pad;
18461862 snd_buf->len += pad;
18471863
18481864 return 0;
1865
+wrap_failed:
1866
+ return status;
1867
+bad_wrap:
1868
+ trace_rpcgss_wrap(task, maj_stat);
1869
+ return -EIO;
18491870 }
18501871
1851
-static int
1852
-gss_wrap_req(struct rpc_task *task,
1853
- kxdreproc_t encode, void *rqstp, __be32 *p, void *obj)
1872
+static int gss_wrap_req(struct rpc_task *task, struct xdr_stream *xdr)
18541873 {
18551874 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
18561875 struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
18571876 gc_base);
18581877 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
1859
- int status = -EIO;
1878
+ int status;
18601879
1861
- dprintk("RPC: %5u %s\n", task->tk_pid, __func__);
1880
+ status = -EIO;
18621881 if (ctx->gc_proc != RPC_GSS_PROC_DATA) {
18631882 /* The spec seems a little ambiguous here, but I think that not
18641883 * wrapping context destruction requests makes the most sense.
18651884 */
1866
- gss_wrap_req_encode(encode, rqstp, p, obj);
1867
- status = 0;
1885
+ status = rpcauth_wrap_req_encode(task, xdr);
18681886 goto out;
18691887 }
18701888 switch (gss_cred->gc_service) {
18711889 case RPC_GSS_SVC_NONE:
1872
- gss_wrap_req_encode(encode, rqstp, p, obj);
1873
- status = 0;
1890
+ status = rpcauth_wrap_req_encode(task, xdr);
18741891 break;
18751892 case RPC_GSS_SVC_INTEGRITY:
1876
- status = gss_wrap_req_integ(cred, ctx, encode, rqstp, p, obj);
1893
+ status = gss_wrap_req_integ(cred, ctx, task, xdr);
18771894 break;
18781895 case RPC_GSS_SVC_PRIVACY:
1879
- status = gss_wrap_req_priv(cred, ctx, encode, rqstp, p, obj);
1896
+ status = gss_wrap_req_priv(cred, ctx, task, xdr);
18801897 break;
1898
+ default:
1899
+ status = -EIO;
18811900 }
18821901 out:
18831902 gss_put_ctx(ctx);
1884
- dprintk("RPC: %5u %s returning %d\n", task->tk_pid, __func__, status);
18851903 return status;
18861904 }
18871905
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)
1906
+/**
1907
+ * gss_update_rslack - Possibly update RPC receive buffer size estimates
1908
+ * @task: rpc_task for incoming RPC Reply being unwrapped
1909
+ * @cred: controlling rpc_cred for @task
1910
+ * @before: XDR words needed before each RPC Reply message
1911
+ * @after: XDR words needed following each RPC Reply message
1912
+ *
1913
+ */
1914
+static void gss_update_rslack(struct rpc_task *task, struct rpc_cred *cred,
1915
+ unsigned int before, unsigned int after)
18911916 {
1892
- struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf;
1893
- struct xdr_buf integ_buf;
1917
+ struct rpc_auth *auth = cred->cr_auth;
1918
+
1919
+ if (test_and_clear_bit(RPCAUTH_AUTH_UPDATE_SLACK, &auth->au_flags)) {
1920
+ auth->au_ralign = auth->au_verfsize + before;
1921
+ auth->au_rslack = auth->au_verfsize + after;
1922
+ trace_rpcgss_update_slack(task, auth);
1923
+ }
1924
+}
1925
+
1926
+static int
1927
+gss_unwrap_resp_auth(struct rpc_task *task, struct rpc_cred *cred)
1928
+{
1929
+ gss_update_rslack(task, cred, 0, 0);
1930
+ return 0;
1931
+}
1932
+
1933
+/*
1934
+ * RFC 2203, Section 5.3.2.2
1935
+ *
1936
+ * struct rpc_gss_integ_data {
1937
+ * opaque databody_integ<>;
1938
+ * opaque checksum<>;
1939
+ * };
1940
+ *
1941
+ * struct rpc_gss_data_t {
1942
+ * unsigned int seq_num;
1943
+ * proc_req_arg_t arg;
1944
+ * };
1945
+ */
1946
+static noinline_for_stack int
1947
+gss_unwrap_resp_integ(struct rpc_task *task, struct rpc_cred *cred,
1948
+ struct gss_cl_ctx *ctx, struct rpc_rqst *rqstp,
1949
+ struct xdr_stream *xdr)
1950
+{
1951
+ struct xdr_buf gss_data, *rcv_buf = &rqstp->rq_rcv_buf;
1952
+ u32 len, offset, seqno, maj_stat;
18941953 struct xdr_netobj mic;
1895
- u32 data_offset, mic_offset;
1896
- u32 integ_len;
1897
- u32 maj_stat;
1898
- int status = -EIO;
1954
+ int ret;
18991955
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;
1956
+ ret = -EIO;
1957
+ mic.data = NULL;
19091958
1910
- if (xdr_buf_subsegment(rcv_buf, &integ_buf, data_offset,
1911
- mic_offset - data_offset))
1912
- return status;
1959
+ /* opaque databody_integ<>; */
1960
+ if (xdr_stream_decode_u32(xdr, &len))
1961
+ goto unwrap_failed;
1962
+ if (len & 3)
1963
+ goto unwrap_failed;
1964
+ offset = rcv_buf->len - xdr_stream_remaining(xdr);
1965
+ if (xdr_stream_decode_u32(xdr, &seqno))
1966
+ goto unwrap_failed;
1967
+ if (seqno != rqstp->rq_seqno)
1968
+ goto bad_seqno;
1969
+ if (xdr_buf_subsegment(rcv_buf, &gss_data, offset, len))
1970
+ goto unwrap_failed;
19131971
1914
- if (xdr_buf_read_netobj(rcv_buf, &mic, mic_offset))
1915
- return status;
1972
+ /*
1973
+ * The xdr_stream now points to the beginning of the
1974
+ * upper layer payload, to be passed below to
1975
+ * rpcauth_unwrap_resp_decode(). The checksum, which
1976
+ * follows the upper layer payload in @rcv_buf, is
1977
+ * located and parsed without updating the xdr_stream.
1978
+ */
19161979
1917
- maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &integ_buf, &mic);
1980
+ /* opaque checksum<>; */
1981
+ offset += len;
1982
+ if (xdr_decode_word(rcv_buf, offset, &len))
1983
+ goto unwrap_failed;
1984
+ offset += sizeof(__be32);
1985
+ if (offset + len > rcv_buf->len)
1986
+ goto unwrap_failed;
1987
+ mic.len = len;
1988
+ mic.data = kmalloc(len, GFP_NOFS);
1989
+ if (!mic.data)
1990
+ goto unwrap_failed;
1991
+ if (read_bytes_from_xdr_buf(rcv_buf, offset, mic.data, mic.len))
1992
+ goto unwrap_failed;
1993
+
1994
+ maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &gss_data, &mic);
19181995 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
19191996 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
19201997 if (maj_stat != GSS_S_COMPLETE)
1921
- return status;
1922
- return 0;
1998
+ goto bad_mic;
1999
+
2000
+ gss_update_rslack(task, cred, 2, 2 + 1 + XDR_QUADLEN(mic.len));
2001
+ ret = 0;
2002
+
2003
+out:
2004
+ kfree(mic.data);
2005
+ return ret;
2006
+
2007
+unwrap_failed:
2008
+ trace_rpcgss_unwrap_failed(task);
2009
+ goto out;
2010
+bad_seqno:
2011
+ trace_rpcgss_bad_seqno(task, rqstp->rq_seqno, seqno);
2012
+ goto out;
2013
+bad_mic:
2014
+ trace_rpcgss_verify_mic(task, maj_stat);
2015
+ goto out;
19232016 }
19242017
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)
2018
+static noinline_for_stack int
2019
+gss_unwrap_resp_priv(struct rpc_task *task, struct rpc_cred *cred,
2020
+ struct gss_cl_ctx *ctx, struct rpc_rqst *rqstp,
2021
+ struct xdr_stream *xdr)
19282022 {
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;
2023
+ struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf;
2024
+ struct kvec *head = rqstp->rq_rcv_buf.head;
2025
+ u32 offset, opaque_len, maj_stat;
2026
+ __be32 *p;
19342027
1935
- opaque_len = ntohl(*(*p)++);
1936
- offset = (u8 *)(*p) - (u8 *)rcv_buf->head[0].iov_base;
2028
+ p = xdr_inline_decode(xdr, 2 * sizeof(*p));
2029
+ if (unlikely(!p))
2030
+ goto unwrap_failed;
2031
+ opaque_len = be32_to_cpup(p++);
2032
+ offset = (u8 *)(p) - (u8 *)head->iov_base;
19372033 if (offset + opaque_len > rcv_buf->len)
1938
- return status;
1939
- /* remove padding: */
1940
- rcv_buf->len = offset + opaque_len;
2034
+ goto unwrap_failed;
19412035
1942
- maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset, rcv_buf);
2036
+ maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset,
2037
+ offset + opaque_len, rcv_buf);
19432038 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
19442039 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
19452040 if (maj_stat != GSS_S_COMPLETE)
1946
- return status;
1947
- if (ntohl(*(*p)++) != rqstp->rq_seqno)
1948
- return status;
2041
+ goto bad_unwrap;
2042
+ /* gss_unwrap decrypted the sequence number */
2043
+ if (be32_to_cpup(p++) != rqstp->rq_seqno)
2044
+ goto bad_seqno;
2045
+
2046
+ /* gss_unwrap redacts the opaque blob from the head iovec.
2047
+ * rcv_buf has changed, thus the stream needs to be reset.
2048
+ */
2049
+ xdr_init_decode(xdr, rcv_buf, p, rqstp);
2050
+
2051
+ gss_update_rslack(task, cred, 2 + ctx->gc_gss_ctx->align,
2052
+ 2 + ctx->gc_gss_ctx->slack);
19492053
19502054 return 0;
2055
+unwrap_failed:
2056
+ trace_rpcgss_unwrap_failed(task);
2057
+ return -EIO;
2058
+bad_seqno:
2059
+ trace_rpcgss_bad_seqno(task, rqstp->rq_seqno, be32_to_cpup(--p));
2060
+ return -EIO;
2061
+bad_unwrap:
2062
+ trace_rpcgss_unwrap(task, maj_stat);
2063
+ return -EIO;
2064
+}
2065
+
2066
+static bool
2067
+gss_seq_is_newer(u32 new, u32 old)
2068
+{
2069
+ return (s32)(new - old) > 0;
2070
+}
2071
+
2072
+static bool
2073
+gss_xmit_need_reencode(struct rpc_task *task)
2074
+{
2075
+ struct rpc_rqst *req = task->tk_rqstp;
2076
+ struct rpc_cred *cred = req->rq_cred;
2077
+ struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
2078
+ u32 win, seq_xmit = 0;
2079
+ bool ret = true;
2080
+
2081
+ if (!ctx)
2082
+ goto out;
2083
+
2084
+ if (gss_seq_is_newer(req->rq_seqno, READ_ONCE(ctx->gc_seq)))
2085
+ goto out_ctx;
2086
+
2087
+ seq_xmit = READ_ONCE(ctx->gc_seq_xmit);
2088
+ while (gss_seq_is_newer(req->rq_seqno, seq_xmit)) {
2089
+ u32 tmp = seq_xmit;
2090
+
2091
+ seq_xmit = cmpxchg(&ctx->gc_seq_xmit, tmp, req->rq_seqno);
2092
+ if (seq_xmit == tmp) {
2093
+ ret = false;
2094
+ goto out_ctx;
2095
+ }
2096
+ }
2097
+
2098
+ win = ctx->gc_win;
2099
+ if (win > 0)
2100
+ ret = !gss_seq_is_newer(req->rq_seqno, seq_xmit - win);
2101
+
2102
+out_ctx:
2103
+ gss_put_ctx(ctx);
2104
+out:
2105
+ trace_rpcgss_need_reencode(task, seq_xmit, ret);
2106
+ return ret;
19512107 }
19522108
19532109 static int
1954
-gss_unwrap_req_decode(kxdrdproc_t decode, struct rpc_rqst *rqstp,
1955
- __be32 *p, void *obj)
2110
+gss_unwrap_resp(struct rpc_task *task, struct xdr_stream *xdr)
19562111 {
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;
2112
+ struct rpc_rqst *rqstp = task->tk_rqstp;
2113
+ struct rpc_cred *cred = rqstp->rq_cred;
19682114 struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
19692115 gc_base);
19702116 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;
2117
+ int status = -EIO;
19752118
19762119 if (ctx->gc_proc != RPC_GSS_PROC_DATA)
19772120 goto out_decode;
19782121 switch (gss_cred->gc_service) {
19792122 case RPC_GSS_SVC_NONE:
2123
+ status = gss_unwrap_resp_auth(task, cred);
19802124 break;
19812125 case RPC_GSS_SVC_INTEGRITY:
1982
- status = gss_unwrap_resp_integ(cred, ctx, rqstp, &p);
1983
- if (status)
1984
- goto out;
2126
+ status = gss_unwrap_resp_integ(task, cred, ctx, rqstp, xdr);
19852127 break;
19862128 case RPC_GSS_SVC_PRIVACY:
1987
- status = gss_unwrap_resp_priv(cred, ctx, rqstp, &p);
1988
- if (status)
1989
- goto out;
2129
+ status = gss_unwrap_resp_priv(task, cred, ctx, rqstp, xdr);
19902130 break;
19912131 }
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);
2132
+ if (status)
2133
+ goto out;
2134
+
19952135 out_decode:
1996
- status = gss_unwrap_req_decode(decode, rqstp, p, obj);
2136
+ status = rpcauth_unwrap_resp_decode(task, xdr);
19972137 out:
19982138 gss_put_ctx(ctx);
1999
- dprintk("RPC: %5u %s returning %d\n",
2000
- task->tk_pid, __func__, status);
20012139 return status;
20022140 }
20032141
....@@ -2010,7 +2148,6 @@
20102148 .hash_cred = gss_hash_cred,
20112149 .lookup_cred = gss_lookup_cred,
20122150 .crcreate = gss_create_cred,
2013
- .list_pseudoflavors = gss_mech_list_pseudoflavors,
20142151 .info2flavor = gss_mech_info2flavor,
20152152 .flavor2info = gss_mech_flavor2info,
20162153 };
....@@ -2019,7 +2156,6 @@
20192156 .cr_name = "AUTH_GSS",
20202157 .crdestroy = gss_destroy_cred,
20212158 .cr_init = gss_cred_init,
2022
- .crbind = rpcauth_generic_bind_cred,
20232159 .crmatch = gss_match,
20242160 .crmarshal = gss_marshal,
20252161 .crrefresh = gss_refresh,
....@@ -2028,12 +2164,12 @@
20282164 .crunwrap_resp = gss_unwrap_resp,
20292165 .crkey_timeout = gss_key_timeout,
20302166 .crstringify_acceptor = gss_stringify_acceptor,
2167
+ .crneed_reencode = gss_xmit_need_reencode,
20312168 };
20322169
20332170 static const struct rpc_credops gss_nullops = {
20342171 .cr_name = "AUTH_GSS",
20352172 .crdestroy = gss_destroy_nullcred,
2036
- .crbind = rpcauth_generic_bind_cred,
20372173 .crmatch = gss_match,
20382174 .crmarshal = gss_marshal,
20392175 .crrefresh = gss_refresh_null,
....@@ -2044,7 +2180,7 @@
20442180 };
20452181
20462182 static const struct rpc_pipe_ops gss_upcall_ops_v0 = {
2047
- .upcall = rpc_pipe_generic_upcall,
2183
+ .upcall = gss_v0_upcall,
20482184 .downcall = gss_pipe_downcall,
20492185 .destroy_msg = gss_pipe_destroy_msg,
20502186 .open_pipe = gss_pipe_open_v0,
....@@ -2052,7 +2188,7 @@
20522188 };
20532189
20542190 static const struct rpc_pipe_ops gss_upcall_ops_v1 = {
2055
- .upcall = rpc_pipe_generic_upcall,
2191
+ .upcall = gss_v1_upcall,
20562192 .downcall = gss_pipe_downcall,
20572193 .destroy_msg = gss_pipe_destroy_msg,
20582194 .open_pipe = gss_pipe_open_v1,