]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
epoll_ctl warns for uninitialized padding on non-amd64 64bit arches
authorMark Wielaard <mark@klomp.org>
Sun, 26 Jul 2020 20:40:22 +0000 (22:40 +0200)
committerMark Wielaard <mark@klomp.org>
Sat, 1 Aug 2020 14:15:02 +0000 (16:15 +0200)
struct vki_epoll_event is packed on x86_64, but not on other 64bit
arches. This means that on 64bit arches there can be padding in the
epoll_event struct. Seperately the data field is only used by user
space (which might not set the data field if it doesn't need to).

Only check the events field on epoll_ctl. But assume both events
and data are both written to by epoll_[p]wait (exclude padding).

https://bugs.kde.org/show_bug.cgi?id=422623

NEWS
coregrind/m_syswrap/syswrap-linux.c

diff --git a/NEWS b/NEWS
index 77de28a294038a3d43ba16906298c2cd79ce72b4..976344cdc01336d7a31d9fcc5907102653bba948 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -43,6 +43,7 @@ where XXXXXX is the bug number as listed below.
 369029  handle linux syscalls sched_getattr and sched_setattr
 n-i-bz  helgrind: If hg_cli__realloc fails, return NULL.
 
+422623  epoll_ctl warns for uninitialized padding on non-amd64 64bit arches
 423021  PPC:  Add missing ISA 3.0 documentation link and HWCAPS test.
 
 
index 56be3032d328a99eac7705c0033d205afaaab874..dd41022108a0351dfbb645bdeffe7b8bc3da74b4 100644 (file)
@@ -2099,8 +2099,29 @@ PRE(sys_epoll_ctl)
          SARG1, ( ARG2<3 ? epoll_ctl_s[ARG2] : "?" ), SARG3, ARG4);
    PRE_REG_READ4(long, "epoll_ctl",
                  int, epfd, int, op, int, fd, struct vki_epoll_event *, event);
-   if (ARG2 != VKI_EPOLL_CTL_DEL)
-      PRE_MEM_READ( "epoll_ctl(event)", ARG4, sizeof(struct vki_epoll_event) );
+   if (ARG2 != VKI_EPOLL_CTL_DEL) {
+      /* Just check the events field, the data field is for user space and
+         unused by the kernel.  */
+      struct vki_epoll_event *event = (struct vki_epoll_event *) ARG4;
+      PRE_MEM_READ( "epoll_ctl(event)", (Addr) &event->events,
+                    sizeof(__vki_u32) );
+   }
+}
+
+/* RES event records have been written (exclude padding).  */
+static void epoll_post_helper ( ThreadId tid, SyscallArgs* arrghs,
+                                SyscallStatus* status )
+{
+   vg_assert(SUCCESS);
+   if (RES > 0) {
+      Int i;
+      struct vki_epoll_event **events = (struct vki_epoll_event**)(Addr)ARG2;
+      for (i = 0; i < RES; i++) {
+         /* Assume both events and data are set (data is user space only). */
+         POST_FIELD_WRITE(events[i]->events);
+         POST_FIELD_WRITE(events[i]->data);
+      }
+   }
 }
 
 PRE(sys_epoll_wait)
@@ -2111,13 +2132,12 @@ PRE(sys_epoll_wait)
    PRE_REG_READ4(long, "epoll_wait",
                  int, epfd, struct vki_epoll_event *, events,
                  int, maxevents, int, timeout);
+   /* Assume all (maxevents) events records should be (fully) writable. */
    PRE_MEM_WRITE( "epoll_wait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
 }
 POST(sys_epoll_wait)
 {
-   vg_assert(SUCCESS);
-   if (RES > 0)
-      POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ;
+   epoll_post_helper (tid, arrghs, status);
 }
 
 PRE(sys_epoll_pwait)
@@ -2130,15 +2150,14 @@ PRE(sys_epoll_pwait)
                  int, epfd, struct vki_epoll_event *, events,
                  int, maxevents, int, timeout, vki_sigset_t *, sigmask,
                  vki_size_t, sigsetsize);
+   /* Assume all (maxevents) events records should be (fully) writable. */
    PRE_MEM_WRITE( "epoll_pwait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
    if (ARG5)
       PRE_MEM_READ( "epoll_pwait(sigmask)", ARG5, sizeof(vki_sigset_t) );
 }
 POST(sys_epoll_pwait)
 {
-   vg_assert(SUCCESS);
-   if (RES > 0)
-      POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ;
+   epoll_post_helper (tid, arrghs, status);
 }
 
 PRE(sys_eventfd)