Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/net: Add sk_bind_sendto_listen and sk_connect_zero_addr

This patch adds 2 new tests: sk_bind_sendto_listen and
sk_connect_zero_addr.

The sk_bind_sendto_listen test exercises the path where a socket's
rcv saddr changes after it has been added to the binding tables,
and then a listen() on the socket is invoked. The listen() should
succeed.

The sk_bind_sendto_listen test is copied over from one of syzbot's
tests: https://syzkaller.appspot.com/x/repro.c?x=1673a38df00000

The sk_connect_zero_addr test exercises the path where the socket was
never previously added to the binding tables and it gets assigned a
saddr upon a connect() to address 0.

Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Joanne Koong and committed by
Jakub Kicinski
1be9ac87 c35ecb95

+146
+2
tools/testing/selftests/net/.gitignore
··· 41 41 unix_connect 42 42 tap 43 43 bind_bhash 44 + sk_bind_sendto_listen 45 + sk_connect_zero_addr
+2
tools/testing/selftests/net/Makefile
··· 66 66 TEST_PROGS += test_vxlan_vnifiltering.sh 67 67 TEST_GEN_FILES += io_uring_zerocopy_tx 68 68 TEST_GEN_FILES += bind_bhash 69 + TEST_GEN_PROGS += sk_bind_sendto_listen 70 + TEST_GEN_PROGS += sk_connect_zero_addr 69 71 70 72 TEST_FILES := settings 71 73
+80
tools/testing/selftests/net/sk_bind_sendto_listen.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <arpa/inet.h> 4 + #include <error.h> 5 + #include <errno.h> 6 + #include <unistd.h> 7 + 8 + int main(void) 9 + { 10 + int fd1, fd2, one = 1; 11 + struct sockaddr_in6 bind_addr = { 12 + .sin6_family = AF_INET6, 13 + .sin6_port = htons(20000), 14 + .sin6_flowinfo = htonl(0), 15 + .sin6_addr = {}, 16 + .sin6_scope_id = 0, 17 + }; 18 + 19 + inet_pton(AF_INET6, "::", &bind_addr.sin6_addr); 20 + 21 + fd1 = socket(AF_INET6, SOCK_STREAM, IPPROTO_IP); 22 + if (fd1 < 0) { 23 + error(1, errno, "socket fd1"); 24 + return -1; 25 + } 26 + 27 + if (setsockopt(fd1, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) { 28 + error(1, errno, "setsockopt(SO_REUSEADDR) fd1"); 29 + goto out_err1; 30 + } 31 + 32 + if (bind(fd1, (struct sockaddr *)&bind_addr, sizeof(bind_addr))) { 33 + error(1, errno, "bind fd1"); 34 + goto out_err1; 35 + } 36 + 37 + if (sendto(fd1, NULL, 0, MSG_FASTOPEN, (struct sockaddr *)&bind_addr, 38 + sizeof(bind_addr))) { 39 + error(1, errno, "sendto fd1"); 40 + goto out_err1; 41 + } 42 + 43 + fd2 = socket(AF_INET6, SOCK_STREAM, IPPROTO_IP); 44 + if (fd2 < 0) { 45 + error(1, errno, "socket fd2"); 46 + goto out_err1; 47 + } 48 + 49 + if (setsockopt(fd2, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) { 50 + error(1, errno, "setsockopt(SO_REUSEADDR) fd2"); 51 + goto out_err2; 52 + } 53 + 54 + if (bind(fd2, (struct sockaddr *)&bind_addr, sizeof(bind_addr))) { 55 + error(1, errno, "bind fd2"); 56 + goto out_err2; 57 + } 58 + 59 + if (sendto(fd2, NULL, 0, MSG_FASTOPEN, (struct sockaddr *)&bind_addr, 60 + sizeof(bind_addr)) != -1) { 61 + error(1, errno, "sendto fd2"); 62 + goto out_err2; 63 + } 64 + 65 + if (listen(fd2, 0)) { 66 + error(1, errno, "listen"); 67 + goto out_err2; 68 + } 69 + 70 + close(fd2); 71 + close(fd1); 72 + return 0; 73 + 74 + out_err2: 75 + close(fd2); 76 + 77 + out_err1: 78 + close(fd1); 79 + return -1; 80 + }
+62
tools/testing/selftests/net/sk_connect_zero_addr.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <arpa/inet.h> 4 + #include <error.h> 5 + #include <errno.h> 6 + #include <unistd.h> 7 + 8 + int main(void) 9 + { 10 + int fd1, fd2, one = 1; 11 + struct sockaddr_in6 bind_addr = { 12 + .sin6_family = AF_INET6, 13 + .sin6_port = htons(20000), 14 + .sin6_flowinfo = htonl(0), 15 + .sin6_addr = {}, 16 + .sin6_scope_id = 0, 17 + }; 18 + 19 + inet_pton(AF_INET6, "::", &bind_addr.sin6_addr); 20 + 21 + fd1 = socket(AF_INET6, SOCK_STREAM, IPPROTO_IP); 22 + if (fd1 < 0) { 23 + error(1, errno, "socket fd1"); 24 + return -1; 25 + } 26 + 27 + if (setsockopt(fd1, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) { 28 + error(1, errno, "setsockopt(SO_REUSEADDR) fd1"); 29 + goto out_err1; 30 + } 31 + 32 + if (bind(fd1, (struct sockaddr *)&bind_addr, sizeof(bind_addr))) { 33 + error(1, errno, "bind fd1"); 34 + goto out_err1; 35 + } 36 + 37 + if (listen(fd1, 0)) { 38 + error(1, errno, "listen"); 39 + goto out_err1; 40 + } 41 + 42 + fd2 = socket(AF_INET6, SOCK_STREAM, IPPROTO_IP); 43 + if (fd2 < 0) { 44 + error(1, errno, "socket fd2"); 45 + goto out_err1; 46 + } 47 + 48 + if (connect(fd2, (struct sockaddr *)&bind_addr, sizeof(bind_addr))) { 49 + error(1, errno, "bind fd2"); 50 + goto out_err2; 51 + } 52 + 53 + close(fd2); 54 + close(fd1); 55 + return 0; 56 + 57 + out_err2: 58 + close(fd2); 59 + out_err1: 60 + close(fd1); 61 + return -1; 62 + }