Commit d73549b8 authored by Kuniyuki Iwashima's avatar Kuniyuki Iwashima Committed by Martin KaFai Lau
Browse files

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: default avatarKuniyuki Iwashima <kuniyu@google.com>
Signed-off-by: default avatarMartin KaFai Lau <martin.lau@kernel.org>
Link: https://patch.msgid.link/20260504210610.180150-3-kuniyu@google.com
parent 481c2265
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -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;
+16 −0
Original line number Diff line number Diff line
@@ -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.
			   */