From: Tom Hughes Date: Thu, 28 Feb 2013 12:50:55 +0000 (+0000) Subject: Don't check the flags word in msghdr for sendmsg as the X-Git-Tag: svn/VALGRIND_3_9_0~387 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=592e58c7477640dba6dfee3561c1dc8f88bc98ff;p=thirdparty%2Fvalgrind.git Don't check the flags word in msghdr for sendmsg as the kernel will neither read nor write it. Patch from Mark Wielaard to fix BZ#315441. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13294 --- diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c index 5e4426fc57..40a4bbe4a5 100644 --- a/coregrind/m_syswrap/syswrap-generic.c +++ b/coregrind/m_syswrap/syswrap-generic.c @@ -849,7 +849,8 @@ void msghdr_foreachfield ( const HChar *name, struct vki_msghdr *msg, UInt length, - void (*foreach_func)( ThreadId, Bool, const HChar *, Addr, SizeT ) + void (*foreach_func)( ThreadId, Bool, const HChar *, Addr, SizeT ), + Bool recv ) { HChar *fieldName; @@ -867,7 +868,11 @@ void msghdr_foreachfield ( foreach_func ( tid, True, fieldName, (Addr)&msg->msg_iovlen, sizeof( msg->msg_iovlen ) ); foreach_func ( tid, True, fieldName, (Addr)&msg->msg_control, sizeof( msg->msg_control ) ); foreach_func ( tid, True, fieldName, (Addr)&msg->msg_controllen, sizeof( msg->msg_controllen ) ); - foreach_func ( tid, False, fieldName, (Addr)&msg->msg_flags, sizeof( msg->msg_flags ) ); + + /* msg_flags is completely ignored for send_mesg, recv_mesg doesn't read + the field, but does write to it. */ + if ( recv ) + foreach_func ( tid, False, fieldName, (Addr)&msg->msg_flags, sizeof( msg->msg_flags ) ); if ( msg->msg_name ) { VG_(sprintf) ( fieldName, "(%s.msg_name)", name ); @@ -1512,7 +1517,7 @@ void ML_(generic_PRE_sys_sendmsg) ( ThreadId tid, const HChar *name, struct vki_msghdr *msg ) { - msghdr_foreachfield ( tid, name, msg, ~0, pre_mem_read_sendmsg ); + msghdr_foreachfield ( tid, name, msg, ~0, pre_mem_read_sendmsg, False ); } /* ------ */ @@ -1521,14 +1526,14 @@ void ML_(generic_PRE_sys_recvmsg) ( ThreadId tid, const HChar *name, struct vki_msghdr *msg ) { - msghdr_foreachfield ( tid, name, msg, ~0, pre_mem_write_recvmsg ); + msghdr_foreachfield ( tid, name, msg, ~0, pre_mem_write_recvmsg, True ); } void ML_(generic_POST_sys_recvmsg) ( ThreadId tid, const HChar *name, struct vki_msghdr *msg, UInt length ) { - msghdr_foreachfield( tid, name, msg, length, post_mem_write_recvmsg ); + msghdr_foreachfield( tid, name, msg, length, post_mem_write_recvmsg, True ); check_cmsg_for_fds( tid, msg ); } diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am index 13ffec8569..0cec5f1603 100644 --- a/memcheck/tests/Makefile.am +++ b/memcheck/tests/Makefile.am @@ -187,6 +187,7 @@ EXTRA_DIST = \ recursive-merge.stderr.exp recursive-merge.vgtest \ sbfragment.stdout.exp sbfragment.stderr.exp sbfragment.vgtest \ sem.stderr.exp sem.vgtest \ + sendmsg.stderr.exp sendmsg.vgtest \ sh-mem.stderr.exp sh-mem.vgtest \ sh-mem-random.stderr.exp sh-mem-random.stdout.exp64 \ sh-mem-random.stdout.exp sh-mem-random.vgtest \ @@ -292,6 +293,7 @@ check_PROGRAMS = \ realloc1 realloc2 realloc3 \ recursive-merge \ sbfragment \ + sendmsg \ sh-mem sh-mem-random \ sigaltstack signal2 sigprocmask static_malloc sigkill \ strchr \ diff --git a/memcheck/tests/filter_stderr b/memcheck/tests/filter_stderr index abd679236e..3d62d944ac 100755 --- a/memcheck/tests/filter_stderr +++ b/memcheck/tests/filter_stderr @@ -22,6 +22,9 @@ sed "s/checked [0-9,]* bytes./checked ... bytes./" | # records. So we filter out the loss record numbers. perl -p -e "s/in loss record \d+ of \d+/in loss record ... of .../" | +# Filter out glibc debuginfo if installed. +perl -p -e "s/\(syscall-template.S:[0-9]*\)/(in \/...libc...)/" | + $dir/../../memcheck/tests/filter_memcheck "$@" exit 0 diff --git a/memcheck/tests/sendmsg.c b/memcheck/tests/sendmsg.c new file mode 100644 index 0000000000..2039f07d34 --- /dev/null +++ b/memcheck/tests/sendmsg.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include +#include + +#define PORT 12345 + +int +main (int argc, char **argv) +{ + int fd; + struct sockaddr_in sa; + struct msghdr msg; + struct iovec iov[2]; + + fd = socket (AF_INET, SOCK_DGRAM, 0); + if (fd == -1) + { + perror ("socket()"); + exit (EXIT_FAILURE); + } + + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK); + sa.sin_port = htons (PORT); + if (connect (fd, (struct sockaddr *) &sa, sizeof (sa)) == -1) + { + perror ("connect ()"); + exit (EXIT_FAILURE); + } + + // Create msg_hdr. Oops, we forget to set msg_name... + msg.msg_namelen = 0; + iov[0].iov_base = "one"; + iov[0].iov_len = 3; + iov[1].iov_base = "two"; + iov[1].iov_len = 3; + msg.msg_iov = &iov; + msg.msg_iovlen = 2; + msg.msg_control = NULL; + msg.msg_controllen = 0; + + size_t s = sendmsg (fd, &msg, 0); + + // Note how we now do set msg_name, but don't set msg_flags. + // The msg_flags field is ignored by sendmsg. + msg.msg_name = NULL; + + fd = socket (AF_INET, SOCK_DGRAM, 0); + if (fd == -1) + { + perror ("socket()"); + exit (EXIT_FAILURE); + } + + if (connect (fd, (struct sockaddr *) &sa, sizeof (sa)) == -1) + { + perror ("connect ()"); + exit (EXIT_FAILURE); + } + + s = sendmsg (fd, &msg, 0); + if (s == -1) + { + perror ("sendmsg ()"); + exit (EXIT_FAILURE); + } + else + fprintf (stderr, "sendmsg: %d\n", (int) s); + + exit(0); +} diff --git a/memcheck/tests/sendmsg.stderr.exp b/memcheck/tests/sendmsg.stderr.exp new file mode 100644 index 0000000000..38e20c5dc8 --- /dev/null +++ b/memcheck/tests/sendmsg.stderr.exp @@ -0,0 +1,6 @@ +Syscall param sendmsg(msg) points to uninitialised byte(s) + at 0x........: sendmsg (in /...libc...) + by 0x........: main (sendmsg.c:45) + Address 0x........ is on thread 1's stack + +sendmsg: 6 diff --git a/memcheck/tests/sendmsg.vgtest b/memcheck/tests/sendmsg.vgtest new file mode 100644 index 0000000000..f252b62b95 --- /dev/null +++ b/memcheck/tests/sendmsg.vgtest @@ -0,0 +1,2 @@ +prog: sendmsg +vgopts: -q