Mark Wielaard bf5c38
commit f326d68d762edf4b0e9604daa446b6f8ca25725a
Mark Wielaard bf5c38
Author: Mark Wielaard <mark@klomp.org>
Mark Wielaard bf5c38
Date:   Sun Jul 26 22:40:22 2020 +0200
Mark Wielaard bf5c38
Mark Wielaard bf5c38
    epoll_ctl warns for uninitialized padding on non-amd64 64bit arches
Mark Wielaard bf5c38
    
Mark Wielaard bf5c38
    struct vki_epoll_event is packed on x86_64, but not on other 64bit
Mark Wielaard bf5c38
    arches. This means that on 64bit arches there can be padding in the
Mark Wielaard bf5c38
    epoll_event struct. Seperately the data field is only used by user
Mark Wielaard bf5c38
    space (which might not set the data field if it doesn't need to).
Mark Wielaard bf5c38
    
Mark Wielaard bf5c38
    Only check the events field on epoll_ctl. But assume both events
Mark Wielaard bf5c38
    and data are both written to by epoll_[p]wait (exclude padding).
Mark Wielaard bf5c38
    
Mark Wielaard bf5c38
    https://bugs.kde.org/show_bug.cgi?id=422623
Mark Wielaard bf5c38
Mark Wielaard bf5c38
diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c
Mark Wielaard bf5c38
index 5b5b7eee6..929a4d9af 100644
Mark Wielaard bf5c38
--- a/coregrind/m_syswrap/syswrap-linux.c
Mark Wielaard bf5c38
+++ b/coregrind/m_syswrap/syswrap-linux.c
Mark Wielaard bf5c38
@@ -2099,8 +2099,29 @@ PRE(sys_epoll_ctl)
Mark Wielaard bf5c38
          SARG1, ( ARG2<3 ? epoll_ctl_s[ARG2] : "?" ), SARG3, ARG4);
Mark Wielaard bf5c38
    PRE_REG_READ4(long, "epoll_ctl",
Mark Wielaard bf5c38
                  int, epfd, int, op, int, fd, struct vki_epoll_event *, event);
Mark Wielaard bf5c38
-   if (ARG2 != VKI_EPOLL_CTL_DEL)
Mark Wielaard bf5c38
-      PRE_MEM_READ( "epoll_ctl(event)", ARG4, sizeof(struct vki_epoll_event) );
Mark Wielaard bf5c38
+   if (ARG2 != VKI_EPOLL_CTL_DEL) {
Mark Wielaard bf5c38
+      /* Just check the events field, the data field is for user space and
Mark Wielaard bf5c38
+         unused by the kernel.  */
Mark Wielaard bf5c38
+      struct vki_epoll_event *event = (struct vki_epoll_event *) ARG4;
Mark Wielaard bf5c38
+      PRE_MEM_READ( "epoll_ctl(event)", (Addr) &event->events,
Mark Wielaard bf5c38
+                    sizeof(__vki_u32) );
Mark Wielaard bf5c38
+   }
Mark Wielaard bf5c38
+}
Mark Wielaard bf5c38
+
Mark Wielaard bf5c38
+/* RES event records have been written (exclude padding).  */
Mark Wielaard bf5c38
+static void epoll_post_helper ( ThreadId tid, SyscallArgs* arrghs,
Mark Wielaard bf5c38
+                                SyscallStatus* status )
Mark Wielaard bf5c38
+{
Mark Wielaard bf5c38
+   vg_assert(SUCCESS);
Mark Wielaard bf5c38
+   if (RES > 0) {
Mark Wielaard bf5c38
+      Int i;
Mark Wielaard bf5c38
+      struct vki_epoll_event **events = (struct vki_epoll_event**)(Addr)ARG2;
Mark Wielaard bf5c38
+      for (i = 0; i < RES; i++) {
Mark Wielaard bf5c38
+         /* Assume both events and data are set (data is user space only). */
Mark Wielaard bf5c38
+         POST_FIELD_WRITE(events[i]->events);
Mark Wielaard bf5c38
+         POST_FIELD_WRITE(events[i]->data);
Mark Wielaard bf5c38
+      }
Mark Wielaard bf5c38
+   }
Mark Wielaard bf5c38
 }
Mark Wielaard bf5c38
 
Mark Wielaard bf5c38
 PRE(sys_epoll_wait)
Mark Wielaard bf5c38
@@ -2111,13 +2132,12 @@ PRE(sys_epoll_wait)
Mark Wielaard bf5c38
    PRE_REG_READ4(long, "epoll_wait",
Mark Wielaard bf5c38
                  int, epfd, struct vki_epoll_event *, events,
Mark Wielaard bf5c38
                  int, maxevents, int, timeout);
