summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Syromyatnikov <evgsyr@gmail.com>2021-08-23 18:24:39 +0200
committerEugene Syromyatnikov <evgsyr@gmail.com>2021-08-24 19:01:21 +0200
commitf73a729cdff29f1459c832be4f1df8c51013ef86 (patch)
tree5360820da8d131f097162eca519823ded59f389e
parentb0dc9a1b3140055fc56317e4cd51687eeb9a04fe (diff)
downloadstrace-f73a729cdff29f1459c832be4f1df8c51013ef86.tar.gz
tests: call setsockopt directly in sockopt-timestamp
While commit v5.13-10-g0211fdc "tests: change sockopt-timestamp test to use syscall(__NR_recvmsg)" has fixed issues with glibc-induced mangling on newer kernels, the combination of an older kernel and new glibc still causes issues, as glibc silently falls back to SO_TIMESTAMP{,NS}_OLD, as implemented in glibc-2.34~294 "linux: Add fallback for 64-bit time_t SO_TIMESTAMP{NS}". Avoid that by calling setsockopt directly as well. * tests/sockopt-timestamp.c (SC_setsockopt): New macro constant. (k_setsockopt): New function. (test_sockopt): Call k_setsockopt instead of setsockopt. Complements: v5.13-10-g0211fdc "tests: change sockopt-timestamp test to use syscall(__NR_recvmsg)"
-rw-r--r--tests/sockopt-timestamp.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/tests/sockopt-timestamp.c b/tests/sockopt-timestamp.c
index 34c4d89a1..924873558 100644
--- a/tests/sockopt-timestamp.c
+++ b/tests/sockopt-timestamp.c
@@ -48,6 +48,30 @@ k_recvmsg(const unsigned int fd, const void *const ptr, const unsigned int flags
return rc;
}
+#define SC_setsockopt 14
+static long
+k_setsockopt(const unsigned int fd, const unsigned int level,
+ const unsigned int optname, const void *const optval,
+ const unsigned int len)
+{
+ const kernel_ulong_t fill = (kernel_ulong_t) 0xdefaced00000000ULL;
+#ifdef __NR_setsockopt
+ const kernel_ulong_t bad = (kernel_ulong_t) 0xbadc0dedbadc0dedULL;
+#endif
+
+ return syscall(
+#ifdef __NR_setsockopt
+ __NR_setsockopt,
+#else /* socketcall */
+ __NR_socketcall, SC_setsockopt,
+#endif
+ fill | fd , fill | level, fill | optname, optval, fill | len
+#ifdef __NR_setsockopt
+ , bad
+#endif
+ );
+}
+
static void
print_timestamp_old(const struct cmsghdr *c)
{
@@ -139,7 +163,12 @@ test_sockopt(int so_val, const char *str, void (*fun)(const struct cmsghdr *))
perror_msg_and_skip(data);
const int opt_1 = 1;
- if (setsockopt(sv[0], SOL_SOCKET, so_val, &opt_1, sizeof(opt_1))) {
+ /*
+ * glibc-2.34~294 adds a fallback for SO_TIMESTAMP{,NS}_NEW that calls
+ * SO_TIMESTAMP{,NS}_OLD, so we have to call the setsockopt directly
+ * in order to avoid unexpected recvmsg msg types.
+ */
+ if (k_setsockopt(sv[0], SOL_SOCKET, so_val, &opt_1, sizeof(opt_1))) {
perror(str);
return 0;
}