aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2010-05-13 12:51:02 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2010-05-14 15:09:33 -0400
commit1f4c86c0be9064ab4eebd9e67c84606c1cfeec4b (patch)
tree6ae9e8e6550f644335bbf6812edd7e6cfcde7e53 /net/sunrpc
parent8535b2be5181fc3019e4150567ef53210fe3b04f (diff)
NFS: Don't use GFP_KERNEL in rpcsec_gss downcalls
Again, we can deadlock if the memory reclaim triggers a writeback that requires a rpcsec_gss credential lookup. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c2
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_keys.c9
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_mech.c34
-rw-r--r--net/sunrpc/auth_gss/gss_mech_switch.c7
-rw-r--r--net/sunrpc/auth_gss/gss_spkm3_mech.c5
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c2
6 files changed, 32 insertions, 27 deletions
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 6654c8534d3..48a7939dc9e 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -229,7 +229,7 @@ gss_fill_context(const void *p, const void *end, struct gss_cl_ctx *ctx, struct
229 p = ERR_PTR(-EFAULT); 229 p = ERR_PTR(-EFAULT);
230 goto err; 230 goto err;
231 } 231 }
232 ret = gss_import_sec_context(p, seclen, gm, &ctx->gc_gss_ctx); 232 ret = gss_import_sec_context(p, seclen, gm, &ctx->gc_gss_ctx, GFP_NOFS);
233 if (ret < 0) { 233 if (ret < 0) {
234 p = ERR_PTR(ret); 234 p = ERR_PTR(ret);
235 goto err; 235 goto err;
diff --git a/net/sunrpc/auth_gss/gss_krb5_keys.c b/net/sunrpc/auth_gss/gss_krb5_keys.c
index 33b87f04b30..76e42e6be75 100644
--- a/net/sunrpc/auth_gss/gss_krb5_keys.c
+++ b/net/sunrpc/auth_gss/gss_krb5_keys.c
@@ -150,7 +150,8 @@ static void krb5_nfold(u32 inbits, const u8 *in,
150u32 krb5_derive_key(const struct gss_krb5_enctype *gk5e, 150u32 krb5_derive_key(const struct gss_krb5_enctype *gk5e,
151 const struct xdr_netobj *inkey, 151 const struct xdr_netobj *inkey,
152 struct xdr_netobj *outkey, 152 struct xdr_netobj *outkey,
153 const struct xdr_netobj *in_constant) 153 const struct xdr_netobj *in_constant,
154 gfp_t gfp_mask)
154{ 155{
155 size_t blocksize, keybytes, keylength, n; 156 size_t blocksize, keybytes, keylength, n;
156 unsigned char *inblockdata, *outblockdata, *rawkey; 157 unsigned char *inblockdata, *outblockdata, *rawkey;
@@ -175,15 +176,15 @@ u32 krb5_derive_key(const struct gss_krb5_enctype *gk5e,
175 /* allocate and set up buffers */ 176 /* allocate and set up buffers */
176 177
177 ret = ENOMEM; 178 ret = ENOMEM;
178 inblockdata = kmalloc(blocksize, GFP_KERNEL); 179 inblockdata = kmalloc(blocksize, gfp_mask);
179 if (inblockdata == NULL) 180 if (inblockdata == NULL)
180 goto err_free_cipher; 181 goto err_free_cipher;
181 182
182 outblockdata = kmalloc(blocksize, GFP_KERNEL); 183 outblockdata = kmalloc(blocksize, gfp_mask);
183 if (outblockdata == NULL) 184 if (outblockdata == NULL)
184 goto err_free_in; 185 goto err_free_in;
185 186
186 rawkey = kmalloc(keybytes, GFP_KERNEL); 187 rawkey = kmalloc(keybytes, gfp_mask);
187 if (rawkey == NULL) 188 if (rawkey == NULL)
188 goto err_free_out; 189 goto err_free_out;
189 190
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
index 7c249a3f9a0..03264461052 100644
--- a/net/sunrpc/auth_gss/gss_krb5_mech.c
+++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
@@ -369,7 +369,7 @@ set_cdata(u8 cdata[GSS_KRB5_K5CLENGTH], u32 usage, u8 seed)
369} 369}
370 370
371static int 371static int
372context_derive_keys_des3(struct krb5_ctx *ctx) 372context_derive_keys_des3(struct krb5_ctx *ctx, gfp_t gfp_mask)
373{ 373{
374 struct xdr_netobj c, keyin, keyout; 374 struct xdr_netobj c, keyin, keyout;
375 u8 cdata[GSS_KRB5_K5CLENGTH]; 375 u8 cdata[GSS_KRB5_K5CLENGTH];
@@ -396,7 +396,7 @@ context_derive_keys_des3(struct krb5_ctx *ctx)
396 /* derive cksum */ 396 /* derive cksum */
397 set_cdata(cdata, KG_USAGE_SIGN, KEY_USAGE_SEED_CHECKSUM); 397 set_cdata(cdata, KG_USAGE_SIGN, KEY_USAGE_SEED_CHECKSUM);
398 keyout.data = ctx->cksum; 398 keyout.data = ctx->cksum;
399 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c); 399 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask);
400 if (err) { 400 if (err) {
401 dprintk("%s: Error %d deriving cksum key\n", 401 dprintk("%s: Error %d deriving cksum key\n",
402 __func__, err); 402 __func__, err);
@@ -487,7 +487,7 @@ out_err:
487} 487}
488 488
489static int 489static int
490context_derive_keys_new(struct krb5_ctx *ctx) 490context_derive_keys_new(struct krb5_ctx *ctx, gfp_t gfp_mask)
491{ 491{
492 struct xdr_netobj c, keyin, keyout; 492 struct xdr_netobj c, keyin, keyout;
493 u8 cdata[GSS_KRB5_K5CLENGTH]; 493 u8 cdata[GSS_KRB5_K5CLENGTH];
@@ -503,7 +503,7 @@ context_derive_keys_new(struct krb5_ctx *ctx)
503 /* initiator seal encryption */ 503 /* initiator seal encryption */
504 set_cdata(cdata, KG_USAGE_INITIATOR_SEAL, KEY_USAGE_SEED_ENCRYPTION); 504 set_cdata(cdata, KG_USAGE_INITIATOR_SEAL, KEY_USAGE_SEED_ENCRYPTION);
505 keyout.data = ctx->initiator_seal; 505 keyout.data = ctx->initiator_seal;
506 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c); 506 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask);
507 if (err) { 507 if (err) {
508 dprintk("%s: Error %d deriving initiator_seal key\n", 508 dprintk("%s: Error %d deriving initiator_seal key\n",
509 __func__, err); 509 __func__, err);
@@ -518,7 +518,7 @@ context_derive_keys_new(struct krb5_ctx *ctx)
518 /* acceptor seal encryption */ 518 /* acceptor seal encryption */
519 set_cdata(cdata, KG_USAGE_ACCEPTOR_SEAL, KEY_USAGE_SEED_ENCRYPTION); 519 set_cdata(cdata, KG_USAGE_ACCEPTOR_SEAL, KEY_USAGE_SEED_ENCRYPTION);
520 keyout.data = ctx->acceptor_seal; 520 keyout.data = ctx->acceptor_seal;
521 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c); 521 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask);
522 if (err) { 522 if (err) {
523 dprintk("%s: Error %d deriving acceptor_seal key\n", 523 dprintk("%s: Error %d deriving acceptor_seal key\n",
524 __func__, err); 524 __func__, err);
@@ -533,7 +533,7 @@ context_derive_keys_new(struct krb5_ctx *ctx)
533 /* initiator sign checksum */ 533 /* initiator sign checksum */
534 set_cdata(cdata, KG_USAGE_INITIATOR_SIGN, KEY_USAGE_SEED_CHECKSUM); 534 set_cdata(cdata, KG_USAGE_INITIATOR_SIGN, KEY_USAGE_SEED_CHECKSUM);
535 keyout.data = ctx->initiator_sign; 535 keyout.data = ctx->initiator_sign;
536 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c); 536 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask);
537 if (err) { 537 if (err) {
538 dprintk("%s: Error %d deriving initiator_sign key\n", 538 dprintk("%s: Error %d deriving initiator_sign key\n",
539 __func__, err); 539 __func__, err);
@@ -543,7 +543,7 @@ context_derive_keys_new(struct krb5_ctx *ctx)
543 /* acceptor sign checksum */ 543 /* acceptor sign checksum */
544 set_cdata(cdata, KG_USAGE_ACCEPTOR_SIGN, KEY_USAGE_SEED_CHECKSUM); 544 set_cdata(cdata, KG_USAGE_ACCEPTOR_SIGN, KEY_USAGE_SEED_CHECKSUM);
545 keyout.data = ctx->acceptor_sign; 545 keyout.data = ctx->acceptor_sign;
546 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c); 546 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask);
547 if (err) { 547 if (err) {
548 dprintk("%s: Error %d deriving acceptor_sign key\n", 548 dprintk("%s: Error %d deriving acceptor_sign key\n",
549 __func__, err); 549 __func__, err);
@@ -553,7 +553,7 @@ context_derive_keys_new(struct krb5_ctx *ctx)
553 /* initiator seal integrity */ 553 /* initiator seal integrity */
554 set_cdata(cdata, KG_USAGE_INITIATOR_SEAL, KEY_USAGE_SEED_INTEGRITY); 554 set_cdata(cdata, KG_USAGE_INITIATOR_SEAL, KEY_USAGE_SEED_INTEGRITY);
555 keyout.data = ctx->initiator_integ; 555 keyout.data = ctx->initiator_integ;
556 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c); 556 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask);
557 if (err) { 557 if (err) {
558 dprintk("%s: Error %d deriving initiator_integ key\n", 558 dprintk("%s: Error %d deriving initiator_integ key\n",
559 __func__, err); 559 __func__, err);
@@ -563,7 +563,7 @@ context_derive_keys_new(struct krb5_ctx *ctx)
563 /* acceptor seal integrity */ 563 /* acceptor seal integrity */
564 set_cdata(cdata, KG_USAGE_ACCEPTOR_SEAL, KEY_USAGE_SEED_INTEGRITY); 564 set_cdata(cdata, KG_USAGE_ACCEPTOR_SEAL, KEY_USAGE_SEED_INTEGRITY);
565 keyout.data = ctx->acceptor_integ; 565 keyout.data = ctx->acceptor_integ;
566 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c); 566 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask);
567 if (err) { 567 if (err) {
568 dprintk("%s: Error %d deriving acceptor_integ key\n", 568 dprintk("%s: Error %d deriving acceptor_integ key\n",
569 __func__, err); 569 __func__, err);
@@ -598,7 +598,8 @@ out_err:
598} 598}
599 599
600static int 600static int
601gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx) 601gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx,
602 gfp_t gfp_mask)
602{ 603{
603 int keylen; 604 int keylen;
604 605
@@ -645,7 +646,7 @@ gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx)
645 } 646 }
646 647
647 ctx->mech_used.data = kmemdup(gss_kerberos_mech.gm_oid.data, 648 ctx->mech_used.data = kmemdup(gss_kerberos_mech.gm_oid.data,
648 gss_kerberos_mech.gm_oid.len, GFP_KERNEL); 649 gss_kerberos_mech.gm_oid.len, gfp_mask);
649 if (unlikely(ctx->mech_used.data == NULL)) { 650 if (unlikely(ctx->mech_used.data == NULL)) {
650 p = ERR_PTR(-ENOMEM); 651 p = ERR_PTR(-ENOMEM);
651 goto out_err; 652 goto out_err;
@@ -654,12 +655,12 @@ gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx)
654 655
655 switch (ctx->enctype) { 656 switch (ctx->enctype) {
656 case ENCTYPE_DES3_CBC_RAW: 657 case ENCTYPE_DES3_CBC_RAW:
657 return context_derive_keys_des3(ctx); 658 return context_derive_keys_des3(ctx, gfp_mask);
658 case ENCTYPE_ARCFOUR_HMAC: 659 case ENCTYPE_ARCFOUR_HMAC:
659 return context_derive_keys_rc4(ctx); 660 return context_derive_keys_rc4(ctx);
660 case ENCTYPE_AES128_CTS_HMAC_SHA1_96: 661 case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
661 case ENCTYPE_AES256_CTS_HMAC_SHA1_96: 662 case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
662 return context_derive_keys_new(ctx); 663 return context_derive_keys_new(ctx, gfp_mask);
663 default: 664 default:
664 return -EINVAL; 665 return -EINVAL;
665 } 666 }
@@ -670,20 +671,21 @@ out_err:
670 671
671static int 672static int
672gss_import_sec_context_kerberos(const void *p, size_t len, 673gss_import_sec_context_kerberos(const void *p, size_t len,
673 struct gss_ctx *ctx_id) 674 struct gss_ctx *ctx_id,
675 gfp_t gfp_mask)
674{ 676{
675 const void *end = (const void *)((const char *)p + len); 677 const void *end = (const void *)((const char *)p + len);
676 struct krb5_ctx *ctx; 678 struct krb5_ctx *ctx;
677 int ret; 679 int ret;
678 680
679 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 681 ctx = kzalloc(sizeof(*ctx), gfp_mask);
680 if (ctx == NULL) 682 if (ctx == NULL)
681 return -ENOMEM; 683 return -ENOMEM;
682 684
683 if (len == 85) 685 if (len == 85)
684 ret = gss_import_v1_context(p, end, ctx); 686 ret = gss_import_v1_context(p, end, ctx);
685 else 687 else
686 ret = gss_import_v2_context(p, end, ctx); 688 ret = gss_import_v2_context(p, end, ctx, gfp_mask);
687 689
688 if (ret == 0) 690 if (ret == 0)
689 ctx_id->internal_ctx_id = ctx; 691 ctx_id->internal_ctx_id = ctx;
diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c
index 28a84ef41d1..2689de39dc7 100644
--- a/net/sunrpc/auth_gss/gss_mech_switch.c
+++ b/net/sunrpc/auth_gss/gss_mech_switch.c
@@ -249,14 +249,15 @@ EXPORT_SYMBOL_GPL(gss_mech_put);
249int 249int
250gss_import_sec_context(const void *input_token, size_t bufsize, 250gss_import_sec_context(const void *input_token, size_t bufsize,
251 struct gss_api_mech *mech, 251 struct gss_api_mech *mech,
252 struct gss_ctx **ctx_id) 252 struct gss_ctx **ctx_id,
253 gfp_t gfp_mask)
253{ 254{
254 if (!(*ctx_id = kzalloc(sizeof(**ctx_id), GFP_KERNEL))) 255 if (!(*ctx_id = kzalloc(sizeof(**ctx_id), gfp_mask)))
255 return -ENOMEM; 256 return -ENOMEM;
256 (*ctx_id)->mech_type = gss_mech_get(mech); 257 (*ctx_id)->mech_type = gss_mech_get(mech);
257 258
258 return mech->gm_ops 259 return mech->gm_ops
259 ->gss_import_sec_context(input_token, bufsize, *ctx_id); 260 ->gss_import_sec_context(input_token, bufsize, *ctx_id, gfp_mask);
260} 261}
261 262
262/* gss_get_mic: compute a mic over message and return mic_token. */ 263/* gss_get_mic: compute a mic over message and return mic_token. */
diff --git a/net/sunrpc/auth_gss/gss_spkm3_mech.c b/net/sunrpc/auth_gss/gss_spkm3_mech.c
index 035e1dd6af1..dc3f1f5ed86 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_mech.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_mech.c
@@ -84,13 +84,14 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res)
84 84
85static int 85static int
86gss_import_sec_context_spkm3(const void *p, size_t len, 86gss_import_sec_context_spkm3(const void *p, size_t len,
87 struct gss_ctx *ctx_id) 87 struct gss_ctx *ctx_id,
88 gfp_t gfp_mask)
88{ 89{
89 const void *end = (const void *)((const char *)p + len); 90 const void *end = (const void *)((const char *)p + len);
90 struct spkm3_ctx *ctx; 91 struct spkm3_ctx *ctx;
91 int version; 92 int version;
92 93
93 if (!(ctx = kzalloc(sizeof(*ctx), GFP_NOFS))) 94 if (!(ctx = kzalloc(sizeof(*ctx), gfp_mask)))
94 goto out_err; 95 goto out_err;
95 96
96 p = simple_get_bytes(p, end, &version, sizeof(version)); 97 p = simple_get_bytes(p, end, &version, sizeof(version));
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 1d9ac4ac818..cc385b3a59c 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -494,7 +494,7 @@ static int rsc_parse(struct cache_detail *cd,
494 len = qword_get(&mesg, buf, mlen); 494 len = qword_get(&mesg, buf, mlen);
495 if (len < 0) 495 if (len < 0)
496 goto out; 496 goto out;
497 status = gss_import_sec_context(buf, len, gm, &rsci.mechctx); 497 status = gss_import_sec_context(buf, len, gm, &rsci.mechctx, GFP_KERNEL);
498 if (status) 498 if (status)
499 goto out; 499 goto out;
500 500