| From 18498f47af2a5efcd492adf22cd3b79badbdd091 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 4 May 2020 10:21:23 -0700 |
| Subject: bpf, sockmap: msg_pop_data can incorrecty set an sge length |
| |
| From: John Fastabend <john.fastabend@gmail.com> |
| |
| [ Upstream commit 3e104c23816220919ea1b3fd93fabe363c67c484 ] |
| |
| When sk_msg_pop() is called where the pop operation is working on |
| the end of a sge element and there is no additional trailing data |
| and there _is_ data in front of pop, like the following case, |
| |
| |____________a_____________|__pop__| |
| |
| We have out of order operations where we incorrectly set the pop |
| variable so that instead of zero'ing pop we incorrectly leave it |
| untouched, effectively. This can cause later logic to shift the |
| buffers around believing it should pop extra space. The result is |
| we have 'popped' more data then we expected potentially breaking |
| program logic. |
| |
| It took us a while to hit this case because typically we pop headers |
| which seem to rarely be at the end of a scatterlist elements but |
| we can't rely on this. |
| |
| Fixes: 7246d8ed4dcce ("bpf: helper to pop data from messages") |
| Signed-off-by: John Fastabend <john.fastabend@gmail.com> |
| Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> |
| Reviewed-by: Jakub Sitnicki <jakub@cloudflare.com> |
| Acked-by: Martin KaFai Lau <kafai@fb.com> |
| Link: https://lore.kernel.org/bpf/158861288359.14306.7654891716919968144.stgit@john-Precision-5820-Tower |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| net/core/filter.c | 2 +- |
| 1 file changed, 1 insertion(+), 1 deletion(-) |
| |
| diff --git a/net/core/filter.c b/net/core/filter.c |
| index c180871e606d8..083fbe92662ec 100644 |
| --- a/net/core/filter.c |
| +++ b/net/core/filter.c |
| @@ -2590,8 +2590,8 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start, |
| } |
| pop = 0; |
| } else if (pop >= sge->length - a) { |
| - sge->length = a; |
| pop -= (sge->length - a); |
| + sge->length = a; |
| } |
| } |
| |
| -- |
| 2.20.1 |
| |