mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
selftests/bpf: add test for bpf_msg_pop_data() overflow
Add a test in sockmap_basic.c that calls bpf_msg_pop_data() with a length close to U32_MAX, which overflows the start + len bounds check. The sk_msg program records the return value over a sendmsg and the test checks that the call is rejected with -EINVAL. Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev> Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com> Cc: Jiayuan Chen <jiayuan.chen@linux.dev> Signed-off-by: Sechang Lim <rhkrqnwk98@gmail.com> Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev> Link: https://lore.kernel.org/r/20260615021959.140010-7-jiayuan.chen@linux.dev Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
a48802fb2c
commit
70b139d048
|
|
@ -14,6 +14,7 @@
|
|||
#include "test_sockmap_pass_prog.skel.h"
|
||||
#include "test_sockmap_drop_prog.skel.h"
|
||||
#include "test_sockmap_change_tail.skel.h"
|
||||
#include "test_sockmap_msg_pop_data.skel.h"
|
||||
#include "bpf_iter_sockmap.skel.h"
|
||||
|
||||
#include "sockmap_helpers.h"
|
||||
|
|
@ -666,6 +667,51 @@ static void test_sockmap_skb_verdict_change_tail(void)
|
|||
test_sockmap_change_tail__destroy(skel);
|
||||
}
|
||||
|
||||
static void test_sockmap_msg_verdict_pop_data(void)
|
||||
{
|
||||
struct test_sockmap_msg_pop_data *skel;
|
||||
int err, map, verdict;
|
||||
int c1 = -1, p1 = -1, sent;
|
||||
int zero = 0;
|
||||
char *buf;
|
||||
const size_t len = 32 * 1024;
|
||||
|
||||
skel = test_sockmap_msg_pop_data__open_and_load();
|
||||
if (!ASSERT_OK_PTR(skel, "open_and_load"))
|
||||
return;
|
||||
|
||||
verdict = bpf_program__fd(skel->progs.prog_msg_pop_data);
|
||||
map = bpf_map__fd(skel->maps.sock_map);
|
||||
|
||||
err = bpf_prog_attach(verdict, map, BPF_SK_MSG_VERDICT, 0);
|
||||
if (!ASSERT_OK(err, "bpf_prog_attach"))
|
||||
goto out;
|
||||
|
||||
err = create_pair(AF_INET, SOCK_STREAM, &c1, &p1);
|
||||
if (!ASSERT_OK(err, "create_pair"))
|
||||
goto out;
|
||||
|
||||
err = bpf_map_update_elem(map, &zero, &c1, BPF_NOEXIST);
|
||||
if (!ASSERT_OK(err, "bpf_map_update_elem"))
|
||||
goto out_close;
|
||||
|
||||
buf = calloc(len, 1);
|
||||
if (!ASSERT_OK_PTR(buf, "calloc"))
|
||||
goto out_close;
|
||||
|
||||
sent = xsend(c1, buf, len, 0);
|
||||
ASSERT_EQ(sent, (ssize_t)len, "xsend");
|
||||
ASSERT_EQ(skel->data->pop_data_ret, -EINVAL, "pop_data_rejects overflow");
|
||||
|
||||
free(buf);
|
||||
|
||||
out_close:
|
||||
close(c1);
|
||||
close(p1);
|
||||
out:
|
||||
test_sockmap_msg_pop_data__destroy(skel);
|
||||
}
|
||||
|
||||
static void test_sockmap_skb_verdict_peek_helper(int map)
|
||||
{
|
||||
int err, c1, p1, zero = 0, sent, recvd, avail;
|
||||
|
|
@ -1373,6 +1419,8 @@ void test_sockmap_basic(void)
|
|||
test_sockmap_skb_verdict_fionread(false);
|
||||
if (test__start_subtest("sockmap skb_verdict change tail"))
|
||||
test_sockmap_skb_verdict_change_tail();
|
||||
if (test__start_subtest("sockmap msg_verdict pop_data overflow"))
|
||||
test_sockmap_msg_verdict_pop_data();
|
||||
if (test__start_subtest("sockmap skb_verdict msg_f_peek"))
|
||||
test_sockmap_skb_verdict_peek();
|
||||
if (test__start_subtest("sockmap skb_verdict msg_f_peek with link"))
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include "vmlinux.h"
|
||||
#include <bpf/bpf_helpers.h>
|
||||
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_SOCKMAP);
|
||||
__uint(max_entries, 1);
|
||||
__type(key, int);
|
||||
__type(value, int);
|
||||
} sock_map SEC(".maps");
|
||||
|
||||
#define POP_START 0x48a3
|
||||
#define POP_LEN 0xfffffffd
|
||||
|
||||
long pop_data_ret = 1;
|
||||
|
||||
SEC("sk_msg")
|
||||
int prog_msg_pop_data(struct sk_msg_md *msg)
|
||||
{
|
||||
if (msg->size <= POP_START)
|
||||
return SK_PASS;
|
||||
|
||||
pop_data_ret = bpf_msg_pop_data(msg, POP_START, POP_LEN, 0);
|
||||
return SK_PASS;
|
||||
}
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
||||
Loading…
Reference in New Issue
Block a user