diff options
author | Sabrina Dubroca <sd@queasysnail.net> | 2018-01-16 10:04:26 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-01-17 16:16:03 -0500 |
commit | cf6d43ef66f416282121f436ce1bee9a25199d52 (patch) | |
tree | 0e2e7f8c15b36422f69874435375d3445688893f | |
parent | 6ab6dd9e7f18dea51a6d65c0c28f0fd74332bfe6 (diff) |
tls: fix sw_ctx leak
During setsockopt(SOL_TCP, TLS_TX), if initialization of the software
context fails in tls_set_sw_offload(), we leak sw_ctx. We also don't
reassign ctx->priv_ctx to NULL, so we can't even do another attempt to
set it up on the same socket, as it will fail with -EEXIST.
Fixes: 3c4d7559159b ('tls: kernel TLS support')
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/tls/tls_sw.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c index 9773571b6a34..61f394d369bf 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c | |||
@@ -681,18 +681,17 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx) | |||
681 | } | 681 | } |
682 | default: | 682 | default: |
683 | rc = -EINVAL; | 683 | rc = -EINVAL; |
684 | goto out; | 684 | goto free_priv; |
685 | } | 685 | } |
686 | 686 | ||
687 | ctx->prepend_size = TLS_HEADER_SIZE + nonce_size; | 687 | ctx->prepend_size = TLS_HEADER_SIZE + nonce_size; |
688 | ctx->tag_size = tag_size; | 688 | ctx->tag_size = tag_size; |
689 | ctx->overhead_size = ctx->prepend_size + ctx->tag_size; | 689 | ctx->overhead_size = ctx->prepend_size + ctx->tag_size; |
690 | ctx->iv_size = iv_size; | 690 | ctx->iv_size = iv_size; |
691 | ctx->iv = kmalloc(iv_size + TLS_CIPHER_AES_GCM_128_SALT_SIZE, | 691 | ctx->iv = kmalloc(iv_size + TLS_CIPHER_AES_GCM_128_SALT_SIZE, GFP_KERNEL); |
692 | GFP_KERNEL); | ||
693 | if (!ctx->iv) { | 692 | if (!ctx->iv) { |
694 | rc = -ENOMEM; | 693 | rc = -ENOMEM; |
695 | goto out; | 694 | goto free_priv; |
696 | } | 695 | } |
697 | memcpy(ctx->iv, gcm_128_info->salt, TLS_CIPHER_AES_GCM_128_SALT_SIZE); | 696 | memcpy(ctx->iv, gcm_128_info->salt, TLS_CIPHER_AES_GCM_128_SALT_SIZE); |
698 | memcpy(ctx->iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE, iv, iv_size); | 697 | memcpy(ctx->iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE, iv, iv_size); |
@@ -740,7 +739,7 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx) | |||
740 | 739 | ||
741 | rc = crypto_aead_setauthsize(sw_ctx->aead_send, ctx->tag_size); | 740 | rc = crypto_aead_setauthsize(sw_ctx->aead_send, ctx->tag_size); |
742 | if (!rc) | 741 | if (!rc) |
743 | goto out; | 742 | return 0; |
744 | 743 | ||
745 | free_aead: | 744 | free_aead: |
746 | crypto_free_aead(sw_ctx->aead_send); | 745 | crypto_free_aead(sw_ctx->aead_send); |
@@ -751,6 +750,9 @@ free_rec_seq: | |||
751 | free_iv: | 750 | free_iv: |
752 | kfree(ctx->iv); | 751 | kfree(ctx->iv); |
753 | ctx->iv = NULL; | 752 | ctx->iv = NULL; |
753 | free_priv: | ||
754 | kfree(ctx->priv_ctx); | ||
755 | ctx->priv_ctx = NULL; | ||
754 | out: | 756 | out: |
755 | return rc; | 757 | return rc; |
756 | } | 758 | } |