Commit fedf201e authored by Dave Watson's avatar Dave Watson Committed by David S. Miller

net: tls: Refactor control message handling on recv

For TLS 1.3, the control message is encrypted.  Handle control
message checks after decryption.
Signed-off-by: default avatarDave Watson <davejwatson@fb.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a2ef9b6a
...@@ -1421,16 +1421,15 @@ static int decrypt_skb_update(struct sock *sk, struct sk_buff *skb, ...@@ -1421,16 +1421,15 @@ static int decrypt_skb_update(struct sock *sk, struct sk_buff *skb,
return err; return err;
} }
rxm->offset += tls_ctx->rx.prepend_size;
rxm->full_len -= tls_ctx->rx.overhead_size;
tls_advance_record_sn(sk, &tls_ctx->rx);
ctx->decrypted = true;
ctx->saved_data_ready(sk);
} else { } else {
*zc = false; *zc = false;
} }
rxm->offset += tls_ctx->rx.prepend_size;
rxm->full_len -= tls_ctx->rx.overhead_size;
tls_advance_record_sn(sk, &tls_ctx->rx);
ctx->decrypted = true;
ctx->saved_data_ready(sk);
return err; return err;
} }
...@@ -1609,6 +1608,25 @@ int tls_sw_recvmsg(struct sock *sk, ...@@ -1609,6 +1608,25 @@ int tls_sw_recvmsg(struct sock *sk,
rxm = strp_msg(skb); rxm = strp_msg(skb);
to_decrypt = rxm->full_len - tls_ctx->rx.overhead_size;
if (to_decrypt <= len && !is_kvec && !is_peek &&
ctx->control == TLS_RECORD_TYPE_DATA)
zc = true;
err = decrypt_skb_update(sk, skb, &msg->msg_iter,
&chunk, &zc, ctx->async_capable);
if (err < 0 && err != -EINPROGRESS) {
tls_err_abort(sk, EBADMSG);
goto recv_end;
}
if (err == -EINPROGRESS) {
async = true;
num_async++;
goto pick_next_record;
}
if (!cmsg) { if (!cmsg) {
int cerr; int cerr;
...@@ -1626,40 +1644,22 @@ int tls_sw_recvmsg(struct sock *sk, ...@@ -1626,40 +1644,22 @@ int tls_sw_recvmsg(struct sock *sk,
goto recv_end; goto recv_end;
} }
to_decrypt = rxm->full_len - tls_ctx->rx.overhead_size; if (!zc) {
if (rxm->full_len > len) {
if (to_decrypt <= len && !is_kvec && !is_peek) retain_skb = true;
zc = true; chunk = len;
} else {
err = decrypt_skb_update(sk, skb, &msg->msg_iter, chunk = rxm->full_len;
&chunk, &zc, ctx->async_capable); }
if (err < 0 && err != -EINPROGRESS) {
tls_err_abort(sk, EBADMSG);
goto recv_end;
}
if (err == -EINPROGRESS) {
async = true;
num_async++;
goto pick_next_record;
} else {
if (!zc) {
if (rxm->full_len > len) {
retain_skb = true;
chunk = len;
} else {
chunk = rxm->full_len;
}
err = skb_copy_datagram_msg(skb, rxm->offset, err = skb_copy_datagram_msg(skb, rxm->offset,
msg, chunk); msg, chunk);
if (err < 0) if (err < 0)
goto recv_end; goto recv_end;
if (!is_peek) { if (!is_peek) {
rxm->offset = rxm->offset + chunk; rxm->offset = rxm->offset + chunk;
rxm->full_len = rxm->full_len - chunk; rxm->full_len = rxm->full_len - chunk;
}
} }
} }
...@@ -1759,15 +1759,15 @@ ssize_t tls_sw_splice_read(struct socket *sock, loff_t *ppos, ...@@ -1759,15 +1759,15 @@ ssize_t tls_sw_splice_read(struct socket *sock, loff_t *ppos,
if (!skb) if (!skb)
goto splice_read_end; goto splice_read_end;
/* splice does not support reading control messages */
if (ctx->control != TLS_RECORD_TYPE_DATA) {
err = -ENOTSUPP;
goto splice_read_end;
}
if (!ctx->decrypted) { if (!ctx->decrypted) {
err = decrypt_skb_update(sk, skb, NULL, &chunk, &zc, false); err = decrypt_skb_update(sk, skb, NULL, &chunk, &zc, false);
/* splice does not support reading control messages */
if (ctx->control != TLS_RECORD_TYPE_DATA) {
err = -ENOTSUPP;
goto splice_read_end;
}
if (err < 0) { if (err < 0) {
tls_err_abort(sk, EBADMSG); tls_err_abort(sk, EBADMSG);
goto splice_read_end; goto splice_read_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