Mark Wielaard bf5c38
+   /* Assume all (maxevents) events records should be (fully) writable. */
Mark Wielaard bf5c38
    PRE_MEM_WRITE( "epoll_wait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
Mark Wielaard bf5c38
 }
Mark Wielaard bf5c38
 POST(sys_epoll_wait)
Mark Wielaard bf5c38
 {
Mark Wielaard bf5c38
-   vg_assert(SUCCESS);
Mark Wielaard bf5c38
-   if (RES > 0)
Mark Wielaard bf5c38
-      POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ;
Mark Wielaard bf5c38
+   epoll_post_helper (tid, arrghs, status);
Mark Wielaard bf5c38
 }
Mark Wielaard bf5c38
 
Mark Wielaard bf5c38
 PRE(sys_epoll_pwait)
Mark Wielaard bf5c38
@@ -2130,15 +2150,14 @@ PRE(sys_epoll_pwait)
Mark Wielaard bf5c38
                  int, epfd, struct vki_epoll_event *, events,
Mark Wielaard bf5c38
                  int, maxevents, int, timeout, vki_sigset_t *, sigmask,
Mark Wielaard bf5c38
                  vki_size_t, sigsetsize);
Mark Wielaard bf5c38
+   /* Assume all (maxevents) events records should be (fully) writable. */
Mark Wielaard bf5c38
    PRE_MEM_WRITE( "epoll_pwait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
Mark Wielaard bf5c38
    if (ARG5)
Mark Wielaard bf5c38
       PRE_MEM_READ( "epoll_pwait(sigmask)", ARG5, sizeof(vki_sigset_t) );
Mark Wielaard bf5c38
 }
Mark Wielaard bf5c38
 POST(sys_epoll_pwait)
Mark Wielaard bf5c38
 {
Mark Wielaard bf5c38
-   vg_assert(SUCCESS);
Mark Wielaard bf5c38
-   if (RES > 0)
Mark Wielaard bf5c38
-      POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ;
Mark Wielaard bf5c38
+   epoll_post_helper (tid, arrghs, status);
Mark Wielaard bf5c38
 }
Mark Wielaard bf5c38
 
Mark Wielaard bf5c38
 PRE(sys_eventfd)
Mark Wielaard b34c10
commit b74f9f23c8758c77367f18368ea95baa858544cb
Mark Wielaard b34c10
Author: Mark Wielaard <mark@klomp.org>
Mark Wielaard b34c10
Date:   Tue Aug 18 23:58:55 2020 +0200
Mark Wielaard b34c10
Mark Wielaard b34c10
    Fix epoll_ctl setting of array event and data fields.
Mark Wielaard b34c10
    
Mark Wielaard b34c10
    Fix for https://bugs.kde.org/show_bug.cgi?id=422623 in commit ecf5ba119
Mark Wielaard b34c10
    epoll_ctl warns for uninitialized padding on non-amd64 64bit arches
Mark Wielaard b34c10
    contained a bug. A pointer to an array is not a pointer to a pointer to
Mark Wielaard b34c10
    an array. Found by a Fedora user:
Mark Wielaard b34c10
    https://bugzilla.redhat.com/show_bug.cgi?id=1844778#c10
Mark Wielaard b34c10
Mark Wielaard b34c10
diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c
Mark Wielaard b34c10
index 0850487e9..3f488795a 100644
Mark Wielaard b34c10
--- a/coregrind/m_syswrap/syswrap-linux.c
Mark Wielaard b34c10
+++ b/coregrind/m_syswrap/syswrap-linux.c
Mark Wielaard b34c10
@@ -2115,11 +2115,11 @@ static void epoll_post_helper ( ThreadId tid, SyscallArgs* arrghs,
Mark Wielaard b34c10
    vg_assert(SUCCESS);
Mark Wielaard b34c10
    if (RES > 0) {
Mark Wielaard b34c10
       Int i;
Mark Wielaard b34c10
-      struct vki_epoll_event **events = (struct vki_epoll_event**)(Addr)ARG2;
Mark Wielaard b34c10
+      struct vki_epoll_event *events = (struct vki_epoll_event*)(Addr)ARG2;
Mark Wielaard b34c10
       for (i = 0; i < RES; i++) {
Mark Wielaard b34c10
          /* Assume both events and data are set (data is user space only). */
Mark Wielaard b34c10
-         POST_FIELD_WRITE(events[i]->events);
Mark Wielaard b34c10
-         POST_FIELD_WRITE(events[i]->data);
Mark Wielaard b34c10
+         POST_FIELD_WRITE(events[i].events);
Mark Wielaard b34c10
+         POST_FIELD_WRITE(events[i].data);
Mark Wielaard b34c10
       }
Mark Wielaard b34c10
    }
Mark Wielaard b34c10
 }