Blame SOURCES/0154-tests-call-setsockopt-directly-in-sockopt-timestamp.patch

03d83a
From 719ccf8f4bf4263b02c686f16f579fd6119bb52c Mon Sep 17 00:00:00 2001
03d83a
From: Eugene Syromyatnikov <evgsyr@gmail.com>
03d83a
Date: Mon, 23 Aug 2021 18:24:39 +0200
03d83a
Subject: [PATCH] tests: call setsockopt directly in sockopt-timestamp
03d83a
03d83a
While commit v5.13-10-g0211fdc "tests: change sockopt-timestamp test to
03d83a
use syscall(__NR_recvmsg)" has fixed issues with glibc-induced mangling
03d83a
on newer kernels, the combination of an older kernel and new glibc still
03d83a
causes issues, as glibc silently falls back to SO_TIMESTAMP{,NS}_OLD, as
03d83a
implemented in glibc-2.34~294 "linux: Add fallback for 64-bit time_t
03d83a
SO_TIMESTAMP{NS}".  Avoid that by calling setsockopt directly as well.
03d83a
03d83a
* tests/sockopt-timestamp.c (SC_setsockopt): New macro constant.
03d83a
(k_setsockopt): New function.
03d83a
(test_sockopt): Call k_setsockopt instead of setsockopt.
03d83a
03d83a
Complements: v5.13-10-g0211fdc "tests: change sockopt-timestamp test to use syscall(__NR_recvmsg)"
03d83a
---
03d83a
 tests/sockopt-timestamp.c | 31 ++++++++++++++++++++++++++++++-
03d83a
 1 file changed, 30 insertions(+), 1 deletion(-)
03d83a
03d83a
diff --git a/tests/sockopt-timestamp.c b/tests/sockopt-timestamp.c
03d83a
index 34c4d89..4bd96fd 100644
03d83a
--- a/tests/sockopt-timestamp.c
03d83a
+++ b/tests/sockopt-timestamp.c
03d83a
@@ -48,6 +48,30 @@ k_recvmsg(const unsigned int fd, const void *const ptr, const unsigned int flags
03d83a
 	return rc;
03d83a
 }
03d83a
 
03d83a
+#define SC_setsockopt 14
03d83a
+static long
03d83a
+k_setsockopt(const unsigned int fd, const unsigned int level,
03d83a
+	     const unsigned int optname, const void *const optval,
03d83a
+	     const unsigned int len)
03d83a
+{
03d83a
+	const kernel_ulong_t fill = (kernel_ulong_t) 0xdefaced00000000ULL;
03d83a
+#ifdef __NR_setsockopt
03d83a
+	const kernel_ulong_t bad = (kernel_ulong_t) 0xbadc0dedbadc0dedULL;
03d83a
+#endif
03d83a
+
03d83a
+	return syscall(
03d83a
+#ifdef __NR_setsockopt
03d83a
+		__NR_setsockopt,
03d83a
+#else /* socketcall */
03d83a
+		__NR_socketcall, SC_setsockopt,
03d83a
+#endif
03d83a
+		fill | fd , fill | level, fill | optname, optval, fill | len
03d83a
+#ifdef __NR_setsockopt
03d83a
+		, bad
03d83a
+#endif
03d83a
+		);
03d83a
+}
03d83a
+
03d83a
 static void
03d83a
 print_timestamp_old(const struct cmsghdr *c)
