Skip to content

Commit fa40d97

Browse files
maxvs1davem330
authored andcommitted
tipc: fix size validations for the MSG_CRYPTO type
The function tipc_crypto_key_rcv is used to parse MSG_CRYPTO messages to receive keys from other nodes in the cluster in order to decrypt any further messages from them. This patch verifies that any supplied sizes in the message body are valid for the received message. Fixes: 1ef6f7c ("tipc: add automatic session key exchange") Signed-off-by: Max VA <maxv@sentinelone.com> Acked-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Acked-by: Jon Maloy <jmaloy@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 2195f20 commit fa40d97

File tree

1 file changed

+21
-11
lines changed

1 file changed

+21
-11
lines changed

net/tipc/crypto.c

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2285,43 +2285,53 @@ static bool tipc_crypto_key_rcv(struct tipc_crypto *rx, struct tipc_msg *hdr)
22852285
u16 key_gen = msg_key_gen(hdr);
22862286
u16 size = msg_data_sz(hdr);
22872287
u8 *data = msg_data(hdr);
2288+
unsigned int keylen;
2289+
2290+
/* Verify whether the size can exist in the packet */
2291+
if (unlikely(size < sizeof(struct tipc_aead_key) + TIPC_AEAD_KEYLEN_MIN)) {
2292+
pr_debug("%s: message data size is too small\n", rx->name);
2293+
goto exit;
2294+
}
2295+
2296+
keylen = ntohl(*((__be32 *)(data + TIPC_AEAD_ALG_NAME)));
2297+
2298+
/* Verify the supplied size values */
2299+
if (unlikely(size != keylen + sizeof(struct tipc_aead_key) ||
2300+
keylen > TIPC_AEAD_KEY_SIZE_MAX)) {
2301+
pr_debug("%s: invalid MSG_CRYPTO key size\n", rx->name);
2302+
goto exit;
2303+
}
22882304

22892305
spin_lock(&rx->lock);
22902306
if (unlikely(rx->skey || (key_gen == rx->key_gen && rx->key.keys))) {
22912307
pr_err("%s: key existed <%p>, gen %d vs %d\n", rx->name,
22922308
rx->skey, key_gen, rx->key_gen);
2293-
goto exit;
2309+
goto exit_unlock;
22942310
}
22952311

22962312
/* Allocate memory for the key */
22972313
skey = kmalloc(size, GFP_ATOMIC);
22982314
if (unlikely(!skey)) {
22992315
pr_err("%s: unable to allocate memory for skey\n", rx->name);
2300-
goto exit;
2316+
goto exit_unlock;
23012317
}
23022318

23032319
/* Copy key from msg data */
2304-
skey->keylen = ntohl(*((__be32 *)(data + TIPC_AEAD_ALG_NAME)));
2320+
skey->keylen = keylen;
23052321
memcpy(skey->alg_name, data, TIPC_AEAD_ALG_NAME);
23062322
memcpy(skey->key, data + TIPC_AEAD_ALG_NAME + sizeof(__be32),
23072323
skey->keylen);
23082324

2309-
/* Sanity check */
2310-
if (unlikely(size != tipc_aead_key_size(skey))) {
2311-
kfree(skey);
2312-
skey = NULL;
2313-
goto exit;
2314-
}
2315-
23162325
rx->key_gen = key_gen;
23172326
rx->skey_mode = msg_key_mode(hdr);
23182327
rx->skey = skey;
23192328
rx->nokey = 0;
23202329
mb(); /* for nokey flag */
23212330

2322-
exit:
2331+
exit_unlock:
23232332
spin_unlock(&rx->lock);
23242333

2334+
exit:
23252335
/* Schedule the key attaching on this crypto */
23262336
if (likely(skey && queue_delayed_work(tx->wq, &rx->work, 0)))
23272337
return true;

0 commit comments

Comments
 (0)