[PATCH] linux: align the ancillary buffer in tst-socket-timestamp

Matt Turner mattst88@gmail.com
Mon Aug 10 19:09:21 GMT 2026


The test places the ancillary buffer so that it ends against a PROT_NONE
page, at cmsg - (CMSG_SPACE (tsize) + slack).  CMSG_SPACE (sizeof (struct
timeval)) is a multiple of the alignment of struct cmsghdr, so the start of
the buffer inherits the alignment of the slack, and one of the slack sizes
the test uses is 4.

msg_control has to be suitably aligned for struct cmsghdr: recvmsg and the
CMSG_* macros both read cmsg_len from the start of the buffer, and it is a
size_t.  On a target that does not fix up unaligned accesses in hardware,
reading it from a misaligned address traps into the kernel.  On alpha each
one is reported:

  ld-linux.so.2(48878): unaligned trap at 0000000120001e3c: ... 29 2

five per run, all from the loop over the control messages in
do_recvmsg_slack_ancillary.  The test still passes, since the kernel
completes the access and returns.

Round the start of the buffer down to the alignment.  A slack that is not a
multiple of it then leaves the buffer ending a few bytes short of the guard
page rather than against it; the overruns the guard page is there to catch
are a whole timestamp rather than a few bytes, so they are still caught.
---
 sysdeps/unix/sysv/linux/tst-socket-timestamp.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git ./sysdeps/unix/sysv/linux/tst-socket-timestamp.c ./sysdeps/unix/sysv/linux/tst-socket-timestamp.c
index a5ab72e39c..8d40d590c0 100644
--- ./sysdeps/unix/sysv/linux/tst-socket-timestamp.c
+++ ./sysdeps/unix/sysv/linux/tst-socket-timestamp.c
@@ -19,6 +19,7 @@
 #include <array_length.h>
 #include <arpa/inet.h>
 #include <errno.h>
+#include <libc-pointer-arith.h>
 #include <string.h>
 #include <stdio.h>
 #include <support/check.h>
@@ -65,7 +66,14 @@ do_recvmsg_slack_ancillary (bool use_multi_call, int s, void *cmsg,
       .iov_len = sizeof (payload)
     };
   size_t msg_controllen = CMSG_SPACE (tsize) + slack;
-  char *msg_control = cmsg - msg_controllen;
+  /* The buffer has to be suitably aligned for struct cmsghdr, since both
+     recvmsg and the CMSG_* macros below read cmsg_len from its start, so
+     round the start down.  A slack that is not a multiple of the alignment
+     then leaves the buffer ending just short of the guard page rather than
+     against it, which still catches the overruns this is looking for: they
+     are a whole timestamp, not a few bytes.  */
+  char *msg_control = PTR_ALIGN_DOWN ((char *) cmsg - msg_controllen,
+				      __alignof__ (struct cmsghdr));
   memset (msg_control, 0x55, msg_controllen);
   struct mmsghdr mmhdr =
     {
-- 
2.54.0



More information about the Libc-alpha mailing list