From mboxrd@z Thu Jan 1 00:00:00 1970 From: John Fastabend Subject: [bpf PATCH v2 1/3] bpf: sockmap, fix scatterlist update on error path in send with apply Date: Wed, 02 May 2018 13:50:19 -0700 Message-ID: <20180502205019.12776.13620.stgit@john-Precision-Tower-5810> References: <20180502204748.12776.80509.stgit@john-Precision-Tower-5810> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Cc: netdev@vger.kernel.org To: borkmann@iogearbox.net, ast@kernel.org Return-path: Received: from [184.63.162.180] ([184.63.162.180]:43666 "EHLO john-Precision-Tower-5810" rhost-flags-FAIL-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1750939AbeEBUuY (ORCPT ); Wed, 2 May 2018 16:50:24 -0400 In-Reply-To: <20180502204748.12776.80509.stgit@john-Precision-Tower-5810> Sender: netdev-owner@vger.kernel.org List-ID: When the call to do_tcp_sendpage() fails to send the complete block requested we either retry if only a partial send was completed or abort if we receive a error less than or equal to zero. Before returning though we must update the scatterlist length/offset to account for any partial send completed. Before this patch we did this at the end of the retry loop, but this was buggy when used while applying a verdict to fewer bytes than in the scatterlist. When the scatterlist length was being set we forgot to account for the apply logic reducing the size variable. So the result was we chopped off some bytes in the scatterlist without doing proper cleanup on them. This results in a WARNING when the sock is tore down because the bytes have previously been charged to the socket but are never uncharged. The simple fix is to simply do the accounting inside the retry loop subtracting from the absolute scatterlist values rather than trying to accumulate the totals and subtract at the end. Reported-by: Alexei Starovoitov Signed-off-by: John Fastabend --- kernel/bpf/sockmap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kernel/bpf/sockmap.c b/kernel/bpf/sockmap.c index 634415c..943929a 100644 --- a/kernel/bpf/sockmap.c +++ b/kernel/bpf/sockmap.c @@ -326,6 +326,9 @@ static int bpf_tcp_push(struct sock *sk, int apply_bytes, if (ret > 0) { if (apply) apply_bytes -= ret; + + sg->offset += ret; + sg->length -= ret; size -= ret; offset += ret; if (uncharge) @@ -333,8 +336,6 @@ static int bpf_tcp_push(struct sock *sk, int apply_bytes, goto retry; } - sg->length = size; - sg->offset = offset; return ret; }