diff options
author | Ilya Lesokhin <ilyal@mellanox.com> | 2017-11-13 03:22:46 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-11-14 02:26:34 -0500 |
commit | ff45d820a2df163957ad8ab459b6eb6976144c18 (patch) | |
tree | 4bacc5b4e85cb2db15bb13f6cff0f6393fffc792 /net/tls/tls_main.c | |
parent | 6d88207fcfddc002afe3e2e4a455e5201089d5d9 (diff) |
tls: Fix TLS ulp context leak, when TLS_TX setsockopt is not used.
Previously the TLS ulp context would leak if we attached a TLS ulp
to a socket but did not use the TLS_TX setsockopt,
or did use it but it failed.
This patch solves the issue by overriding prot[TLS_BASE_TX].close
and fixing tls_sk_proto_close to work properly
when its called with ctx->tx_conf == TLS_BASE_TX.
This patch also removes ctx->free_resources as we can use ctx->tx_conf
to obtain the relevant information.
Fixes: 3c4d7559159b ('tls: kernel TLS support')
Signed-off-by: Ilya Lesokhin <ilyal@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tls/tls_main.c')
-rw-r--r-- | net/tls/tls_main.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c index de6a1416bc41..13427ee7c582 100644 --- a/net/tls/tls_main.c +++ b/net/tls/tls_main.c | |||
@@ -226,6 +226,12 @@ static void tls_sk_proto_close(struct sock *sk, long timeout) | |||
226 | void (*sk_proto_close)(struct sock *sk, long timeout); | 226 | void (*sk_proto_close)(struct sock *sk, long timeout); |
227 | 227 | ||
228 | lock_sock(sk); | 228 | lock_sock(sk); |
229 | sk_proto_close = ctx->sk_proto_close; | ||
230 | |||
231 | if (ctx->tx_conf == TLS_BASE_TX) { | ||
232 | kfree(ctx); | ||
233 | goto skip_tx_cleanup; | ||
234 | } | ||
229 | 235 | ||
230 | if (!tls_complete_pending_work(sk, ctx, 0, &timeo)) | 236 | if (!tls_complete_pending_work(sk, ctx, 0, &timeo)) |
231 | tls_handle_open_record(sk, 0); | 237 | tls_handle_open_record(sk, 0); |
@@ -242,13 +248,14 @@ static void tls_sk_proto_close(struct sock *sk, long timeout) | |||
242 | sg++; | 248 | sg++; |
243 | } | 249 | } |
244 | } | 250 | } |
245 | ctx->free_resources(sk); | 251 | |
246 | kfree(ctx->rec_seq); | 252 | kfree(ctx->rec_seq); |
247 | kfree(ctx->iv); | 253 | kfree(ctx->iv); |
248 | 254 | ||
249 | sk_proto_close = ctx->sk_proto_close; | 255 | if (ctx->tx_conf == TLS_SW_TX) |
250 | kfree(ctx); | 256 | tls_sw_free_tx_resources(sk); |
251 | 257 | ||
258 | skip_tx_cleanup: | ||
252 | release_sock(sk); | 259 | release_sock(sk); |
253 | sk_proto_close(sk, timeout); | 260 | sk_proto_close(sk, timeout); |
254 | } | 261 | } |
@@ -402,8 +409,6 @@ static int do_tls_setsockopt_tx(struct sock *sk, char __user *optval, | |||
402 | ctx->sk_write_space = sk->sk_write_space; | 409 | ctx->sk_write_space = sk->sk_write_space; |
403 | sk->sk_write_space = tls_write_space; | 410 | sk->sk_write_space = tls_write_space; |
404 | 411 | ||
405 | ctx->sk_proto_close = sk->sk_prot->close; | ||
406 | |||
407 | /* currently SW is default, we will have ethtool in future */ | 412 | /* currently SW is default, we will have ethtool in future */ |
408 | rc = tls_set_sw_offload(sk, ctx); | 413 | rc = tls_set_sw_offload(sk, ctx); |
409 | tx_conf = TLS_SW_TX; | 414 | tx_conf = TLS_SW_TX; |
@@ -464,6 +469,7 @@ static int tls_init(struct sock *sk) | |||
464 | icsk->icsk_ulp_data = ctx; | 469 | icsk->icsk_ulp_data = ctx; |
465 | ctx->setsockopt = sk->sk_prot->setsockopt; | 470 | ctx->setsockopt = sk->sk_prot->setsockopt; |
466 | ctx->getsockopt = sk->sk_prot->getsockopt; | 471 | ctx->getsockopt = sk->sk_prot->getsockopt; |
472 | ctx->sk_proto_close = sk->sk_prot->close; | ||
467 | 473 | ||
468 | ctx->tx_conf = TLS_BASE_TX; | 474 | ctx->tx_conf = TLS_BASE_TX; |
469 | update_sk_prot(sk, ctx); | 475 | update_sk_prot(sk, ctx); |
@@ -480,11 +486,11 @@ static struct tcp_ulp_ops tcp_tls_ulp_ops __read_mostly = { | |||
480 | static void build_protos(struct proto *prot, struct proto *base) | 486 | static void build_protos(struct proto *prot, struct proto *base) |
481 | { | 487 | { |
482 | prot[TLS_BASE_TX] = *base; | 488 | prot[TLS_BASE_TX] = *base; |
483 | prot[TLS_BASE_TX].setsockopt = tls_setsockopt; | 489 | prot[TLS_BASE_TX].setsockopt = tls_setsockopt; |
484 | prot[TLS_BASE_TX].getsockopt = tls_getsockopt; | 490 | prot[TLS_BASE_TX].getsockopt = tls_getsockopt; |
491 | prot[TLS_BASE_TX].close = tls_sk_proto_close; | ||
485 | 492 | ||
486 | prot[TLS_SW_TX] = prot[TLS_BASE_TX]; | 493 | prot[TLS_SW_TX] = prot[TLS_BASE_TX]; |
487 | prot[TLS_SW_TX].close = tls_sk_proto_close; | ||
488 | prot[TLS_SW_TX].sendmsg = tls_sw_sendmsg; | 494 | prot[TLS_SW_TX].sendmsg = tls_sw_sendmsg; |
489 | prot[TLS_SW_TX].sendpage = tls_sw_sendpage; | 495 | prot[TLS_SW_TX].sendpage = tls_sw_sendpage; |
490 | } | 496 | } |