tls: rx: return the already-copied data on crypto error
authorJakub Kicinski <kuba@kernel.org>
Mon, 11 Apr 2022 19:19:14 +0000 (12:19 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 13 Apr 2022 10:45:39 +0000 (11:45 +0100)
async crypto handler will report the socket error no need
to report it again. We can, however, let the data we already
copied be reported to user space but we need to make sure
the error will be reported next time around.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/tls/tls_sw.c

index c1ba64bfe228d2d779b5dedc38ced2f8db6e9409..73c31f38dfe935b2c1fe0f65ad9fb4de28316374 100644 (file)
@@ -1744,6 +1744,11 @@ int tls_sw_recvmsg(struct sock *sk,
        lock_sock(sk);
        bpf_strp_enabled = sk_psock_strp_enabled(psock);
 
+       /* If crypto failed the connection is broken */
+       err = ctx->async_wait.err;
+       if (err)
+               goto end;
+
        /* Process pending decrypted records. It must be non-zero-copy */
        err = process_rx_list(ctx, msg, &control, 0, len, false, is_peek);
        if (err < 0)
@@ -1874,7 +1879,7 @@ leave_on_list:
 
 recv_end:
        if (async) {
-               int pending;
+               int ret, pending;
 
                /* Wait for all previously submitted records to be decrypted */
                spin_lock_bh(&ctx->decrypt_compl_lock);
@@ -1882,11 +1887,10 @@ recv_end:
                pending = atomic_read(&ctx->decrypt_pending);
                spin_unlock_bh(&ctx->decrypt_compl_lock);
                if (pending) {
-                       err = crypto_wait_req(-EINPROGRESS, &ctx->async_wait);
-                       if (err) {
-                               /* one of async decrypt failed */
-                               tls_err_abort(sk, err);
-                               copied = 0;
+                       ret = crypto_wait_req(-EINPROGRESS, &ctx->async_wait);
+                       if (ret) {
+                               if (err >= 0 || err == -EINPROGRESS)
+                                       err = ret;
                                decrypted = 0;
                                goto end;
                        }