Commit c14a0246 authored by David S. Miller's avatar David S. Miller

Merge branch 'tls-fixes'

Daniel Borkmann says:

====================
Two tls fixes

First one is syzkaller trigered uaf and second one noticed
while writing test code with tls ulp. For details please see
individual patches.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 695ad876 06030dba
...@@ -191,18 +191,12 @@ static void tls_free_both_sg(struct sock *sk) ...@@ -191,18 +191,12 @@ static void tls_free_both_sg(struct sock *sk)
} }
static int tls_do_encryption(struct tls_context *tls_ctx, static int tls_do_encryption(struct tls_context *tls_ctx,
struct tls_sw_context_tx *ctx, size_t data_len, struct tls_sw_context_tx *ctx,
gfp_t flags) struct aead_request *aead_req,
size_t data_len)
{ {
unsigned int req_size = sizeof(struct aead_request) +
crypto_aead_reqsize(ctx->aead_send);
struct aead_request *aead_req;
int rc; int rc;
aead_req = kzalloc(req_size, flags);
if (!aead_req)
return -ENOMEM;
ctx->sg_encrypted_data[0].offset += tls_ctx->tx.prepend_size; ctx->sg_encrypted_data[0].offset += tls_ctx->tx.prepend_size;
ctx->sg_encrypted_data[0].length -= tls_ctx->tx.prepend_size; ctx->sg_encrypted_data[0].length -= tls_ctx->tx.prepend_size;
...@@ -219,7 +213,6 @@ static int tls_do_encryption(struct tls_context *tls_ctx, ...@@ -219,7 +213,6 @@ static int tls_do_encryption(struct tls_context *tls_ctx,
ctx->sg_encrypted_data[0].offset -= tls_ctx->tx.prepend_size; ctx->sg_encrypted_data[0].offset -= tls_ctx->tx.prepend_size;
ctx->sg_encrypted_data[0].length += tls_ctx->tx.prepend_size; ctx->sg_encrypted_data[0].length += tls_ctx->tx.prepend_size;
kfree(aead_req);
return rc; return rc;
} }
...@@ -228,8 +221,14 @@ static int tls_push_record(struct sock *sk, int flags, ...@@ -228,8 +221,14 @@ static int tls_push_record(struct sock *sk, int flags,
{ {
struct tls_context *tls_ctx = tls_get_ctx(sk); struct tls_context *tls_ctx = tls_get_ctx(sk);
struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx); struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx);
struct aead_request *req;
int rc; int rc;
req = kzalloc(sizeof(struct aead_request) +
crypto_aead_reqsize(ctx->aead_send), sk->sk_allocation);
if (!req)
return -ENOMEM;
sg_mark_end(ctx->sg_plaintext_data + ctx->sg_plaintext_num_elem - 1); sg_mark_end(ctx->sg_plaintext_data + ctx->sg_plaintext_num_elem - 1);
sg_mark_end(ctx->sg_encrypted_data + ctx->sg_encrypted_num_elem - 1); sg_mark_end(ctx->sg_encrypted_data + ctx->sg_encrypted_num_elem - 1);
...@@ -245,15 +244,14 @@ static int tls_push_record(struct sock *sk, int flags, ...@@ -245,15 +244,14 @@ static int tls_push_record(struct sock *sk, int flags,
tls_ctx->pending_open_record_frags = 0; tls_ctx->pending_open_record_frags = 0;
set_bit(TLS_PENDING_CLOSED_RECORD, &tls_ctx->flags); set_bit(TLS_PENDING_CLOSED_RECORD, &tls_ctx->flags);
rc = tls_do_encryption(tls_ctx, ctx, ctx->sg_plaintext_size, rc = tls_do_encryption(tls_ctx, ctx, req, ctx->sg_plaintext_size);
sk->sk_allocation);
if (rc < 0) { if (rc < 0) {
/* If we are called from write_space and /* If we are called from write_space and
* we fail, we need to set this SOCK_NOSPACE * we fail, we need to set this SOCK_NOSPACE
* to trigger another write_space in the future. * to trigger another write_space in the future.
*/ */
set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
return rc; goto out_req;
} }
free_sg(sk, ctx->sg_plaintext_data, &ctx->sg_plaintext_num_elem, free_sg(sk, ctx->sg_plaintext_data, &ctx->sg_plaintext_num_elem,
...@@ -268,6 +266,8 @@ static int tls_push_record(struct sock *sk, int flags, ...@@ -268,6 +266,8 @@ static int tls_push_record(struct sock *sk, int flags,
tls_err_abort(sk, EBADMSG); tls_err_abort(sk, EBADMSG);
tls_advance_record_sn(sk, &tls_ctx->tx); tls_advance_record_sn(sk, &tls_ctx->tx);
out_req:
kfree(req);
return rc; return rc;
} }
...@@ -754,7 +754,7 @@ int tls_sw_recvmsg(struct sock *sk, ...@@ -754,7 +754,7 @@ int tls_sw_recvmsg(struct sock *sk,
struct sk_buff *skb; struct sk_buff *skb;
ssize_t copied = 0; ssize_t copied = 0;
bool cmsg = false; bool cmsg = false;
int err = 0; int target, err = 0;
long timeo; long timeo;
flags |= nonblock; flags |= nonblock;
...@@ -764,6 +764,7 @@ int tls_sw_recvmsg(struct sock *sk, ...@@ -764,6 +764,7 @@ int tls_sw_recvmsg(struct sock *sk,
lock_sock(sk); lock_sock(sk);
target = sock_rcvlowat(sk, flags & MSG_WAITALL, len);
timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
do { do {
bool zc = false; bool zc = false;
...@@ -856,6 +857,9 @@ int tls_sw_recvmsg(struct sock *sk, ...@@ -856,6 +857,9 @@ int tls_sw_recvmsg(struct sock *sk,
goto recv_end; goto recv_end;
} }
} }
/* If we have a new message from strparser, continue now. */
if (copied >= target && !ctx->recv_pkt)
break;
} while (len); } while (len);
recv_end: recv_end:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment