| From 7a0410dec7602db226ed4f358501d0c25fe7fd4b Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 18 Jun 2021 13:34:06 -0700 |
| Subject: tls: prevent oversized sendfile() hangs by ignoring MSG_MORE |
| |
| From: Jakub Kicinski <kuba@kernel.org> |
| |
| [ Upstream commit d452d48b9f8b1a7f8152d33ef52cfd7fe1735b0a ] |
| |
| We got multiple reports that multi_chunk_sendfile test |
| case from tls selftest fails. This was sort of expected, |
| as the original fix was never applied (see it in the first |
| Link:). The test in question uses sendfile() with count |
| larger than the size of the underlying file. This will |
| make splice set MSG_MORE on all sendpage calls, meaning |
| TLS will never close and flush the last partial record. |
| |
| Eric seem to have addressed a similar problem in |
| commit 35f9c09fe9c7 ("tcp: tcp_sendpages() should call tcp_push() once") |
| by introducing MSG_SENDPAGE_NOTLAST. Unlike MSG_MORE |
| MSG_SENDPAGE_NOTLAST is not set on the last call |
| of a "pipefull" of data (PIPE_DEF_BUFFERS == 16, |
| so every 16 pages or whenever we run out of data). |
| |
| Having a break every 16 pages should be fine, TLS |
| can pack exactly 4 pages into a record, so for |
| aligned reads there should be no difference, |
| unaligned may see one extra record per sendpage(). |
| |
| Sticking to TCP semantics seems preferable to modifying |
| splice, but we can revisit it if real life scenarios |
| show a regression. |
| |
| Reported-by: Vadim Fedorenko <vfedorenko@novek.ru> |
| Reported-by: Seth Forshee <seth.forshee@canonical.com> |
| Link: https://lore.kernel.org/netdev/1591392508-14592-1-git-send-email-pooja.trivedi@stackpath.com/ |
| Fixes: 3c4d7559159b ("tls: kernel TLS support") |
| Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
| Tested-by: Seth Forshee <seth.forshee@canonical.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| net/tls/tls_sw.c | 2 +- |
| 1 file changed, 1 insertion(+), 1 deletion(-) |
| |
| diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c |
| index 3abe5257f757..15395683b8e2 100644 |
| --- a/net/tls/tls_sw.c |
| +++ b/net/tls/tls_sw.c |
| @@ -1154,7 +1154,7 @@ static int tls_sw_do_sendpage(struct sock *sk, struct page *page, |
| int ret = 0; |
| bool eor; |
| |
| - eor = !(flags & (MSG_MORE | MSG_SENDPAGE_NOTLAST)); |
| + eor = !(flags & MSG_SENDPAGE_NOTLAST); |
| sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk); |
| |
| /* Call the sk_stream functions to manage the sndbuf mem. */ |
| -- |
| 2.30.2 |
| |