Skip to content

Commit

Permalink
mptcp: Preallocate aligned HMAC key's placeholder
Browse files Browse the repository at this point in the history
'crypto_hash_setkey' might call a GFP_KERNEL allocation
in case of unaligned input key, causing deadlock.
We can avoid this by preallocating an aligned placeholder for
the key.

Signed-off-by: Fabrizio Demaria <fabrizio.demaria@intel.com>
  • Loading branch information
fabriziodemaria committed Dec 8, 2015
1 parent 9c0495f commit 06e7644
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 2 deletions.
3 changes: 3 additions & 0 deletions include/net/mptcp.h
Expand Up @@ -346,8 +346,11 @@ struct mptcp_cb {

struct mptcp_hmacsha1_pool {
struct hash_desc hmacsha1_desc;
u8 *key_placeholder;
};

#define MPTCP_HMACSHA1_KEYLEN 16

#define MPTCP_SUB_CAPABLE 0
#define MPTCP_SUB_LEN_CAPABLE_SYN 12
#define MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN 12
Expand Down
1 change: 0 additions & 1 deletion net/ipv4/tcp.c
Expand Up @@ -443,7 +443,6 @@ void tcp_init_sock(struct sock *sk)

/* Initialize MPTCP-specific stuff and function-pointers */
mptcp_init_tcp_sock(sk);
mptcp_alloc_hmacsha1_pool();

local_bh_disable();
sock_update_memcg(sk);
Expand Down
19 changes: 18 additions & 1 deletion net/mptcp/mptcp_ctrl.c
Expand Up @@ -391,11 +391,26 @@ static void __mptcp_alloc_hmacsha1_pool(void)
for_each_possible_cpu(cpu) {
if (!per_cpu(mptcp_hmacsha1_pool, cpu).hmacsha1_desc.tfm) {
struct crypto_hash *hash;
unsigned int keylen = MPTCP_HMACSHA1_KEYLEN;
unsigned long absize;
unsigned long alignmask;
u8 *buffer;
u8 *alignbuffer;

/* Allocating crypto_hash */
hash = crypto_alloc_hash("hmac(sha1)", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR_OR_NULL(hash))
return;
per_cpu(mptcp_hmacsha1_pool, cpu).hmacsha1_desc.tfm = hash;

/* Allocating aligned key_placeholder */
alignmask = crypto_hash_alignmask(hash);
absize = keylen + (alignmask & ~(crypto_tfm_ctx_alignment() - 1));
buffer = kmalloc(absize, GFP_KERNEL);
if (!buffer)
return;
alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
per_cpu(mptcp_hmacsha1_pool, cpu).key_placeholder = alignbuffer;
}
}
/* before setting mptcp_hmacsha1_pool_populated, we must commit all
Expand Down Expand Up @@ -489,6 +504,7 @@ void mptcp_disable_static_key(void)

void mptcp_enable_sock(struct sock *sk)
{
mptcp_alloc_hmacsha1_pool();
if (!sock_flag(sk, SOCK_MPTCP)) {
sock_set_flag(sk, SOCK_MPTCP);

Expand Down Expand Up @@ -850,7 +866,7 @@ void mptcp_hmac_sha1(u8 *key_1, u8 *key_2, u8 *hash_out, int arg_num, ...)
{
struct mptcp_hmacsha1_pool *sp;
struct scatterlist sg;
u8 key[16];
u8 *key;
int i;
int length;
u8 *msg;
Expand All @@ -860,6 +876,7 @@ void mptcp_hmac_sha1(u8 *key_1, u8 *key_2, u8 *hash_out, int arg_num, ...)
if (!sp)
goto clear_hmac_noput;
sp->hmacsha1_desc.flags = 0;
key = sp->key_placeholder;

memcpy(&key[0], key_1, 8);
memcpy(&key[8], key_2, 8);
Expand Down

0 comments on commit 06e7644

Please sign in to comment.