03d83a
 {
03d83a
@@ -139,7 +163,12 @@ test_sockopt(int so_val, const char *str, void (*fun)(const struct cmsghdr *))
03d83a
 		perror_msg_and_skip(data);
03d83a
 
03d83a
 	const int opt_1 = 1;
03d83a
-	if (setsockopt(sv[0], SOL_SOCKET, so_val, &opt_1, sizeof(opt_1))) {
03d83a
+	/*
03d83a
+	 * glibc-2.34~294 adds fallsback for SO_TIMESTAMP{,NS}_NEW that calls
03d83a
+	 * SO_TIMESTAMP{,NS}_OLD, so we have to call the setsockopt directly
03d83a
+	 * in order to avoid unexpected recvmsg msg types.
03d83a
+	 */
03d83a
+	if (k_setsockopt(sv[0], SOL_SOCKET, so_val, &opt_1, sizeof(opt_1))) {
03d83a
 		perror(str);
03d83a
 		return 0;
03d83a
 	}
03d83a
diff --git a/tests-m32/sockopt-timestamp.c b/tests-m32/sockopt-timestamp.c
03d83a
index 34c4d89..4bd96fd 100644
03d83a
--- a/tests-m32/sockopt-timestamp.c
03d83a
+++ b/tests-m32/sockopt-timestamp.c
03d83a
@@ -48,6 +48,30 @@ k_recvmsg(const unsigned int fd, const void *const ptr, const unsigned int flags
03d83a
 	return rc;
03d83a
 }
03d83a
 
03d83a
+#define SC_setsockopt 14
03d83a
+static long
03d83a
+k_setsockopt(const unsigned int fd, const unsigned int level,
03d83a
+	     const unsigned int optname, const void *const optval,
03d83a
+	     const unsigned int len)
03d83a
+{
03d83a
+	const kernel_ulong_t fill = (kernel_ulong_t) 0xdefaced00000000ULL;
03d83a
+#ifdef __NR_setsockopt
03d83a
+	const kernel_ulong_t bad = (kernel_ulong_t) 0xbadc0dedbadc0dedULL;
03d83a
+#endif
03d83a
+
03d83a
+	return syscall(
03d83a
+#ifdef __NR_setsockopt
03d83a
+		__NR_setsockopt,
03d83a
+#else /* socketcall */
03d83a
+		__NR_socketcall, SC_setsockopt,
03d83a
+#endif
03d83a
+		fill | fd , fill | level, fill | optname, optval, fill | len
03d83a
+#ifdef __NR_setsockopt
03d83a
+		, bad
03d83a
+#endif
03d83a
+		);
03d83a
+}
03d83a
+
03d83a
 static void
03d83a
 print_timestamp_old(const struct cmsghdr *c)
03d83a
 {
03d83a
@@ -139,7 +163,12 @@ test_sockopt(int so_val, const char *str, void (*fun)(const struct cmsghdr *))
03d83a
 		perror_msg_and_skip(data);
03d83a
 
03d83a
 	const int opt_1 = 1;
03d83a
-	if (setsockopt(sv[0], SOL_SOCKET, so_val, &opt_1, sizeof(opt_1))) {
03d83a
+	/*
03d83a
+	 * glibc-2.34~294 adds fallsback for SO_TIMESTAMP{,NS}_NEW that calls
03d83a
+	 * SO_TIMESTAMP{,NS}_OLD, so we have to call the setsockopt directly
03d83a
+	 * in order to avoid unexpected recvmsg msg types.
03d83a
+	 */
03d83a
+	if (k_setsockopt(sv[0], SOL_SOCKET, so_val, &opt_1, sizeof(opt_1))) {
03d83a
 		perror(str);
03d83a
 		return 0;
03d83a
 	}
03d83a
diff --git a/tests-mx32/sockopt-timestamp.c b/tests-mx32/sockopt-timestamp.c
03d83a
index 34c4d89..4bd96fd 100644
03d83a
--- a/tests-mx32/sockopt-timestamp.c
03d83a
+++ b/tests-mx32/sockopt-timestamp.c
03d83a
@@ -48,6 +48,30 @@ k_recvmsg(const unsigned int fd, const void *const ptr, const unsigned int flags
03d83a
 	return rc;
03d83a
 }
03d83a
 
03d83a
+#define SC_setsockopt 14
03d83a
+static long
03d83a
+k_setsockopt(const unsigned int fd, const unsigned int level,
03d83a
+	     const unsigned int optname, const void *const optval,
03d83a
+	     const unsigned int len)
03d83a
+{
03d83a
+	const kernel_ulong_t fill = (kernel_ulong_t) 0xdefaced00000000ULL;
03d83a
+#ifdef __NR_setsockopt
03d83a
+	const kernel_ulong_t bad = (kernel_ulong_t) 0xbadc0dedbadc0dedULL;
03d83a
+#endif
03d83a
+
03d83a
+	return syscall(
03d83a
+#ifdef __NR_setsockopt
03d83a
+		__NR_setsockopt,
03d83a
+#else /* socketcall */
03d83a
+		__NR_socketcall, SC_setsockopt,
03d83a
+#endif
03d83a
+		fill | fd , fill | level, fill | optname, optval, fill | len
03d83a
+#ifdef __NR_setsockopt
03d83a
+		, bad
03d83a
+#endif
03d83a
+		);
03d83a
+}
03d83a
+
03d83a
 static void
03d83a
 print_timestamp_old(const struct cmsghdr *c)
03d83a
 {
03d83a
@@ -139,7 +163,12 @@ test_sockopt(int so_val, const char *str, void (*fun)(const struct cmsghdr *))
03d83a
 		perror_msg_and_skip(data);
03d83a
 
03d83a
 	const int opt_1 = 1;
03d83a
-	if (setsockopt(sv[0], SOL_SOCKET, so_val, &opt_1, sizeof(opt_1))) {
03d83a
+	/*
03d83a
+	 * glibc-2.34~294 adds fallsback for SO_TIMESTAMP{,NS}_NEW that calls
03d83a
+	 * SO_TIMESTAMP{,NS}_OLD, so we have to call the setsockopt directly
03d83a
+	 * in order to avoid unexpected recvmsg msg types.
03d83a
+	 */
03d83a
+	if (k_setsockopt(sv[0], SOL_SOCKET, so_val, &opt_1, sizeof(opt_1))) {
03d83a
 		perror(str);
03d83a
 		return 0;
03d83a
 	}
03d83a
-- 
03d83a
2.1.4
03d83a