selftest: bpf: Add test for bpf_tcp_sock() and RAW socket.

Let's extend sockopt_sk.c to cover bpf_tcp_sock() for the
wrong socket type.

Before:
  # ./test_progs -t sockopt_sk
  [  151.948613] ==================================================================
  [  151.951376] BUG: KASAN: slab-out-of-bounds in sol_tcp_sockopt+0xc7/0x8e0
  [  151.954159] Read of size 8 at addr ffff88801083d760 by task test_progs/1259
  ...
  run_test:FAIL:getsetsockopt unexpected error: -1 (errno 0)
  #427     sockopt_sk:FAIL

After:
  #427     sockopt_sk:OK

While at it, missing free() is fixed up.

Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
Link: https://patch.msgid.link/20260504210610.180150-3-kuniyu@google.com
This commit is contained in:
Kuniyuki Iwashima 2026-05-04 21:04:49 +00:00 committed by Martin KaFai Lau
parent 481c226528
commit d73549b8bb
2 changed files with 32 additions and 1 deletions

View File

@ -190,7 +190,7 @@ static int getsetsockopt(void)
fd = socket(AF_NETLINK, SOCK_RAW, 0);
if (fd < 0) {
log_err("Failed to create AF_NETLINK socket");
return -1;
goto err;
}
buf.u32 = 1;
@ -211,6 +211,21 @@ static int getsetsockopt(void)
}
ASSERT_EQ(optlen, 8, "Unexpected NETLINK_LIST_MEMBERSHIPS value");
/* Trick bpf_tcp_sock() with IPPROTO_TCP */
close(fd);
fd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
if (!ASSERT_OK_FD(fd, "socket"))
goto err;
/* The BPF prog intercepts this before the kernel sees it, any
* optlen works. Go with 4 bytes for simplicity.
*/
buf.u32 = 1;
optlen = sizeof(buf.u32);
err = setsockopt(fd, SOL_TCP, TCP_SAVED_SYN, &buf, optlen);
if (!ASSERT_ERR(err, "setsockopt(TCP_SAVED_SYN)"))
goto err;
free(big_buf);
close(fd);
return 0;

View File

@ -149,6 +149,20 @@ int _setsockopt(struct bpf_sockopt *ctx)
if (sk && sk->family == AF_NETLINK)
goto out;
if (sk && sk->family == AF_INET && sk->type == SOCK_RAW) {
struct bpf_tcp_sock *tp = bpf_tcp_sock(sk);
if (tp) {
char saved_syn[60];
bpf_getsockopt(sk, SOL_TCP, TCP_SAVED_SYN,
&saved_syn, sizeof(saved_syn));
goto consumed;
}
goto out;
}
/* Make sure bpf_get_netns_cookie is callable.
*/
if (bpf_get_netns_cookie(NULL) == 0)
@ -224,6 +238,8 @@ int _setsockopt(struct bpf_sockopt *ctx)
return 0; /* couldn't get sk storage */
storage->val = optval[0];
consumed:
ctx->optlen = -1; /* BPF has consumed this option, don't call kernel
* setsockopt handler.
*/