aboutsummaryrefslogtreecommitdiffstats
path: root/net/rxrpc
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2014-07-18 13:56:36 -0400
committerDavid Howells <dhowells@redhat.com>2014-07-22 16:46:41 -0400
commit8a7a3eb4ddbe7c7e639170a64adede7cbd5a9247 (patch)
tree47bcf8f2a0b98fba79953dc9a1fac719381a8bfa /net/rxrpc
parentd46d494214cabfd03eb836e3a8ff3768d4c51497 (diff)
KEYS: RxRPC: Use key preparsing
Make use of key preparsing in the RxRPC protocol so that quota size determination can take place prior to keyring locking when a key is being added. Signed-off-by: David Howells <dhowells@redhat.com> Acked-by: Steve Dickson <steved@redhat.com>
Diffstat (limited to 'net/rxrpc')
-rw-r--r--net/rxrpc/ar-key.c165
1 files changed, 97 insertions, 68 deletions
diff --git a/net/rxrpc/ar-key.c b/net/rxrpc/ar-key.c
index 0ad080790a32..3907add75932 100644
--- a/net/rxrpc/ar-key.c
+++ b/net/rxrpc/ar-key.c
@@ -26,8 +26,10 @@
26#include "ar-internal.h" 26#include "ar-internal.h"
27 27
28static int rxrpc_vet_description_s(const char *); 28static int rxrpc_vet_description_s(const char *);
29static int rxrpc_instantiate(struct key *, struct key_preparsed_payload *); 29static int rxrpc_preparse(struct key_preparsed_payload *);
30static int rxrpc_instantiate_s(struct key *, struct key_preparsed_payload *); 30static int rxrpc_preparse_s(struct key_preparsed_payload *);
31static void rxrpc_free_preparse(struct key_preparsed_payload *);
32static void rxrpc_free_preparse_s(struct key_preparsed_payload *);
31static void rxrpc_destroy(struct key *); 33static void rxrpc_destroy(struct key *);
32static void rxrpc_destroy_s(struct key *); 34static void rxrpc_destroy_s(struct key *);
33static void rxrpc_describe(const struct key *, struct seq_file *); 35static void rxrpc_describe(const struct key *, struct seq_file *);
@@ -39,7 +41,9 @@ static long rxrpc_read(const struct key *, char __user *, size_t);
39 */ 41 */
40struct key_type key_type_rxrpc = { 42struct key_type key_type_rxrpc = {
41 .name = "rxrpc", 43 .name = "rxrpc",
42 .instantiate = rxrpc_instantiate, 44 .preparse = rxrpc_preparse,
45 .free_preparse = rxrpc_free_preparse,
46 .instantiate = generic_key_instantiate,
43 .match = user_match, 47 .match = user_match,
44 .destroy = rxrpc_destroy, 48 .destroy = rxrpc_destroy,
45 .describe = rxrpc_describe, 49 .describe = rxrpc_describe,
@@ -54,7 +58,9 @@ EXPORT_SYMBOL(key_type_rxrpc);
54struct key_type key_type_rxrpc_s = { 58struct key_type key_type_rxrpc_s = {
55 .name = "rxrpc_s", 59 .name = "rxrpc_s",
56 .vet_description = rxrpc_vet_description_s, 60 .vet_description = rxrpc_vet_description_s,
57 .instantiate = rxrpc_instantiate_s, 61 .preparse = rxrpc_preparse_s,
62 .free_preparse = rxrpc_free_preparse_s,
63 .instantiate = generic_key_instantiate,
58 .match = user_match, 64 .match = user_match,
59 .destroy = rxrpc_destroy_s, 65 .destroy = rxrpc_destroy_s,
60 .describe = rxrpc_describe, 66 .describe = rxrpc_describe,
@@ -81,13 +87,13 @@ static int rxrpc_vet_description_s(const char *desc)
81 * parse an RxKAD type XDR format token 87 * parse an RxKAD type XDR format token
82 * - the caller guarantees we have at least 4 words 88 * - the caller guarantees we have at least 4 words
83 */ 89 */
84static int rxrpc_instantiate_xdr_rxkad(struct key *key, const __be32 *xdr, 90static int rxrpc_preparse_xdr_rxkad(struct key_preparsed_payload *prep,
85 unsigned int toklen) 91 size_t datalen,
92 const __be32 *xdr, unsigned int toklen)
86{ 93{
87 struct rxrpc_key_token *token, **pptoken; 94 struct rxrpc_key_token *token, **pptoken;
88 size_t plen; 95 size_t plen;
89 u32 tktlen; 96 u32 tktlen;
90 int ret;
91 97
92 _enter(",{%x,%x,%x,%x},%u", 98 _enter(",{%x,%x,%x,%x},%u",
93 ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]), 99 ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]),
@@ -103,9 +109,7 @@ static int rxrpc_instantiate_xdr_rxkad(struct key *key, const __be32 *xdr,
103 return -EKEYREJECTED; 109 return -EKEYREJECTED;
104 110
105 plen = sizeof(*token) + sizeof(*token->kad) + tktlen; 111 plen = sizeof(*token) + sizeof(*token->kad) + tktlen;
106 ret = key_payload_reserve(key, key->datalen + plen); 112 prep->quotalen = datalen + plen;
107 if (ret < 0)
108 return ret;
109 113
110 plen -= sizeof(*token); 114 plen -= sizeof(*token);
111 token = kzalloc(sizeof(*token), GFP_KERNEL); 115 token = kzalloc(sizeof(*token), GFP_KERNEL);
@@ -146,16 +150,16 @@ static int rxrpc_instantiate_xdr_rxkad(struct key *key, const __be32 *xdr,
146 token->kad->ticket[6], token->kad->ticket[7]); 150 token->kad->ticket[6], token->kad->ticket[7]);
147 151
148 /* count the number of tokens attached */ 152 /* count the number of tokens attached */
149 key->type_data.x[0]++; 153 prep->type_data[0] = (void *)((unsigned long)prep->type_data[0] + 1);
150 154
151 /* attach the data */ 155 /* attach the data */
152 for (pptoken = (struct rxrpc_key_token **)&key->payload.data; 156 for (pptoken = (struct rxrpc_key_token **)&prep->payload[0];
153 *pptoken; 157 *pptoken;
154 pptoken = &(*pptoken)->next) 158 pptoken = &(*pptoken)->next)
155 continue; 159 continue;
156 *pptoken = token; 160 *pptoken = token;
157 if (token->kad->expiry < key->expiry) 161 if (token->kad->expiry < prep->expiry)
158 key->expiry = token->kad->expiry; 162 prep->expiry = token->kad->expiry;
159 163
160 _leave(" = 0"); 164 _leave(" = 0");
161 return 0; 165 return 0;
@@ -418,8 +422,9 @@ static int rxrpc_krb5_decode_ticket(u8 **_ticket, u16 *_tktlen,
418 * parse an RxK5 type XDR format token 422 * parse an RxK5 type XDR format token
419 * - the caller guarantees we have at least 4 words 423 * - the caller guarantees we have at least 4 words
420 */ 424 */
421static int rxrpc_instantiate_xdr_rxk5(struct key *key, const __be32 *xdr, 425static int rxrpc_preparse_xdr_rxk5(struct key_preparsed_payload *prep,
422 unsigned int toklen) 426 size_t datalen,
427 const __be32 *xdr, unsigned int toklen)
423{ 428{
424 struct rxrpc_key_token *token, **pptoken; 429 struct rxrpc_key_token *token, **pptoken;
425 struct rxk5_key *rxk5; 430 struct rxk5_key *rxk5;
@@ -432,9 +437,7 @@ static int rxrpc_instantiate_xdr_rxk5(struct key *key, const __be32 *xdr,
432 437
433 /* reserve some payload space for this subkey - the length of the token 438 /* reserve some payload space for this subkey - the length of the token
434 * is a reasonable approximation */ 439 * is a reasonable approximation */
435 ret = key_payload_reserve(key, key->datalen + toklen); 440 prep->quotalen = datalen + toklen;
436 if (ret < 0)
437 return ret;
438 441
439 token = kzalloc(sizeof(*token), GFP_KERNEL); 442 token = kzalloc(sizeof(*token), GFP_KERNEL);
440 if (!token) 443 if (!token)
@@ -520,14 +523,14 @@ static int rxrpc_instantiate_xdr_rxk5(struct key *key, const __be32 *xdr,
520 if (toklen != 0) 523 if (toklen != 0)
521 goto inval; 524 goto inval;
522 525
523 /* attach the payload to the key */ 526 /* attach the payload */
524 for (pptoken = (struct rxrpc_key_token **)&key->payload.data; 527 for (pptoken = (struct rxrpc_key_token **)&prep->payload[0];
525 *pptoken; 528 *pptoken;
526 pptoken = &(*pptoken)->next) 529 pptoken = &(*pptoken)->next)
527 continue; 530 continue;
528 *pptoken = token; 531 *pptoken = token;
529 if (token->kad->expiry < key->expiry) 532 if (token->kad->expiry < prep->expiry)
530 key->expiry = token->kad->expiry; 533 prep->expiry = token->kad->expiry;
531 534
532 _leave(" = 0"); 535 _leave(" = 0");
533 return 0; 536 return 0;
@@ -545,16 +548,17 @@ error:
545 * attempt to parse the data as the XDR format 548 * attempt to parse the data as the XDR format
546 * - the caller guarantees we have more than 7 words 549 * - the caller guarantees we have more than 7 words
547 */ 550 */
548static int rxrpc_instantiate_xdr(struct key *key, const void *data, size_t datalen) 551static int rxrpc_preparse_xdr(struct key_preparsed_payload *prep)
549{ 552{
550 const __be32 *xdr = data, *token; 553 const __be32 *xdr = prep->data, *token;
551 const char *cp; 554 const char *cp;
552 unsigned int len, tmp, loop, ntoken, toklen, sec_ix; 555 unsigned int len, tmp, loop, ntoken, toklen, sec_ix;
556 size_t datalen = prep->datalen;
553 int ret; 557 int ret;
554 558
555 _enter(",{%x,%x,%x,%x},%zu", 559 _enter(",{%x,%x,%x,%x},%zu",
556 ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]), 560 ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]),
557 datalen); 561 prep->datalen);
558 562
559 if (datalen > AFSTOKEN_LENGTH_MAX) 563 if (datalen > AFSTOKEN_LENGTH_MAX)
560 goto not_xdr; 564 goto not_xdr;
@@ -635,13 +639,13 @@ static int rxrpc_instantiate_xdr(struct key *key, const void *data, size_t datal
635 639
636 switch (sec_ix) { 640 switch (sec_ix) {
637 case RXRPC_SECURITY_RXKAD: 641 case RXRPC_SECURITY_RXKAD:
638 ret = rxrpc_instantiate_xdr_rxkad(key, xdr, toklen); 642 ret = rxrpc_preparse_xdr_rxkad(prep, datalen, xdr, toklen);
639 if (ret != 0) 643 if (ret != 0)
640 goto error; 644 goto error;
641 break; 645 break;
642 646
643 case RXRPC_SECURITY_RXK5: 647 case RXRPC_SECURITY_RXK5:
644 ret = rxrpc_instantiate_xdr_rxk5(key, xdr, toklen); 648 ret = rxrpc_preparse_xdr_rxk5(prep, datalen, xdr, toklen);
645 if (ret != 0) 649 if (ret != 0)
646 goto error; 650 goto error;
647 break; 651 break;
@@ -665,8 +669,9 @@ error:
665} 669}
666 670
667/* 671/*
668 * instantiate an rxrpc defined key 672 * Preparse an rxrpc defined key.
669 * data should be of the form: 673 *
674 * Data should be of the form:
670 * OFFSET LEN CONTENT 675 * OFFSET LEN CONTENT
671 * 0 4 key interface version number 676 * 0 4 key interface version number
672 * 4 2 security index (type) 677 * 4 2 security index (type)
@@ -678,7 +683,7 @@ error:
678 * 683 *
679 * if no data is provided, then a no-security key is made 684 * if no data is provided, then a no-security key is made
680 */ 685 */
681static int rxrpc_instantiate(struct key *key, struct key_preparsed_payload *prep) 686static int rxrpc_preparse(struct key_preparsed_payload *prep)
682{ 687{
683 const struct rxrpc_key_data_v1 *v1; 688 const struct rxrpc_key_data_v1 *v1;
684 struct rxrpc_key_token *token, **pp; 689 struct rxrpc_key_token *token, **pp;
@@ -686,7 +691,7 @@ static int rxrpc_instantiate(struct key *key, struct key_preparsed_payload *prep
686 u32 kver; 691 u32 kver;
687 int ret; 692 int ret;
688 693
689 _enter("{%x},,%zu", key_serial(key), prep->datalen); 694 _enter("%zu", prep->datalen);
690 695
691 /* handle a no-security key */ 696 /* handle a no-security key */
692 if (!prep->data && prep->datalen == 0) 697 if (!prep->data && prep->datalen == 0)
@@ -694,7 +699,7 @@ static int rxrpc_instantiate(struct key *key, struct key_preparsed_payload *prep
694 699
695 /* determine if the XDR payload format is being used */ 700 /* determine if the XDR payload format is being used */
696 if (prep->datalen > 7 * 4) { 701 if (prep->datalen > 7 * 4) {
697 ret = rxrpc_instantiate_xdr(key, prep->data, prep->datalen); 702 ret = rxrpc_preparse_xdr(prep);
698 if (ret != -EPROTO) 703 if (ret != -EPROTO)
699 return ret; 704 return ret;
700 } 705 }
@@ -743,9 +748,7 @@ static int rxrpc_instantiate(struct key *key, struct key_preparsed_payload *prep
743 goto error; 748 goto error;
744 749
745 plen = sizeof(*token->kad) + v1->ticket_length; 750 plen = sizeof(*token->kad) + v1->ticket_length;
746 ret = key_payload_reserve(key, plen + sizeof(*token)); 751 prep->quotalen = plen + sizeof(*token);
747 if (ret < 0)
748 goto error;
749 752
750 ret = -ENOMEM; 753 ret = -ENOMEM;
751 token = kzalloc(sizeof(*token), GFP_KERNEL); 754 token = kzalloc(sizeof(*token), GFP_KERNEL);
@@ -762,15 +765,16 @@ static int rxrpc_instantiate(struct key *key, struct key_preparsed_payload *prep
762 memcpy(&token->kad->session_key, &v1->session_key, 8); 765 memcpy(&token->kad->session_key, &v1->session_key, 8);
763 memcpy(&token->kad->ticket, v1->ticket, v1->ticket_length); 766 memcpy(&token->kad->ticket, v1->ticket, v1->ticket_length);
764 767
765 /* attach the data */ 768 /* count the number of tokens attached */
766 key->type_data.x[0]++; 769 prep->type_data[0] = (void *)((unsigned long)prep->type_data[0] + 1);
767 770
768 pp = (struct rxrpc_key_token **)&key->payload.data; 771 /* attach the data */
772 pp = (struct rxrpc_key_token **)&prep->payload[0];
769 while (*pp) 773 while (*pp)
770 pp = &(*pp)->next; 774 pp = &(*pp)->next;
771 *pp = token; 775 *pp = token;
772 if (token->kad->expiry < key->expiry) 776 if (token->kad->expiry < prep->expiry)
773 key->expiry = token->kad->expiry; 777 prep->expiry = token->kad->expiry;
774 token = NULL; 778 token = NULL;
775 ret = 0; 779 ret = 0;
776 780
@@ -781,20 +785,55 @@ error:
781} 785}
782 786
783/* 787/*
784 * instantiate a server secret key 788 * Free token list.
785 * data should be a pointer to the 8-byte secret key
786 */ 789 */
787static int rxrpc_instantiate_s(struct key *key, 790static void rxrpc_free_token_list(struct rxrpc_key_token *token)
788 struct key_preparsed_payload *prep) 791{
792 struct rxrpc_key_token *next;
793
794 for (; token; token = next) {
795 next = token->next;
796 switch (token->security_index) {
797 case RXRPC_SECURITY_RXKAD:
798 kfree(token->kad);
799 break;
800 case RXRPC_SECURITY_RXK5:
801 if (token->k5)
802 rxrpc_rxk5_free(token->k5);
803 break;
804 default:
805 printk(KERN_ERR "Unknown token type %x on rxrpc key\n",
806 token->security_index);
807 BUG();
808 }
809
810 kfree(token);
811 }
812}
813
814/*
815 * Clean up preparse data.
816 */
817static void rxrpc_free_preparse(struct key_preparsed_payload *prep)
818{
819 rxrpc_free_token_list(prep->payload[0]);
820}
821
822/*
823 * Preparse a server secret key.
824 *
825 * The data should be the 8-byte secret key.
826 */
827static int rxrpc_preparse_s(struct key_preparsed_payload *prep)
789{ 828{
790 struct crypto_blkcipher *ci; 829 struct crypto_blkcipher *ci;
791 830
792 _enter("{%x},,%zu", key_serial(key), prep->datalen); 831 _enter("%zu", prep->datalen);
793 832
794 if (prep->datalen != 8) 833 if (prep->datalen != 8)
795 return -EINVAL; 834 return -EINVAL;
796 835
797 memcpy(&key->type_data, prep->data, 8); 836 memcpy(&prep->type_data, prep->data, 8);
798 837
799 ci = crypto_alloc_blkcipher("pcbc(des)", 0, CRYPTO_ALG_ASYNC); 838 ci = crypto_alloc_blkcipher("pcbc(des)", 0, CRYPTO_ALG_ASYNC);
800 if (IS_ERR(ci)) { 839 if (IS_ERR(ci)) {
@@ -805,36 +844,26 @@ static int rxrpc_instantiate_s(struct key *key,
805 if (crypto_blkcipher_setkey(ci, prep->data, 8) < 0) 844 if (crypto_blkcipher_setkey(ci, prep->data, 8) < 0)
806 BUG(); 845 BUG();
807 846
808 key->payload.data = ci; 847 prep->payload[0] = ci;
809 _leave(" = 0"); 848 _leave(" = 0");
810 return 0; 849 return 0;
811} 850}
812 851
813/* 852/*
853 * Clean up preparse data.
854 */
855static void rxrpc_free_preparse_s(struct key_preparsed_payload *prep)
856{
857 if (prep->payload[0])
858 crypto_free_blkcipher(prep->payload[0]);
859}
860
861/*
814 * dispose of the data dangling from the corpse of a rxrpc key 862 * dispose of the data dangling from the corpse of a rxrpc key
815 */ 863 */
816static void rxrpc_destroy(struct key *key) 864static void rxrpc_destroy(struct key *key)
817{ 865{
818 struct rxrpc_key_token *token; 866 rxrpc_free_token_list(key->payload.data);
819
820 while ((token = key->payload.data)) {
821 key->payload.data = token->next;
822 switch (token->security_index) {
823 case RXRPC_SECURITY_RXKAD:
824 kfree(token->kad);
825 break;
826 case RXRPC_SECURITY_RXK5:
827 if (token->k5)
828 rxrpc_rxk5_free(token->k5);
829 break;
830 default:
831 printk(KERN_ERR "Unknown token type %x on rxrpc key\n",
832 token->security_index);
833 BUG();
834 }
835
836 kfree(token);
837 }
838} 867}
839 868
840/* 869/*