]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
syswrap-linux.c: fix the wrapper for ioctl(SIOCETHTOOL), case ETHTOOL_GSET. n-i-bz.
authorJulian Seward <jseward@acm.org>
Fri, 27 Dec 2019 15:20:32 +0000 (16:20 +0100)
committerJulian Seward <jseward@acm.org>
Fri, 27 Dec 2019 15:20:32 +0000 (16:20 +0100)
For the case ETHTOOL_GSET, don't insist that the whole structure is defined.
That appears to cause false positives.  All other cases remain unchanged.

coregrind/m_syswrap/syswrap-linux.c

index f1ecbbf14ea9fcfd27100008efc4e5bf603dc5f1..4655d09f20da5e744f26d6412f89f759c83e0892 100644 (file)
@@ -6773,12 +6773,35 @@ PRE(sys_ioctl)
                      sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex));
       PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", ARG3, sizeof(struct vki_ifreq));
       break;
+
    case VKI_SIOCETHTOOL: {       /* ethtool(8) interface         */
       struct vki_ifreq *ir = (struct vki_ifreq *)(Addr)ARG3;
-      PRE_MEM_READ( "ioctl(SIOCETHTOOL)", (Addr)ir, sizeof(struct vki_ifreq) );
-      PRE_MEM_RASCIIZ( "ioctl(SIOCETHTOOL)", (Addr)ir->vki_ifr_name );
-      PRE_MEM_READ( "ioctl(SIOCETHTOOL)", (Addr)ir->vki_ifr_data, sizeof(vki_u32) );
+      // The kernel will have to look at ifr_data to determine which operation
+      // to perform.
+      PRE_MEM_READ( "ioctl(SIOCETHTOOL,ir->ifr_data)",
+                    (Addr)ir->vki_ifr_data, sizeof(vki_u32) );
+
       PRINT("SIOCETHTOOL( 0x%x )", *(vki_u32 *)ir->vki_ifr_data );
+
+      // Is this correct?  Is ifr_name *always* looked at?
+      PRE_MEM_RASCIIZ( "ioctl(SIOCETHTOOL,ir->ifr_name)",
+                       (Addr)ir->vki_ifr_name );
+
+      // At least for ETHTOOL_GSET, it is apparently incorrect to insist that
+      // the whole structure is defined.  So in this case, just check it's
+      // accessible.
+      switch ( *(vki_u32 *)ir->vki_ifr_data ) {
+      case VKI_ETHTOOL_GSET:
+         PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,ir)",
+                        (Addr)ir, sizeof(struct vki_ifreq) );
+         break;
+      default:
+         PRE_MEM_READ( "ioctl(SIOCETHTOOL,ir)",
+                       (Addr)ir, sizeof(struct vki_ifreq) );
+         break;
+      }
+
+      // Now perform the relevant pre-action for the operation.
       switch ( *(vki_u32 *)ir->vki_ifr_data ) {
       case VKI_ETHTOOL_GSET:
          PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSET)",
@@ -6893,7 +6916,8 @@ PRE(sys_ioctl)
          break;
       }
       break;
-   }
+   } /* case VKI_SIOCETHTOOL */
+
    case VKI_SIOCGMIIPHY:         /* get hardware entry           */
       PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
                      (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );