--- zzzz-none-000/linux-3.10.107/net/rxrpc/ar-key.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/net/rxrpc/ar-key.c 2021-02-04 17:41:59.000000000 +0000 @@ -26,8 +26,10 @@ #include "ar-internal.h" static int rxrpc_vet_description_s(const char *); -static int rxrpc_instantiate(struct key *, struct key_preparsed_payload *); -static int rxrpc_instantiate_s(struct key *, struct key_preparsed_payload *); +static int rxrpc_preparse(struct key_preparsed_payload *); +static int rxrpc_preparse_s(struct key_preparsed_payload *); +static void rxrpc_free_preparse(struct key_preparsed_payload *); +static void rxrpc_free_preparse_s(struct key_preparsed_payload *); static void rxrpc_destroy(struct key *); static void rxrpc_destroy_s(struct key *); static void rxrpc_describe(const struct key *, struct seq_file *); @@ -39,8 +41,9 @@ */ struct key_type key_type_rxrpc = { .name = "rxrpc", - .instantiate = rxrpc_instantiate, - .match = user_match, + .preparse = rxrpc_preparse, + .free_preparse = rxrpc_free_preparse, + .instantiate = generic_key_instantiate, .destroy = rxrpc_destroy, .describe = rxrpc_describe, .read = rxrpc_read, @@ -54,8 +57,9 @@ struct key_type key_type_rxrpc_s = { .name = "rxrpc_s", .vet_description = rxrpc_vet_description_s, - .instantiate = rxrpc_instantiate_s, - .match = user_match, + .preparse = rxrpc_preparse_s, + .free_preparse = rxrpc_free_preparse_s, + .instantiate = generic_key_instantiate, .destroy = rxrpc_destroy_s, .describe = rxrpc_describe, }; @@ -81,13 +85,13 @@ * parse an RxKAD type XDR format token * - the caller guarantees we have at least 4 words */ -static int rxrpc_instantiate_xdr_rxkad(struct key *key, const __be32 *xdr, - unsigned int toklen) +static int rxrpc_preparse_xdr_rxkad(struct key_preparsed_payload *prep, + size_t datalen, + const __be32 *xdr, unsigned int toklen) { struct rxrpc_key_token *token, **pptoken; size_t plen; u32 tktlen; - int ret; _enter(",{%x,%x,%x,%x},%u", ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]), @@ -99,13 +103,11 @@ _debug("tktlen: %x", tktlen); if (tktlen > AFSTOKEN_RK_TIX_MAX) return -EKEYREJECTED; - if (8 * 4 + tktlen != toklen) + if (toklen < 8 * 4 + tktlen) return -EKEYREJECTED; plen = sizeof(*token) + sizeof(*token->kad) + tktlen; - ret = key_payload_reserve(key, key->datalen + plen); - if (ret < 0) - return ret; + prep->quotalen = datalen + plen; plen -= sizeof(*token); token = kzalloc(sizeof(*token), GFP_KERNEL); @@ -146,16 +148,16 @@ token->kad->ticket[6], token->kad->ticket[7]); /* count the number of tokens attached */ - key->type_data.x[0]++; + prep->payload.data[1] = (void *)((unsigned long)prep->payload.data[1] + 1); /* attach the data */ - for (pptoken = (struct rxrpc_key_token **)&key->payload.data; + for (pptoken = (struct rxrpc_key_token **)&prep->payload.data[0]; *pptoken; pptoken = &(*pptoken)->next) continue; *pptoken = token; - if (token->kad->expiry < key->expiry) - key->expiry = token->kad->expiry; + if (token->kad->expiry < prep->expiry) + prep->expiry = token->kad->expiry; _leave(" = 0"); return 0; @@ -346,7 +348,7 @@ n_elem = ntohl(*xdr++); toklen -= 4; - if (n_elem < 0 || n_elem > max_n_elem) + if (n_elem > max_n_elem) return -EINVAL; *_n_elem = n_elem; if (n_elem > 0) { @@ -418,8 +420,9 @@ * parse an RxK5 type XDR format token * - the caller guarantees we have at least 4 words */ -static int rxrpc_instantiate_xdr_rxk5(struct key *key, const __be32 *xdr, - unsigned int toklen) +static int rxrpc_preparse_xdr_rxk5(struct key_preparsed_payload *prep, + size_t datalen, + const __be32 *xdr, unsigned int toklen) { struct rxrpc_key_token *token, **pptoken; struct rxk5_key *rxk5; @@ -432,9 +435,7 @@ /* reserve some payload space for this subkey - the length of the token * is a reasonable approximation */ - ret = key_payload_reserve(key, key->datalen + toklen); - if (ret < 0) - return ret; + prep->quotalen = datalen + toklen; token = kzalloc(sizeof(*token), GFP_KERNEL); if (!token) @@ -520,14 +521,14 @@ if (toklen != 0) goto inval; - /* attach the payload to the key */ - for (pptoken = (struct rxrpc_key_token **)&key->payload.data; + /* attach the payload */ + for (pptoken = (struct rxrpc_key_token **)&prep->payload.data[0]; *pptoken; pptoken = &(*pptoken)->next) continue; *pptoken = token; - if (token->kad->expiry < key->expiry) - key->expiry = token->kad->expiry; + if (token->kad->expiry < prep->expiry) + prep->expiry = token->kad->expiry; _leave(" = 0"); return 0; @@ -545,16 +546,17 @@ * attempt to parse the data as the XDR format * - the caller guarantees we have more than 7 words */ -static int rxrpc_instantiate_xdr(struct key *key, const void *data, size_t datalen) +static int rxrpc_preparse_xdr(struct key_preparsed_payload *prep) { - const __be32 *xdr = data, *token; + const __be32 *xdr = prep->data, *token; const char *cp; unsigned int len, tmp, loop, ntoken, toklen, sec_ix; + size_t datalen = prep->datalen; int ret; _enter(",{%x,%x,%x,%x},%zu", ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]), - datalen); + prep->datalen); if (datalen > AFSTOKEN_LENGTH_MAX) goto not_xdr; @@ -635,13 +637,13 @@ switch (sec_ix) { case RXRPC_SECURITY_RXKAD: - ret = rxrpc_instantiate_xdr_rxkad(key, xdr, toklen); + ret = rxrpc_preparse_xdr_rxkad(prep, datalen, xdr, toklen); if (ret != 0) goto error; break; case RXRPC_SECURITY_RXK5: - ret = rxrpc_instantiate_xdr_rxk5(key, xdr, toklen); + ret = rxrpc_preparse_xdr_rxk5(prep, datalen, xdr, toklen); if (ret != 0) goto error; break; @@ -665,8 +667,9 @@ } /* - * instantiate an rxrpc defined key - * data should be of the form: + * Preparse an rxrpc defined key. + * + * Data should be of the form: * OFFSET LEN CONTENT * 0 4 key interface version number * 4 2 security index (type) @@ -678,7 +681,7 @@ * * if no data is provided, then a no-security key is made */ -static int rxrpc_instantiate(struct key *key, struct key_preparsed_payload *prep) +static int rxrpc_preparse(struct key_preparsed_payload *prep) { const struct rxrpc_key_data_v1 *v1; struct rxrpc_key_token *token, **pp; @@ -686,7 +689,7 @@ u32 kver; int ret; - _enter("{%x},,%zu", key_serial(key), prep->datalen); + _enter("%zu", prep->datalen); /* handle a no-security key */ if (!prep->data && prep->datalen == 0) @@ -694,7 +697,7 @@ /* determine if the XDR payload format is being used */ if (prep->datalen > 7 * 4) { - ret = rxrpc_instantiate_xdr(key, prep->data, prep->datalen); + ret = rxrpc_preparse_xdr(prep); if (ret != -EPROTO) return ret; } @@ -743,9 +746,7 @@ goto error; plen = sizeof(*token->kad) + v1->ticket_length; - ret = key_payload_reserve(key, plen + sizeof(*token)); - if (ret < 0) - goto error; + prep->quotalen = plen + sizeof(*token); ret = -ENOMEM; token = kzalloc(sizeof(*token), GFP_KERNEL); @@ -762,15 +763,16 @@ memcpy(&token->kad->session_key, &v1->session_key, 8); memcpy(&token->kad->ticket, v1->ticket, v1->ticket_length); - /* attach the data */ - key->type_data.x[0]++; + /* count the number of tokens attached */ + prep->payload.data[1] = (void *)((unsigned long)prep->payload.data[1] + 1); - pp = (struct rxrpc_key_token **)&key->payload.data; + /* attach the data */ + pp = (struct rxrpc_key_token **)&prep->payload.data[0]; while (*pp) pp = &(*pp)->next; *pp = token; - if (token->kad->expiry < key->expiry) - key->expiry = token->kad->expiry; + if (token->kad->expiry < prep->expiry) + prep->expiry = token->kad->expiry; token = NULL; ret = 0; @@ -781,20 +783,55 @@ } /* - * instantiate a server secret key - * data should be a pointer to the 8-byte secret key + * Free token list. */ -static int rxrpc_instantiate_s(struct key *key, - struct key_preparsed_payload *prep) +static void rxrpc_free_token_list(struct rxrpc_key_token *token) +{ + struct rxrpc_key_token *next; + + for (; token; token = next) { + next = token->next; + switch (token->security_index) { + case RXRPC_SECURITY_RXKAD: + kfree(token->kad); + break; + case RXRPC_SECURITY_RXK5: + if (token->k5) + rxrpc_rxk5_free(token->k5); + break; + default: + printk(KERN_ERR "Unknown token type %x on rxrpc key\n", + token->security_index); + BUG(); + } + + kfree(token); + } +} + +/* + * Clean up preparse data. + */ +static void rxrpc_free_preparse(struct key_preparsed_payload *prep) +{ + rxrpc_free_token_list(prep->payload.data[0]); +} + +/* + * Preparse a server secret key. + * + * The data should be the 8-byte secret key. + */ +static int rxrpc_preparse_s(struct key_preparsed_payload *prep) { struct crypto_blkcipher *ci; - _enter("{%x},,%zu", key_serial(key), prep->datalen); + _enter("%zu", prep->datalen); if (prep->datalen != 8) return -EINVAL; - memcpy(&key->type_data, prep->data, 8); + memcpy(&prep->payload.data[2], prep->data, 8); ci = crypto_alloc_blkcipher("pcbc(des)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(ci)) { @@ -805,36 +842,26 @@ if (crypto_blkcipher_setkey(ci, prep->data, 8) < 0) BUG(); - key->payload.data = ci; + prep->payload.data[0] = ci; _leave(" = 0"); return 0; } /* + * Clean up preparse data. + */ +static void rxrpc_free_preparse_s(struct key_preparsed_payload *prep) +{ + if (prep->payload.data[0]) + crypto_free_blkcipher(prep->payload.data[0]); +} + +/* * dispose of the data dangling from the corpse of a rxrpc key */ static void rxrpc_destroy(struct key *key) { - struct rxrpc_key_token *token; - - while ((token = key->payload.data)) { - key->payload.data = token->next; - switch (token->security_index) { - case RXRPC_SECURITY_RXKAD: - kfree(token->kad); - break; - case RXRPC_SECURITY_RXK5: - if (token->k5) - rxrpc_rxk5_free(token->k5); - break; - default: - printk(KERN_ERR "Unknown token type %x on rxrpc key\n", - token->security_index); - BUG(); - } - - kfree(token); - } + rxrpc_free_token_list(key->payload.data[0]); } /* @@ -842,9 +869,9 @@ */ static void rxrpc_destroy_s(struct key *key) { - if (key->payload.data) { - crypto_free_blkcipher(key->payload.data); - key->payload.data = NULL; + if (key->payload.data[0]) { + crypto_free_blkcipher(key->payload.data[0]); + key->payload.data[0] = NULL; } } @@ -1043,7 +1070,7 @@ size += 1 * 4; /* token count */ ntoks = 0; - for (token = key->payload.data; token; token = token->next) { + for (token = key->payload.data[0]; token; token = token->next) { toksize = 4; /* sec index */ switch (token->security_index) { @@ -1114,7 +1141,7 @@ if (copy_to_user(xdr, (s), _l) != 0) \ goto fault; \ if (_l & 3 && \ - copy_to_user((u8 *)xdr + _l, &zero, 4 - (_l & 3)) != 0) \ + copy_to_user((u8 __user *)xdr + _l, &zero, 4 - (_l & 3)) != 0) \ goto fault; \ xdr += (_l + 3) >> 2; \ } while(0) @@ -1136,7 +1163,7 @@ ENCODE(ntoks); tok = 0; - for (token = key->payload.data; token; token = token->next) { + for (token = key->payload.data[0]; token; token = token->next) { toksize = toksizes[tok++]; ENCODE(toksize); oldxdr = xdr;