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

Florian Weimer via Glibc-cvs <[email protected]>
Newsgroups gmane.comp.lib.glibc.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=059e1cd67bc81ac31ac208e00c3200d45f02dbd9

commit 059e1cd67bc81ac31ac208e00c3200d45f02dbd9
Author: Matt Turner <[email protected]>
Date:   Tue Aug 11 23:13:20 2026 -0400

    linux: align the ancillary buffer in tst-socket-timestamp
    
    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, and add the alignment
    minus one to the requested allocation so the rounding cannot move the start
    outside it.  A slack that is not a multiple of the alignment 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.
    
    Reviewed-by: Florian Weimer <[email protected]>

Diff:
---
 sysdeps/unix/sysv/linux/tst-socket-timestamp.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/tst-socket-timestamp.c b/sysdeps/unix/sysv/linux/tst-socket-timestamp.c
index a5ab72e39c..c77ac7b439 100644
--- a/sysdeps/unix/sysv/linux/tst-socket-timestamp.c
+++ b/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,15 @@ 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.  The caller reserves the extra bytes this may
+     consume.  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 =
     {
@@ -142,10 +151,13 @@ static void
 do_test_slack_space (void)
 {
   /* Setup the ancillary data buffer with an extra page with PROT_NONE to
-     check the possible timestamp conversion on some systems.  */
+     check the possible timestamp conversion on some systems.  Request
+     __alignof__ (struct cmsghdr) - 1 extra bytes to cover the rounding down
+     of the buffer start in do_recvmsg_slack_ancillary.  */
   struct support_next_to_fault nf =
-    support_next_to_fault_allocate (slack_max_size);
-  void *msgbuf = nf.buffer + slack_max_size;
+    support_next_to_fault_allocate (slack_max_size
+				    + __alignof__ (struct cmsghdr) - 1);
+  void *msgbuf = nf.buffer + nf.length;
 
   /* Enable the timestamp using struct timeval precision.  */
   {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.