]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Handle setsockopt(SOL_SOCKET, SO_ATTACH_FILTER) better. Based
authorTom Hughes <tom@compton.nu>
Wed, 17 Jul 2013 14:36:57 +0000 (14:36 +0000)
committerTom Hughes <tom@compton.nu>
Wed, 17 Jul 2013 14:36:57 +0000 (14:36 +0000)
on patch from Guy Harris on BZ#318203.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13461

coregrind/m_syswrap/priv_syswrap-linux.h
coregrind/m_syswrap/syswrap-linux.c
include/vki/vki-linux.h

index 2ae844201a0c034e25e68af392f4f65fec631e3f..c09dc103adb15d245b6daeb590d2426518b0abd4 100644 (file)
@@ -295,6 +295,7 @@ extern void ML_(linux_PRE_sys_msgctl)      ( TId, UW, UW, UW );
 extern void ML_(linux_POST_sys_msgctl)     ( TId, UW, UW, UW, UW );
 extern void ML_(linux_PRE_sys_getsockopt)  ( TId, UW, UW, UW, UW, UW );
 extern void ML_(linux_POST_sys_getsockopt) ( TId, SR, UW, UW, UW, UW, UW );
+extern void ML_(linux_PRE_sys_setsockopt)  ( TId, UW, UW, UW, UW, UW );
 
 // Linux-specific (but non-arch-specific) ptrace wrapper helpers
 extern void ML_(linux_PRE_getregset) ( ThreadId, long, long );
index a4e4bb773e1677248175aed3c0389e491489037c..e73c9855d82bb9b7d5a346176ca038b2f19317da 100644 (file)
@@ -3842,8 +3842,8 @@ PRE(sys_socketcall)
       /* int setsockopt(int s, int level, int optname, 
                         const void *optval, int optlen); */
       PRE_MEM_READ_ef( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
-      ML_(generic_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2, 
-                                       ARG2_3, ARG2_4 );
+      ML_(linux_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2, 
+                                     ARG2_3, ARG2_4 );
       break;
 
    case VKI_SYS_GETSOCKOPT:
@@ -4021,7 +4021,7 @@ PRE(sys_setsockopt)
    PRE_REG_READ5(long, "setsockopt",
                  int, s, int, level, int, optname,
                  const void *, optval, int, optlen);
-   ML_(generic_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
+   ML_(linux_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
 }
 
 PRE(sys_getsockopt)
@@ -7771,6 +7771,57 @@ ML_(linux_POST_sys_getsockopt) ( ThreadId tid,
    }
 }
 
+void 
+ML_(linux_PRE_sys_setsockopt) ( ThreadId tid, 
+                                UWord arg0, UWord arg1, UWord arg2,
+                                UWord arg3, UWord arg4 )
+{
+   /* int setsockopt(int s, int level, int optname, 
+                     const void *optval, socklen_t optlen); */
+   Addr optval_p = arg3;
+   if (optval_p != (Addr)NULL) {
+      /*
+       * OK, let's handle at least some setsockopt levels and options
+       * ourselves, so we don't get false claims of references to
+       * uninitialized memory (such as padding in structures) and *do*
+       * check what pointers in the argument point to.
+       */
+      if (arg1 == VKI_SOL_SOCKET && arg2 == VKI_SO_ATTACH_FILTER)
+      {
+         struct vki_sock_fprog *fp = (struct vki_sock_fprog *)optval_p;
+
+         /*
+          * struct sock_fprog has a 16-bit count of instructions,
+          * followed by a pointer to an array of those instructions.
+          * There's padding between those two elements.
+          *
+          * So that we don't bogusly complain about the padding bytes,
+          * we just report that we read len and and filter.
+          *
+          * We then make sure that what filter points to is valid.
+          */
+         PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.len)",
+                       (Addr)&fp->len, sizeof(fp->len) );
+         PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.filter)",
+                       (Addr)&fp->filter, sizeof(fp->filter) );
+
+         /* len * sizeof (*filter) */
+         if (fp->filter != NULL)
+         {
+            PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, optval.filter)",
+                          (Addr)(fp->filter),
+                          fp->len * sizeof(*fp->filter) );
+         }
+      }
+      else
+      {
+         PRE_MEM_READ( "socketcall.setsockopt(optval)",
+                       arg3, /* optval */
+                       arg4  /* optlen */ );
+      }
+   }
+}
+
 /* ---------------------------------------------------------------------
    ptrace wrapper helpers
    ------------------------------------------------------------------ */
index c9aa0477a052add3cb94814b3bda5db4a50fc239..63cd50149ee82c77eee02d44fb2712b495b9a2d6 100644 (file)
@@ -680,8 +680,11 @@ __KINLINE struct vki_cmsghdr * vki_cmsg_nxthdr (struct vki_msghdr *__msg, struct
 
 #define VKI_MSG_NOSIGNAL       0x4000  /* Do not generate SIGPIPE */
 
+#define VKI_SOL_SOCKET 1
 #define VKI_SOL_SCTP   132
 
+#define VKI_SO_ATTACH_FILTER   26
+
 //----------------------------------------------------------------------
 // From linux-2.6.8.1/include/linux/in.h
 //----------------------------------------------------------------------
@@ -3139,6 +3142,22 @@ struct vki_file_handle {
    unsigned char f_handle[0];
 };
 
+//----------------------------------------------------------------------
+// From linux-3.2.0/include/linux/filter.h
+//----------------------------------------------------------------------
+
+struct vki_sock_filter {
+       __vki_u16 code; /* Actual filter code */
+       __vki_u8 jt;    /* Jump true */
+       __vki_u8 jf;    /* Jump false */
+       __vki_u32 k;    /* Generic multiuse field */
+};
+
+struct vki_sock_fprog {
+       __vki_u16 len;  /* actually unsigned short */
+       struct vki_sock_filter *filter;
+};
+   
 #endif // __VKI_LINUX_H
 
 /*--------------------------------------------------------------------*/