Skip to content

Commit 62d02fc

Browse files
committed
Martin KaFai Lau says: ==================== pull-request: bpf 2023-08-09 We've added 5 non-merge commits during the last 7 day(s) which contain a total of 6 files changed, 102 insertions(+), 8 deletions(-). The main changes are: 1) A bpf sockmap memleak fix and a fix in accessing the programs of a sockmap under the incorrect map type from Xu Kuohai. 2) A refcount underflow fix in xsk from Magnus Karlsson. * tag 'for-netdev' of https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf: selftests/bpf: Add sockmap test for redirecting partial skb data selftests/bpf: fix a CI failure caused by vsock sockmap test bpf, sockmap: Fix bug that strp_done cannot be called bpf, sockmap: Fix map type error in sock_map_del_link xsk: fix refcount underflow in error path ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 6db541a + b734f02 commit 62d02fc

File tree

6 files changed

+102
-8
lines changed

6 files changed

+102
-8
lines changed

include/linux/skmsg.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ struct sk_psock_progs {
6262

6363
enum sk_psock_state_bits {
6464
SK_PSOCK_TX_ENABLED,
65+
SK_PSOCK_RX_STRP_ENABLED,
6566
};
6667

6768
struct sk_psock_link {

net/core/skmsg.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,13 +1120,19 @@ static void sk_psock_strp_data_ready(struct sock *sk)
11201120

11211121
int sk_psock_init_strp(struct sock *sk, struct sk_psock *psock)
11221122
{
1123+
int ret;
1124+
11231125
static const struct strp_callbacks cb = {
11241126
.rcv_msg = sk_psock_strp_read,
11251127
.read_sock_done = sk_psock_strp_read_done,
11261128
.parse_msg = sk_psock_strp_parse,
11271129
};
11281130

1129-
return strp_init(&psock->strp, sk, &cb);
1131+
ret = strp_init(&psock->strp, sk, &cb);
1132+
if (!ret)
1133+
sk_psock_set_state(psock, SK_PSOCK_RX_STRP_ENABLED);
1134+
1135+
return ret;
11301136
}
11311137

11321138
void sk_psock_start_strp(struct sock *sk, struct sk_psock *psock)
@@ -1154,7 +1160,7 @@ void sk_psock_stop_strp(struct sock *sk, struct sk_psock *psock)
11541160
static void sk_psock_done_strp(struct sk_psock *psock)
11551161
{
11561162
/* Parser has been stopped */
1157-
if (psock->progs.stream_parser)
1163+
if (sk_psock_test_state(psock, SK_PSOCK_RX_STRP_ENABLED))
11581164
strp_done(&psock->strp);
11591165
}
11601166
#else

net/core/sock_map.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,13 +146,13 @@ static void sock_map_del_link(struct sock *sk,
146146
list_for_each_entry_safe(link, tmp, &psock->link, list) {
147147
if (link->link_raw == link_raw) {
148148
struct bpf_map *map = link->map;
149-
struct bpf_stab *stab = container_of(map, struct bpf_stab,
150-
map);
151-
if (psock->saved_data_ready && stab->progs.stream_parser)
149+
struct sk_psock_progs *progs = sock_map_progs(map);
150+
151+
if (psock->saved_data_ready && progs->stream_parser)
152152
strp_stop = true;
153-
if (psock->saved_data_ready && stab->progs.stream_verdict)
153+
if (psock->saved_data_ready && progs->stream_verdict)
154154
verdict_stop = true;
155-
if (psock->saved_data_ready && stab->progs.skb_verdict)
155+
if (psock->saved_data_ready && progs->skb_verdict)
156156
verdict_stop = true;
157157
list_del(&link->list);
158158
sk_psock_free_link(link);

net/xdp/xsk.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,7 @@ static int xsk_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
994994
err = xp_alloc_tx_descs(xs->pool, xs);
995995
if (err) {
996996
xp_put_pool(xs->pool);
997+
xs->pool = NULL;
997998
sockfd_put(sock);
998999
goto out_unlock;
9991000
}

tools/testing/selftests/bpf/prog_tests/sockmap_listen.c

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,77 @@ static void test_msg_redir_to_listening(struct test_sockmap_listen *skel,
869869
xbpf_prog_detach2(verdict, sock_map, BPF_SK_MSG_VERDICT);
870870
}
871871

872+
static void redir_partial(int family, int sotype, int sock_map, int parser_map)
873+
{
874+
int s, c0, c1, p0, p1;
875+
int err, n, key, value;
876+
char buf[] = "abc";
877+
878+
key = 0;
879+
value = sizeof(buf) - 1;
880+
err = xbpf_map_update_elem(parser_map, &key, &value, 0);
881+
if (err)
882+
return;
883+
884+
s = socket_loopback(family, sotype | SOCK_NONBLOCK);
885+
if (s < 0)
886+
goto clean_parser_map;
887+
888+
err = create_socket_pairs(s, family, sotype, &c0, &c1, &p0, &p1);
889+
if (err)
890+
goto close_srv;
891+
892+
err = add_to_sockmap(sock_map, p0, p1);
893+
if (err)
894+
goto close;
895+
896+
n = xsend(c1, buf, sizeof(buf), 0);
897+
if (n < sizeof(buf))
898+
FAIL("incomplete write");
899+
900+
n = xrecv_nonblock(c0, buf, sizeof(buf), 0);
901+
if (n != sizeof(buf) - 1)
902+
FAIL("expect %zu, received %d", sizeof(buf) - 1, n);
903+
904+
close:
905+
xclose(c0);
906+
xclose(p0);
907+
xclose(c1);
908+
xclose(p1);
909+
close_srv:
910+
xclose(s);
911+
912+
clean_parser_map:
913+
key = 0;
914+
value = 0;
915+
xbpf_map_update_elem(parser_map, &key, &value, 0);
916+
}
917+
918+
static void test_skb_redir_partial(struct test_sockmap_listen *skel,
919+
struct bpf_map *inner_map, int family,
920+
int sotype)
921+
{
922+
int verdict = bpf_program__fd(skel->progs.prog_stream_verdict);
923+
int parser = bpf_program__fd(skel->progs.prog_stream_parser);
924+
int parser_map = bpf_map__fd(skel->maps.parser_map);
925+
int sock_map = bpf_map__fd(inner_map);
926+
int err;
927+
928+
err = xbpf_prog_attach(parser, sock_map, BPF_SK_SKB_STREAM_PARSER, 0);
929+
if (err)
930+
return;
931+
932+
err = xbpf_prog_attach(verdict, sock_map, BPF_SK_SKB_STREAM_VERDICT, 0);
933+
if (err)
934+
goto detach;
935+
936+
redir_partial(family, sotype, sock_map, parser_map);
937+
938+
xbpf_prog_detach2(verdict, sock_map, BPF_SK_SKB_STREAM_VERDICT);
939+
detach:
940+
xbpf_prog_detach2(parser, sock_map, BPF_SK_SKB_STREAM_PARSER);
941+
}
942+
872943
static void test_reuseport_select_listening(int family, int sotype,
873944
int sock_map, int verd_map,
874945
int reuseport_prog)
@@ -1243,6 +1314,7 @@ static void test_redir(struct test_sockmap_listen *skel, struct bpf_map *map,
12431314
} tests[] = {
12441315
TEST(test_skb_redir_to_connected),
12451316
TEST(test_skb_redir_to_listening),
1317+
TEST(test_skb_redir_partial),
12461318
TEST(test_msg_redir_to_connected),
12471319
TEST(test_msg_redir_to_listening),
12481320
};
@@ -1432,7 +1504,7 @@ static void vsock_unix_redir_connectible(int sock_mapfd, int verd_mapfd,
14321504
if (n < 1)
14331505
goto out;
14341506

1435-
n = recv(mode == REDIR_INGRESS ? u0 : u1, &b, sizeof(b), MSG_DONTWAIT);
1507+
n = xrecv_nonblock(mode == REDIR_INGRESS ? u0 : u1, &b, sizeof(b), 0);
14361508
if (n < 0)
14371509
FAIL("%s: recv() err, errno=%d", log_prefix, errno);
14381510
if (n == 0)

tools/testing/selftests/bpf/progs/test_sockmap_listen.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,26 @@ struct {
2828
__type(value, unsigned int);
2929
} verdict_map SEC(".maps");
3030

31+
struct {
32+
__uint(type, BPF_MAP_TYPE_ARRAY);
33+
__uint(max_entries, 1);
34+
__type(key, int);
35+
__type(value, int);
36+
} parser_map SEC(".maps");
37+
3138
bool test_sockmap = false; /* toggled by user-space */
3239
bool test_ingress = false; /* toggled by user-space */
3340

3441
SEC("sk_skb/stream_parser")
3542
int prog_stream_parser(struct __sk_buff *skb)
3643
{
44+
int *value;
45+
__u32 key = 0;
46+
47+
value = bpf_map_lookup_elem(&parser_map, &key);
48+
if (value && *value)
49+
return *value;
50+
3751
return skb->len;
3852
}
3953

0 commit comments

Comments
 (0)