From 9772754380f98cacdc653056074bed6cd8f7368b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 12 Feb 2026 13:04:11 +0100 Subject: [PATCH] 6.12-stable patches added patches: vsock-test-verify-socket-options-after-setting-them.patch --- queue-6.12/series | 1 + ...fy-socket-options-after-setting-them.patch | 395 ++++++++++++++++++ 2 files changed, 396 insertions(+) create mode 100644 queue-6.12/vsock-test-verify-socket-options-after-setting-them.patch diff --git a/queue-6.12/series b/queue-6.12/series index 14ca567736..b1f6273145 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -1,2 +1,3 @@ net-tunnel-make-skb_vlan_inet_prepare-return-drop-reasons.patch io_uring-rw-recycle-buffers-manually-for-non-mshot-reads.patch +vsock-test-verify-socket-options-after-setting-them.patch diff --git a/queue-6.12/vsock-test-verify-socket-options-after-setting-them.patch b/queue-6.12/vsock-test-verify-socket-options-after-setting-them.patch new file mode 100644 index 0000000000..c3eb15fe46 --- /dev/null +++ b/queue-6.12/vsock-test-verify-socket-options-after-setting-them.patch @@ -0,0 +1,395 @@ +From 86814d8ffd55fd4ad19c512eccd721522a370fb2 Mon Sep 17 00:00:00 2001 +From: Konstantin Shkolnyy +Date: Tue, 3 Dec 2024 09:06:56 -0600 +Subject: vsock/test: verify socket options after setting them + +From: Konstantin Shkolnyy + +commit 86814d8ffd55fd4ad19c512eccd721522a370fb2 upstream. + +Replace setsockopt() calls with calls to functions that follow +setsockopt() with getsockopt() and check that the returned value and its +size are the same as have been set. (Except in vsock_perf.) + +Signed-off-by: Konstantin Shkolnyy +Reviewed-by: Stefano Garzarella +Signed-off-by: Paolo Abeni +[Stefano: patch needed to avoid vsock test build failure reported by + Johan Korsnes after backporting commit 0a98de8013696 ("vsock/test: fix + seqpacket message bounds test") in 6.12-stable tree] +Signed-off-by: Stefano Garzarella +Tested-by: Johan Korsnes +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/vsock/control.c | 9 - + tools/testing/vsock/msg_zerocopy_common.c | 10 -- + tools/testing/vsock/msg_zerocopy_common.h | 1 + tools/testing/vsock/util.c | 142 ++++++++++++++++++++++++++++++ + tools/testing/vsock/util.h | 7 + + tools/testing/vsock/vsock_perf.c | 10 ++ + tools/testing/vsock/vsock_test.c | 53 +++-------- + tools/testing/vsock/vsock_test_zerocopy.c | 2 + tools/testing/vsock/vsock_uring_test.c | 2 + 9 files changed, 182 insertions(+), 54 deletions(-) + +--- a/tools/testing/vsock/control.c ++++ b/tools/testing/vsock/control.c +@@ -27,6 +27,7 @@ + + #include "timeout.h" + #include "control.h" ++#include "util.h" + + static int control_fd = -1; + +@@ -50,7 +51,6 @@ void control_init(const char *control_ho + + for (ai = result; ai; ai = ai->ai_next) { + int fd; +- int val = 1; + + fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (fd < 0) +@@ -65,11 +65,8 @@ void control_init(const char *control_ho + break; + } + +- if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, +- &val, sizeof(val)) < 0) { +- perror("setsockopt"); +- exit(EXIT_FAILURE); +- } ++ setsockopt_int_check(fd, SOL_SOCKET, SO_REUSEADDR, 1, ++ "setsockopt SO_REUSEADDR"); + + if (bind(fd, ai->ai_addr, ai->ai_addrlen) < 0) + goto next; +--- a/tools/testing/vsock/msg_zerocopy_common.c ++++ b/tools/testing/vsock/msg_zerocopy_common.c +@@ -14,16 +14,6 @@ + + #include "msg_zerocopy_common.h" + +-void enable_so_zerocopy(int fd) +-{ +- int val = 1; +- +- if (setsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, &val, sizeof(val))) { +- perror("setsockopt"); +- exit(EXIT_FAILURE); +- } +-} +- + void vsock_recv_completion(int fd, const bool *zerocopied) + { + struct sock_extended_err *serr; +--- a/tools/testing/vsock/msg_zerocopy_common.h ++++ b/tools/testing/vsock/msg_zerocopy_common.h +@@ -12,7 +12,6 @@ + #define VSOCK_RECVERR 1 + #endif + +-void enable_so_zerocopy(int fd); + void vsock_recv_completion(int fd, const bool *zerocopied); + + #endif /* MSG_ZEROCOPY_COMMON_H */ +--- a/tools/testing/vsock/util.c ++++ b/tools/testing/vsock/util.c +@@ -663,3 +663,145 @@ void free_test_iovec(const struct iovec + + free(iovec); + } ++ ++/* Set "unsigned long long" socket option and check that it's indeed set */ ++void setsockopt_ull_check(int fd, int level, int optname, ++ unsigned long long val, char const *errmsg) ++{ ++ unsigned long long chkval; ++ socklen_t chklen; ++ int err; ++ ++ err = setsockopt(fd, level, optname, &val, sizeof(val)); ++ if (err) { ++ fprintf(stderr, "setsockopt err: %s (%d)\n", ++ strerror(errno), errno); ++ goto fail; ++ } ++ ++ chkval = ~val; /* just make storage != val */ ++ chklen = sizeof(chkval); ++ ++ err = getsockopt(fd, level, optname, &chkval, &chklen); ++ if (err) { ++ fprintf(stderr, "getsockopt err: %s (%d)\n", ++ strerror(errno), errno); ++ goto fail; ++ } ++ ++ if (chklen != sizeof(chkval)) { ++ fprintf(stderr, "size mismatch: set %zu got %d\n", sizeof(val), ++ chklen); ++ goto fail; ++ } ++ ++ if (chkval != val) { ++ fprintf(stderr, "value mismatch: set %llu got %llu\n", val, ++ chkval); ++ goto fail; ++ } ++ return; ++fail: ++ fprintf(stderr, "%s val %llu\n", errmsg, val); ++ exit(EXIT_FAILURE); ++; ++} ++ ++/* Set "int" socket option and check that it's indeed set */ ++void setsockopt_int_check(int fd, int level, int optname, int val, ++ char const *errmsg) ++{ ++ int chkval; ++ socklen_t chklen; ++ int err; ++ ++ err = setsockopt(fd, level, optname, &val, sizeof(val)); ++ if (err) { ++ fprintf(stderr, "setsockopt err: %s (%d)\n", ++ strerror(errno), errno); ++ goto fail; ++ } ++ ++ chkval = ~val; /* just make storage != val */ ++ chklen = sizeof(chkval); ++ ++ err = getsockopt(fd, level, optname, &chkval, &chklen); ++ if (err) { ++ fprintf(stderr, "getsockopt err: %s (%d)\n", ++ strerror(errno), errno); ++ goto fail; ++ } ++ ++ if (chklen != sizeof(chkval)) { ++ fprintf(stderr, "size mismatch: set %zu got %d\n", sizeof(val), ++ chklen); ++ goto fail; ++ } ++ ++ if (chkval != val) { ++ fprintf(stderr, "value mismatch: set %d got %d\n", val, chkval); ++ goto fail; ++ } ++ return; ++fail: ++ fprintf(stderr, "%s val %d\n", errmsg, val); ++ exit(EXIT_FAILURE); ++} ++ ++static void mem_invert(unsigned char *mem, size_t size) ++{ ++ size_t i; ++ ++ for (i = 0; i < size; i++) ++ mem[i] = ~mem[i]; ++} ++ ++/* Set "timeval" socket option and check that it's indeed set */ ++void setsockopt_timeval_check(int fd, int level, int optname, ++ struct timeval val, char const *errmsg) ++{ ++ struct timeval chkval; ++ socklen_t chklen; ++ int err; ++ ++ err = setsockopt(fd, level, optname, &val, sizeof(val)); ++ if (err) { ++ fprintf(stderr, "setsockopt err: %s (%d)\n", ++ strerror(errno), errno); ++ goto fail; ++ } ++ ++ /* just make storage != val */ ++ chkval = val; ++ mem_invert((unsigned char *)&chkval, sizeof(chkval)); ++ chklen = sizeof(chkval); ++ ++ err = getsockopt(fd, level, optname, &chkval, &chklen); ++ if (err) { ++ fprintf(stderr, "getsockopt err: %s (%d)\n", ++ strerror(errno), errno); ++ goto fail; ++ } ++ ++ if (chklen != sizeof(chkval)) { ++ fprintf(stderr, "size mismatch: set %zu got %d\n", sizeof(val), ++ chklen); ++ goto fail; ++ } ++ ++ if (memcmp(&chkval, &val, sizeof(val)) != 0) { ++ fprintf(stderr, "value mismatch: set %ld:%ld got %ld:%ld\n", ++ val.tv_sec, val.tv_usec, chkval.tv_sec, chkval.tv_usec); ++ goto fail; ++ } ++ return; ++fail: ++ fprintf(stderr, "%s val %ld:%ld\n", errmsg, val.tv_sec, val.tv_usec); ++ exit(EXIT_FAILURE); ++} ++ ++void enable_so_zerocopy_check(int fd) ++{ ++ setsockopt_int_check(fd, SOL_SOCKET, SO_ZEROCOPY, 1, ++ "setsockopt SO_ZEROCOPY"); ++} +--- a/tools/testing/vsock/util.h ++++ b/tools/testing/vsock/util.h +@@ -68,4 +68,11 @@ unsigned long iovec_hash_djb2(const stru + struct iovec *alloc_test_iovec(const struct iovec *test_iovec, int iovnum); + void free_test_iovec(const struct iovec *test_iovec, + struct iovec *iovec, int iovnum); ++void setsockopt_ull_check(int fd, int level, int optname, ++ unsigned long long val, char const *errmsg); ++void setsockopt_int_check(int fd, int level, int optname, int val, ++ char const *errmsg); ++void setsockopt_timeval_check(int fd, int level, int optname, ++ struct timeval val, char const *errmsg); ++void enable_so_zerocopy_check(int fd); + #endif /* UTIL_H */ +--- a/tools/testing/vsock/vsock_perf.c ++++ b/tools/testing/vsock/vsock_perf.c +@@ -251,6 +251,16 @@ static void run_receiver(int rcvlowat_by + close(fd); + } + ++static void enable_so_zerocopy(int fd) ++{ ++ int val = 1; ++ ++ if (setsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, &val, sizeof(val))) { ++ perror("setsockopt"); ++ exit(EXIT_FAILURE); ++ } ++} ++ + static void run_sender(int peer_cid, unsigned long to_send_bytes) + { + time_t tx_begin_ns; +--- a/tools/testing/vsock/vsock_test.c ++++ b/tools/testing/vsock/vsock_test.c +@@ -455,17 +455,13 @@ static void test_seqpacket_msg_bounds_se + + sock_buf_size = SOCK_BUF_SIZE; + +- if (setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_MAX_SIZE, +- &sock_buf_size, sizeof(sock_buf_size))) { +- perror("setsockopt(SO_VM_SOCKETS_BUFFER_MAX_SIZE)"); +- exit(EXIT_FAILURE); +- } +- +- if (setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE, +- &sock_buf_size, sizeof(sock_buf_size))) { +- perror("setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)"); +- exit(EXIT_FAILURE); +- } ++ setsockopt_ull_check(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_MAX_SIZE, ++ sock_buf_size, ++ "setsockopt(SO_VM_SOCKETS_BUFFER_MAX_SIZE)"); ++ ++ setsockopt_ull_check(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE, ++ sock_buf_size, ++ "setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)"); + + /* Ready to receive data. */ + control_writeln("SRVREADY"); +@@ -597,10 +593,8 @@ static void test_seqpacket_timeout_clien + tv.tv_sec = RCVTIMEO_TIMEOUT_SEC; + tv.tv_usec = 0; + +- if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, sizeof(tv)) == -1) { +- perror("setsockopt(SO_RCVTIMEO)"); +- exit(EXIT_FAILURE); +- } ++ setsockopt_timeval_check(fd, SOL_SOCKET, SO_RCVTIMEO, tv, ++ "setsockopt(SO_RCVTIMEO)"); + + read_enter_ns = current_nsec(); + +@@ -866,11 +860,8 @@ static void test_stream_poll_rcvlowat_cl + exit(EXIT_FAILURE); + } + +- if (setsockopt(fd, SOL_SOCKET, SO_RCVLOWAT, +- &lowat_val, sizeof(lowat_val))) { +- perror("setsockopt(SO_RCVLOWAT)"); +- exit(EXIT_FAILURE); +- } ++ setsockopt_int_check(fd, SOL_SOCKET, SO_RCVLOWAT, ++ lowat_val, "setsockopt(SO_RCVLOWAT)"); + + control_expectln("SRVSENT"); + +@@ -1398,11 +1389,9 @@ static void test_stream_credit_update_te + /* size_t can be < unsigned long long */ + sock_buf_size = buf_size; + +- if (setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE, +- &sock_buf_size, sizeof(sock_buf_size))) { +- perror("setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)"); +- exit(EXIT_FAILURE); +- } ++ setsockopt_ull_check(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE, ++ sock_buf_size, ++ "setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)"); + + if (low_rx_bytes_test) { + /* Set new SO_RCVLOWAT here. This enables sending credit +@@ -1411,11 +1400,8 @@ static void test_stream_credit_update_te + */ + recv_buf_size = 1 + VIRTIO_VSOCK_MAX_PKT_BUF_SIZE; + +- if (setsockopt(fd, SOL_SOCKET, SO_RCVLOWAT, +- &recv_buf_size, sizeof(recv_buf_size))) { +- perror("setsockopt(SO_RCVLOWAT)"); +- exit(EXIT_FAILURE); +- } ++ setsockopt_int_check(fd, SOL_SOCKET, SO_RCVLOWAT, ++ recv_buf_size, "setsockopt(SO_RCVLOWAT)"); + } + + /* Send one dummy byte here, because 'setsockopt()' above also +@@ -1457,11 +1443,8 @@ static void test_stream_credit_update_te + recv_buf_size++; + + /* Updating SO_RCVLOWAT will send credit update. */ +- if (setsockopt(fd, SOL_SOCKET, SO_RCVLOWAT, +- &recv_buf_size, sizeof(recv_buf_size))) { +- perror("setsockopt(SO_RCVLOWAT)"); +- exit(EXIT_FAILURE); +- } ++ setsockopt_int_check(fd, SOL_SOCKET, SO_RCVLOWAT, ++ recv_buf_size, "setsockopt(SO_RCVLOWAT)"); + } + + fds.fd = fd; +--- a/tools/testing/vsock/vsock_test_zerocopy.c ++++ b/tools/testing/vsock/vsock_test_zerocopy.c +@@ -162,7 +162,7 @@ static void test_client(const struct tes + } + + if (test_data->so_zerocopy) +- enable_so_zerocopy(fd); ++ enable_so_zerocopy_check(fd); + + iovec = alloc_test_iovec(test_data->vecs, test_data->vecs_cnt); + +--- a/tools/testing/vsock/vsock_uring_test.c ++++ b/tools/testing/vsock/vsock_uring_test.c +@@ -73,7 +73,7 @@ static void vsock_io_uring_client(const + } + + if (msg_zerocopy) +- enable_so_zerocopy(fd); ++ enable_so_zerocopy_check(fd); + + iovec = alloc_test_iovec(test_data->vecs, test_data->vecs_cnt); + -- 2.47.3