bpf: fix sg shift repair start offset in bpf_msg_pull_data
When we perform the sg shift repair for the scatterlist ring, we currently start out at i = first_sg + 1. However, this is not correct since the first_sg could point to the sge sitting at slot MAX_SKB_FRAGS - 1, and a subsequent i = MAX_SKB_FRAGS will access the scatterlist ring (sg) out of bounds. Add the sk_msg_iter_var() helper for iterating through the ring, and apply the same rule for advancing to the next ring element as we do elsewhere. Later work will use this helper also in other places. Fixes: 015632bb30da ("bpf: sk_msg program helper bpf_sk_msg_pull_data") Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: John Fastabend <john.fastabend@gmail.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
committed by
Alexei Starovoitov
parent
2e43f95dd8
commit
a8cf76a902
@ -2282,6 +2282,13 @@ static const struct bpf_func_proto bpf_msg_cork_bytes_proto = {
|
||||
.arg2_type = ARG_ANYTHING,
|
||||
};
|
||||
|
||||
#define sk_msg_iter_var(var) \
|
||||
do { \
|
||||
var++; \
|
||||
if (var == MAX_SKB_FRAGS) \
|
||||
var = 0; \
|
||||
} while (0)
|
||||
|
||||
BPF_CALL_4(bpf_msg_pull_data,
|
||||
struct sk_msg_buff *, msg, u32, start, u32, end, u64, flags)
|
||||
{
|
||||
@ -2302,9 +2309,7 @@ BPF_CALL_4(bpf_msg_pull_data,
|
||||
if (start < offset + len)
|
||||
break;
|
||||
offset += len;
|
||||
i++;
|
||||
if (i == MAX_SKB_FRAGS)
|
||||
i = 0;
|
||||
sk_msg_iter_var(i);
|
||||
} while (i != msg->sg_end);
|
||||
|
||||
if (unlikely(start >= offset + len))
|
||||
@ -2330,9 +2335,7 @@ BPF_CALL_4(bpf_msg_pull_data,
|
||||
*/
|
||||
do {
|
||||
copy += sg[i].length;
|
||||
i++;
|
||||
if (i == MAX_SKB_FRAGS)
|
||||
i = 0;
|
||||
sk_msg_iter_var(i);
|
||||
if (bytes_sg_total <= copy)
|
||||
break;
|
||||
} while (i != msg->sg_end);
|
||||
@ -2358,9 +2361,7 @@ BPF_CALL_4(bpf_msg_pull_data,
|
||||
sg[i].length = 0;
|
||||
put_page(sg_page(&sg[i]));
|
||||
|
||||
i++;
|
||||
if (i == MAX_SKB_FRAGS)
|
||||
i = 0;
|
||||
sk_msg_iter_var(i);
|
||||
} while (i != last_sg);
|
||||
|
||||
sg[first_sg].length = copy;
|
||||
@ -2377,7 +2378,8 @@ BPF_CALL_4(bpf_msg_pull_data,
|
||||
if (!shift)
|
||||
goto out;
|
||||
|
||||
i = first_sg + 1;
|
||||
i = first_sg;
|
||||
sk_msg_iter_var(i);
|
||||
do {
|
||||
int move_from;
|
||||
|
||||
@ -2394,9 +2396,7 @@ BPF_CALL_4(bpf_msg_pull_data,
|
||||
sg[move_from].page_link = 0;
|
||||
sg[move_from].offset = 0;
|
||||
|
||||
i++;
|
||||
if (i == MAX_SKB_FRAGS)
|
||||
i = 0;
|
||||
sk_msg_iter_var(i);
|
||||
} while (1);
|
||||
msg->sg_end -= shift;
|
||||
if (msg->sg_end < 0)
|
||||
|
Reference in New Issue
Block a user