tls: rx: clear ctx->recv_pkt earlier
authorJakub Kicinski <kuba@kernel.org>
Fri, 8 Apr 2022 18:31:33 +0000 (11:31 -0700)
committerDavid S. Miller <davem@davemloft.net>
Sun, 10 Apr 2022 16:32:12 +0000 (17:32 +0100)
Whatever we do in the loop the skb should not remain on as
ctx->recv_pkt afterwards. We can clear that pointer and
restart strparser earlier.

This adds overhead of extra linking and unlinking to rx_list
but that's not large (upcoming change will switch to unlocked
skb list operations).

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

index 3aa8fe1c6e7720b0ac2b5e9426a01970780fc55e..71d8082647c801b46c7213d1b742d243e1c0a260 100644 (file)
@@ -1826,6 +1826,10 @@ int tls_sw_recvmsg(struct sock *sk,
                if (err <= 0)
                        goto recv_end;
 
+               ctx->recv_pkt = NULL;
+               __strp_unpause(&ctx->strp);
+               skb_queue_tail(&ctx->rx_list, skb);
+
                if (async) {
                        /* TLS 1.2-only, to_decrypt must be text length */
                        chunk = min_t(int, to_decrypt, len);
@@ -1840,10 +1844,9 @@ int tls_sw_recvmsg(struct sock *sk,
                                if (err != __SK_PASS) {
                                        rxm->offset = rxm->offset + rxm->full_len;
                                        rxm->full_len = 0;
+                                       skb_unlink(skb, &ctx->rx_list);
                                        if (err == __SK_DROP)
                                                consume_skb(skb);
-                                       ctx->recv_pkt = NULL;
-                                       __strp_unpause(&ctx->strp);
                                        continue;
                                }
                        }
@@ -1869,14 +1872,9 @@ pick_next_record:
                len -= chunk;
 
                /* For async or peek case, queue the current skb */
-               if (async || is_peek || retain_skb) {
-                       skb_queue_tail(&ctx->rx_list, skb);
-                       ctx->recv_pkt = NULL;
-                       __strp_unpause(&ctx->strp);
-               } else {
+               if (!(async || is_peek || retain_skb)) {
+                       skb_unlink(skb, &ctx->rx_list);
                        consume_skb(skb);
-                       ctx->recv_pkt = NULL;
-                       __strp_unpause(&ctx->strp);
 
                        /* Return full control message to
                         * userspace before trying to parse