net: tls: avoid discarding data on record close
authorJakub Kicinski <kuba@kernel.org>
Fri, 4 Aug 2023 22:59:51 +0000 (15:59 -0700)
committerDavid S. Miller <davem@davemloft.net>
Sun, 6 Aug 2023 07:32:18 +0000 (08:32 +0100)
commit6b47808f223c70ff564f9b363446d2a5fa1e05b2
tree2a4ba4041ede248ebe642c8820ccc0d6cfeece43
parenta47e598fbd8617967e49d85c49c22f9fc642704c
net: tls: avoid discarding data on record close

TLS records end with a 16B tag. For TLS device offload we only
need to make space for this tag in the stream, the device will
generate and replace it with the actual calculated tag.

Long time ago the code would just re-reference the head frag
which mostly worked but was suboptimal because it prevented TCP
from combining the record into a single skb frag. I'm not sure
if it was correct as the first frag may be shorter than the tag.

The commit under fixes tried to replace that with using the page
frag and if the allocation failed rolling back the data, if record
was long enough. It achieves better fragment coalescing but is
also buggy.

We don't roll back the iterator, so unless we're at the end of
send we'll skip the data we designated as tag and start the
next record as if the rollback never happened.
There's also the possibility that the record was constructed
with MSG_MORE and the data came from a different syscall and
we already told the user space that we "got it".

Allocate a single dummy page and use it as fallback.

Found by code inspection, and proven by forcing allocation
failures.

Fixes: e7b159a48ba6 ("net/tls: remove the record tail optimization")
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/tls/tls_device.c