From 3e50321323a8fc03644950d2159195500657b395 Mon Sep 17 00:00:00 2001 From: David Smith Date: Tue, 1 Apr 2014 13:30:06 -0500 Subject: [PATCH] PR16716 partial fix: Better types in 'syscall.{send,sendto}'. * tapset/linux/syscalls2.stp: Fixed types and nesting in 'syscall.{send,sendto}'. Fixed a few more types in 'syscall.{recv,recvfrom}'. * tapset/linux/nd_syscalls2.stp: Ditto. * runtime/linux/compat_unistd.h: Added __NR_sendto. * tapset/linux/aux_syscalls.stp: Be sure we have the SYS_* defines by including ''. * testsuite/systemtap.syscall/send.c: New testcase. * testsuite/systemtap.syscall/sendto.c: New testcase. * testsuite/systemtap.syscall/recv.c: Added more testing of the 'flags' parameter. * testsuite/systemtap.syscall/recvfrom.c: Ditto. * testsuite/systemtap.syscall/recvmmsg.c: Ditto. * testsuite/systemtap.syscall/recvmsg.c: Ditto. --- runtime/linux/compat_unistd.h | 3 + tapset/linux/aux_syscalls.stp | 3 + tapset/linux/nd_syscalls2.stp | 67 ++++++++-- tapset/linux/syscalls2.stp | 69 +++++++--- testsuite/systemtap.syscall/recv.c | 10 +- testsuite/systemtap.syscall/recvfrom.c | 12 +- testsuite/systemtap.syscall/recvmmsg.c | 4 +- testsuite/systemtap.syscall/recvmsg.c | 16 ++- testsuite/systemtap.syscall/send.c | 166 ++++++++++++++++++++++++ testsuite/systemtap.syscall/sendto.c | 169 +++++++++++++++++++++++++ 10 files changed, 474 insertions(+), 45 deletions(-) create mode 100644 testsuite/systemtap.syscall/send.c create mode 100644 testsuite/systemtap.syscall/sendto.c diff --git a/runtime/linux/compat_unistd.h b/runtime/linux/compat_unistd.h index 4e68bb236..f0f24417a 100644 --- a/runtime/linux/compat_unistd.h +++ b/runtime/linux/compat_unistd.h @@ -140,5 +140,8 @@ #ifndef __NR_recvfrom #define __NR_recvfrom (__NR_syscall_max + 1) #endif +#ifndef __NR_sendto +#define __NR_sendto (__NR_syscall_max + 1) +#endif #endif /* _COMPAT_UNISTD_H_ */ diff --git a/tapset/linux/aux_syscalls.stp b/tapset/linux/aux_syscalls.stp index 5b188782a..bf8182e25 100644 --- a/tapset/linux/aux_syscalls.stp +++ b/tapset/linux/aux_syscalls.stp @@ -4,6 +4,9 @@ #include #include "linux/compat_unistd.h" +// Be sure we have the SYS_* defines. +#include + /* * Simple lookup functions for mapping values to names * using embedded C. Use these functions to create safe, diff --git a/tapset/linux/nd_syscalls2.stp b/tapset/linux/nd_syscalls2.stp index e9889d019..4f0bf3d05 100644 --- a/tapset/linux/nd_syscalls2.stp +++ b/tapset/linux/nd_syscalls2.stp @@ -924,10 +924,10 @@ probe __nd_syscall.socketcall.recv = kprobe.function("sys_socketcall").call ? asmlinkage() if (int_arg(1) != %{ SYS_RECV %}) next; __args = pointer_arg(2) - s = user_int(&@cast(__args, "ulong")[0]) + s = __int32(user_ulong(&@cast(__args, "ulong")[0])) buf_uaddr = user_ulong(&@cast(__args, "ulong")[1]) len = user_ulong(&@cast(__args, "ulong")[2]) - flags = user_uint32(&@cast(__args, "ulong")[3]) + flags = __uint32(user_ulong(&@cast(__args, "ulong")[3])) } probe __nd_syscall.compat_socketcall.recv = kprobe.function("compat_sys_socketcall").call ? @@ -994,12 +994,12 @@ probe __nd_syscall.socketcall.recvfrom = asmlinkage() if (int_arg(1) != %{ SYS_RECVFROM %}) next __args = pointer_arg(2) - s = user_int(&@cast(__args, "ulong")[0]) + s = __int32(user_ulong(&@cast(__args, "ulong")[0])) buf_uaddr = user_ulong(&@cast(__args, "ulong")[1]) len = user_ulong(&@cast(__args, "ulong")[2]) - flags = user_uint32(&@cast(__args, "ulong")[3]) + flags = __uint32(user_ulong(&@cast(__args, "ulong")[3])) addr_uaddr = user_ulong(&@cast(__args, "ulong")[4]) - addrlen_uaddr = user_ulong(&@cast(__args, "ulong")[5]) + addrlen_uaddr = __uint32(user_ulong(&@cast(__args, "ulong")[5])) } probe __nd_syscall.compat_socketcall.recvfrom = kprobe.function("compat_sys_socketcall").call ? @@ -1966,7 +1966,7 @@ probe nd_syscall.send = kprobe.function("sys_send") ? len = ulong_arg(3) flags = uint_arg(4) flags_str = _msg_flags_str(flags) - argstr = sprintf("%d, %p, %d, %s", s, buf_uaddr, len, flags_str) + argstr = sprintf("%d, %p, %u, %s", s, buf_uaddr, len, flags_str) } probe nd_syscall.send.return = kprobe.function("sys_send").return ? { @@ -2091,25 +2091,68 @@ probe nd_syscall.sendmmsg.return = kprobe.function("sys_sendmmsg").return ? # struct sockaddr __user *addr, # int addr_len) # -probe nd_syscall.sendto = kprobe.function("sys_sendto") ? +probe nd_syscall.sendto = __nd_syscall.sendto ?, + __nd_syscall.socketcall.sendto ?, + __nd_syscall.compat_socketcall.sendto ? { name = "sendto" + flags_str = _msg_flags_str(flags) + argstr = sprintf("%d, %p, %u, %s, %s, %u", s, buf_uaddr, + len, flags_str, + _struct_sockaddr_u(to_uaddr, tolen), tolen) +} +probe __nd_syscall.sendto = kprobe.function("sys_sendto").call ? +{ asmlinkage() + @__syscall_gate(%{ __NR_sendto %}) s = int_arg(1) buf_uaddr = pointer_arg(2) len = ulong_arg(3) flags = uint_arg(4) - flags_str = _msg_flags_str(flags) to_uaddr = pointer_arg(5) - tolen = int_arg(6) - argstr = sprintf("%d, %p, %d, %s, %s, %d", s, buf_uaddr, - len, flags_str, _struct_sockaddr_u(to_uaddr, tolen), tolen) + tolen = uint_arg(6) +} +probe __nd_syscall.socketcall.sendto = kprobe.function("sys_socketcall").call ? +{ + asmlinkage() + if (int_arg(1) != %{ SYS_SENDTO %}) next; + __args = pointer_arg(2) + s = __int32(user_ulong(&@cast(__args, "ulong")[0])) + buf_uaddr = user_ulong(&@cast(__args, "ulong")[1]) + len = user_ulong(&@cast(__args, "ulong")[2]) + flags = __uint32(user_ulong(&@cast(__args, "ulong")[3])) + to_uaddr = user_ulong(&@cast(__args, "ulong")[4]) + tolen = __uint32(user_ulong(&@cast(__args, "ulong")[5])) +} +probe __nd_syscall.compat_socketcall.sendto = + kprobe.function("compat_sys_socketcall").call ? +{ + asmlinkage() + if (int_arg(1) != %{ SYS_SENDTO %}) next; + __args = pointer_arg(2) + s = user_int(&@cast(__args, "unsigned int")[0]) + buf_uaddr = user_uint32(&@cast(__args, "unsigned int")[1]) + len = user_uint32(&@cast(__args, "unsigned int")[2]) + flags = user_uint32(&@cast(__args, "unsigned int")[3]) + to_uaddr = user_uint32(&@cast(__args, "unsigned int")[4]) + tolen = user_uint32(&@cast(__args, "unsigned int")[5]) } -probe nd_syscall.sendto.return = kprobe.function("sys_sendto").return ? +probe nd_syscall.sendto.return = __nd_syscall.sendto.return ?, + __nd_syscall.socketcall.sendto.return ? { name = "sendto" retstr = returnstr(1) } +probe __nd_syscall.sendto.return = kprobe.function("sys_sendto").return ? +{ + @__syscall_gate(%{ __NR_sendto %}) +} +probe __nd_syscall.socketcall.recv.return = + kprobe.function("sys_socketcall").return ?, + kprobe.function("compat_sys_socketcall").return ? +{ + if (@entry(__asmlinkage_int_arg(1)) != %{ SYS_SENDTO %}) next; +} # setdomainname ______________________________________________ # diff --git a/tapset/linux/syscalls2.stp b/tapset/linux/syscalls2.stp index 50b8358a4..b5c86ee80 100644 --- a/tapset/linux/syscalls2.stp +++ b/tapset/linux/syscalls2.stp @@ -973,10 +973,10 @@ probe syscall.recv = __syscall.socketcall.recv ?, probe __syscall.socketcall.recv = kernel.function("sys_socketcall").call ? { if ($call != %{ SYS_RECV %}) next; - s = user_int(&@cast($args, "ulong")[0]) + s = __int32(user_ulong(&@cast($args, "ulong")[0])) buf_uaddr = user_ulong(&@cast($args, "ulong")[1]) len = user_ulong(&@cast($args, "ulong")[2]) - flags = user_uint32(&@cast($args, "ulong")[3]) + flags = __uint32(user_ulong(&@cast($args, "ulong")[3])) } probe __syscall.compat_socketcall.recv = kernel.function("compat_sys_socketcall").call ? @@ -1036,12 +1036,12 @@ probe syscall.recvfrom = __syscall.socketcall.recvfrom ?, probe __syscall.socketcall.recvfrom = kernel.function("sys_socketcall").call ? { if ($call != %{ SYS_RECVFROM %}) next - s = user_int(&@cast($args, "ulong")[0]) + s = __int32(user_ulong(&@cast($args, "ulong")[0])) buf_uaddr = user_ulong(&@cast($args, "ulong")[1]) len = user_ulong(&@cast($args, "ulong")[2]) - flags = user_uint32(&@cast($args, "ulong")[3]) + flags = __uint32(user_ulong(&@cast($args, "ulong")[3])) addr_uaddr = user_ulong(&@cast($args, "ulong")[4]) - addrlen_uaddr = user_ulong(&@cast($args, "ulong")[5]) + addrlen_uaddr = __uint32(user_ulong(&@cast($args, "ulong")[5])) } probe __syscall.compat_socketcall.recvfrom = kernel.function("compat_sys_socketcall").call ? @@ -1952,12 +1952,12 @@ probe syscall.compat_sys_semtimedop.return = kernel.function("compat_sys_semtime probe syscall.send = kernel.function("sys_send").call ? { name = "send" - s = $fd + s = __int32($fd) buf_uaddr = $buff len = $len - flags = $flags - flags_str = _msg_flags_str($flags) - argstr = sprintf("%d, %p, %d, %s", $fd, $buff, $len, flags_str) + flags = __uint32($flags) + flags_str = _msg_flags_str(flags) + argstr = sprintf("%d, %p, %u, %s", s, $buff, $len, flags_str) } probe syscall.send.return = kernel.function("sys_send").return ? { @@ -2081,21 +2081,56 @@ probe syscall.sendmmsg.return = kernel.function("sys_sendmmsg").return ? # struct sockaddr __user *addr, # int addr_len) # -probe syscall.sendto = kernel.function("sys_sendto").call ? +probe syscall.sendto = __syscall.sendto ?, __syscall.socketcall.sendto ?, + __syscall.compat_socketcall.sendto ? { name = "sendto" - s = $fd + flags_str = _msg_flags_str(flags) + argstr = sprintf("%d, %p, %u, %s, %s, %u", s, buf_uaddr, + len, flags_str, + _struct_sockaddr_u(to_uaddr, tolen), tolen) +} +probe __syscall.sendto = kernel.function("sys_sendto").call ? +{ + @__syscall_gate(%{ __NR_sendto %}) + s = __int32($fd) buf_uaddr = $buff len = $len - flags = $flags - flags_str = _msg_flags_str($flags) + flags = __uint32($flags) to_uaddr = $addr - tolen = $addr_len - argstr = sprintf("%d, %p, %d, %s, %s, %d", $fd, $buff, - $len, flags_str, _struct_sockaddr_u($addr, $addr_len), $addr_len) + tolen = __uint32($addr_len) } -probe syscall.sendto.return = kernel.function("sys_sendto").return ? +probe __syscall.socketcall.sendto = kernel.function("sys_socketcall").call ? { + if ($call != %{ SYS_SENDTO %}) next; + s = __int32(user_ulong(&@cast($args, "ulong")[0])) + buf_uaddr = user_ulong(&@cast($args, "ulong")[1]) + len = user_ulong(&@cast($args, "ulong")[2]) + flags = __uint32(user_ulong(&@cast($args, "ulong")[3])) + to_uaddr = user_ulong(&@cast($args, "ulong")[4]) + tolen = __uint32(user_ulong(&@cast($args, "ulong")[5])) +} +probe __syscall.compat_socketcall.sendto = + kernel.function("compat_sys_socketcall").call ? +{ + if ($call != %{ SYS_SENDTO %}) next; + s = user_int(&@cast($args, "unsigned int")[0]) + buf_uaddr = user_uint32(&@cast($args, "unsigned int")[1]) + len = user_uint32(&@cast($args, "unsigned int")[2]) + flags = user_uint32(&@cast($args, "unsigned int")[3]) + to_uaddr = user_uint32(&@cast($args, "unsigned int")[4]) + tolen = user_uint32(&@cast($args, "unsigned int")[5]) +} +probe syscall.sendto.return = kernel.function("sys_sendto").return ?, + kernel.function("sys_socketcall").return ?, + kernel.function("compat_sys_socketcall").return ? +{ + if (@defined($call)) { + if ($call != %{ SYS_SENDTO %}) next; + } + else { + @__syscall_gate(%{ __NR_sendto %}) + } name = "sendto" retstr = return_str(1, $return) } diff --git a/testsuite/systemtap.syscall/recv.c b/testsuite/systemtap.syscall/recv.c index 12aa63e7c..275bbc633 100644 --- a/testsuite/systemtap.syscall/recv.c +++ b/testsuite/systemtap.syscall/recv.c @@ -121,8 +121,8 @@ int main() recv(-1, buf, sizeof(buf), 0); //staptest// recv[[[[from]]]]? (-1, XXXX, 1024, 0x0[[[[, 0x0, 0x0]]]]?) = -NNNN (EBADF) - recv(fd_null, buf, sizeof(buf), 0); - //staptest// recv[[[[from]]]]? (NNNN, XXXX, 1024, 0x0[[[[, 0x0, 0x0]]]]?) = -NNNN (ENOTSOCK) + recv(fd_null, buf, sizeof(buf), MSG_DONTWAIT); + //staptest// recv[[[[from]]]]? (NNNN, XXXX, 1024, MSG_DONTWAIT[[[[, 0x0, 0x0]]]]?) = -NNNN (ENOTSOCK) s = socket(PF_INET, SOCK_STREAM, 0); //staptest// socket (PF_INET, SOCK_STREAM, IPPROTO_IP) = NNNN @@ -164,11 +164,11 @@ int main() recv(s, buf, sizeof(buf), -1); //staptest// recv[[[[from]]]]? (NNNN, XXXX, 1024, MSG_[^ ]+|XXXX[[[[, 0x0, 0x0]]]]?) = -NNNN (EINVAL) - recv(s, buf, (size_t)-1, 0); + recv(s, buf, (size_t)-1, MSG_DONTWAIT); #if __WORDSIZE == 64 - //staptest// recv[[[[from]]]]? (NNNN, XXXX, 18446744073709551615, 0x0[[[[, 0x0, 0x0]]]]?) = 6 + //staptest// recv[[[[from]]]]? (NNNN, XXXX, 18446744073709551615, MSG_DONTWAIT[[[[, 0x0, 0x0]]]]?) = 6 #else - //staptest// recv[[[[from]]]]? (NNNN, XXXX, 4294967295, 0x0[[[[, 0x0, 0x0]]]]?) = 6 + //staptest// recv[[[[from]]]]? (NNNN, XXXX, 4294967295, MSG_DONTWAIT[[[[, 0x0, 0x0]]]]?) = 6 #endif close(s); diff --git a/testsuite/systemtap.syscall/recvfrom.c b/testsuite/systemtap.syscall/recvfrom.c index 8abe7074a..297244276 100644 --- a/testsuite/systemtap.syscall/recvfrom.c +++ b/testsuite/systemtap.syscall/recvfrom.c @@ -120,8 +120,9 @@ int main() recvfrom(-1, buf, sizeof(buf), 0, (struct sockaddr *)&from, &fromlen); //staptest// recvfrom (-1, XXXX, 1024, 0x0, XXXX, XXXX) = -NNNN (EBADF) - recvfrom(fd_null, buf, sizeof(buf), 0, (struct sockaddr *)&from, &fromlen); - //staptest// recvfrom (NNNN, XXXX, 1024, 0x0, XXXX, XXXX) = -NNNN (ENOTSOCK) + recvfrom(fd_null, buf, sizeof(buf), MSG_DONTWAIT, (struct sockaddr *)&from, + &fromlen); + //staptest// recvfrom (NNNN, XXXX, 1024, MSG_DONTWAIT, XXXX, XXXX) = -NNNN (ENOTSOCK) s = socket(PF_INET, SOCK_STREAM, 0); //staptest// socket (PF_INET, SOCK_STREAM, IPPROTO_IP) = NNNN @@ -219,11 +220,12 @@ int main() recvfrom(s, buf, sizeof(buf), -1, (struct sockaddr *)&from, &fromlen); //staptest// recvfrom (NNNN, XXXX, 1024, MSG_[^ ]+|XXXX, XXXX, XXXX) = -NNNN - recvfrom(s, buf, (size_t)-1, 0, (struct sockaddr *)&from, &fromlen); + recvfrom(s, buf, (size_t)-1, MSG_DONTWAIT, (struct sockaddr *)&from, + &fromlen); #if __WORDSIZE == 64 - //staptest// recvfrom (NNNN, XXXX, 18446744073709551615, 0x0, XXXX, XXXX) = 6 + //staptest// recvfrom (NNNN, XXXX, 18446744073709551615, MSG_DONTWAIT, XXXX, XXXX) = 6 #else - //staptest// recvfrom (NNNN, XXXX, 4294967295, 0x0, XXXX, XXXX) = 6 + //staptest// recvfrom (NNNN, XXXX, 4294967295, MSG_DONTWAIT, XXXX, XXXX) = 6 #endif close(s); diff --git a/testsuite/systemtap.syscall/recvmmsg.c b/testsuite/systemtap.syscall/recvmmsg.c index 9b47cc3fe..02d67dffe 100644 --- a/testsuite/systemtap.syscall/recvmmsg.c +++ b/testsuite/systemtap.syscall/recvmmsg.c @@ -189,8 +189,8 @@ int main() recvmmsg(-1, msgs, 2, 0, NULL); //staptest// recvmmsg (-1, XXXX, 2, 0x0, NULL) = -NNNN (EBADF) - recvmmsg(fd_null, msgs, 2, 0, NULL); - //staptest// recvmmsg (NNNN, XXXX, 2, 0x0, NULL) = -NNNN (ENOTSOCK) + recvmmsg(fd_null, msgs, 2, MSG_DONTWAIT, NULL); + //staptest// recvmmsg (NNNN, XXXX, 2, MSG_DONTWAIT, NULL) = -NNNN (ENOTSOCK) s = socket(PF_INET, SOCK_STREAM, 0); //staptest// socket (PF_INET, SOCK_STREAM, IPPROTO_IP) = NNNN diff --git a/testsuite/systemtap.syscall/recvmsg.c b/testsuite/systemtap.syscall/recvmsg.c index 134f2f0b8..d1ac46184 100644 --- a/testsuite/systemtap.syscall/recvmsg.c +++ b/testsuite/systemtap.syscall/recvmsg.c @@ -187,8 +187,8 @@ int main() recvmsg(-1, &msgdat, 0); //staptest// recvmsg (-1, XXXX, 0x0) = -NNNN (EBADF) - recvmsg(fd_null, &msgdat, 0); - //staptest// recvmsg (NNNN, XXXX, 0x0) = -NNNN (ENOTSOCK) + recvmsg(fd_null, &msgdat, MSG_DONTWAIT); + //staptest// recvmsg (NNNN, XXXX, MSG_DONTWAIT) = -NNNN (ENOTSOCK) s = socket(PF_INET, SOCK_STREAM, 0); //staptest// socket (PF_INET, SOCK_STREAM, IPPROTO_IP) = NNNN @@ -241,8 +241,16 @@ int main() write(s, "R", 1); //staptest// write (NNNN, "R", 1) = 1 - recvmsg(s, &msgdat, 0); - //staptest// recvmsg (NNNN, XXXX, 0x0) = 11 + /* Wait for something to be readable */ + FD_ZERO(&rdfds); + FD_SET(s, &rdfds); + timeout.tv_sec = 2; + timeout.tv_usec = 0; + select(s + 1, &rdfds, 0, 0, &timeout); + //staptest// select (NNNN, XXXX, 0x[0]+, 0x[0]+, [2\.[0]+]) = 1 + + recvmsg(s, &msgdat, MSG_DONTWAIT); + //staptest// recvmsg (NNNN, XXXX, MSG_DONTWAIT) = 11 close(s); //staptest// close (NNNN) = 0 diff --git a/testsuite/systemtap.syscall/send.c b/testsuite/systemtap.syscall/send.c new file mode 100644 index 000000000..3eb791501 --- /dev/null +++ b/testsuite/systemtap.syscall/send.c @@ -0,0 +1,166 @@ +/* COVERAGE: send */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int sfd; /* shared between start_server and do_child */ + +void do_child() +{ + struct sockaddr_in fsin; + fd_set afds, rfds; + int nfds, cc, fd; + char buf[1024]; + + FD_ZERO(&afds); + FD_SET(sfd, &afds); + + nfds = FD_SETSIZE; + + /* accept connections until killed */ + while (1) { + socklen_t fromlen; + + memcpy(&rfds, &afds, sizeof(rfds)); + + if (select(nfds, &rfds, (fd_set *) 0, (fd_set *) 0, + (struct timeval *)0) < 0) { + if (errno != EINTR) + exit(1); + } + if (FD_ISSET(sfd, &rfds)) { + int newfd; + + fromlen = sizeof(fsin); + newfd = accept(sfd, (struct sockaddr *)&fsin, &fromlen); + if (newfd >= 0) + FD_SET(newfd, &afds); + } + for (fd = 0; fd < nfds; ++fd) { + if (fd != sfd && FD_ISSET(fd, &rfds)) { + cc = read(fd, buf, sizeof(buf)); + if (cc == 0 || (cc < 0 && errno != EINTR)) { + (void)close(fd); + FD_CLR(fd, &afds); + } + } + } + } +} + +pid_t +start_server(struct sockaddr_in *sin0) +{ + struct sockaddr_in sin1 = *sin0; + pid_t pid; + + sfd = socket(PF_INET, SOCK_STREAM, 0); + if (sfd < 0) + return -1; + if (bind(sfd, (struct sockaddr *)&sin1, sizeof(sin1)) < 0) + return -1; + if (listen(sfd, 10) < 0) + return -1; + + switch (pid = fork()) { + case 0: /* child */ + do_child(); + break; + case -1: /* fall through */ + default: /* parent */ + (void)close(sfd); + return pid; + } + + return -1; +} + +int main() +{ + int s, fd_null; + struct sockaddr_in sin1; + pid_t pid = 0; + char buf[1024]; + fd_set rdfds; + struct timeval timeout; + + /* On several platforms, glibc substitutes sendto() for send() + * (verified using strace). So, we'll just expect send() or + * sendto(). */ + + /* initialize sockaddr's */ + sin1.sin_family = AF_INET; + sin1.sin_port = htons((getpid() % 32768) + 11000); + sin1.sin_addr.s_addr = INADDR_ANY; + + signal(SIGPIPE, SIG_IGN); + + pid = start_server(&sin1); + + fd_null = open("/dev/null", O_WRONLY); + + send(-1, buf, sizeof(buf), 0); + //staptest// send[[[[to]]]]? (-1, XXXX, 1024, 0x0[[[[, NULL, 0]]]]?) = -NNNN (EBADF) + + send(fd_null, buf, sizeof(buf), MSG_DONTWAIT); + //staptest// send[[[[to]]]]? (NNNN, XXXX, 1024, MSG_DONTWAIT[[[[, NULL, 0]]]]?) = -NNNN (ENOTSOCK) + + s = socket(PF_INET, SOCK_DGRAM, 0); + //staptest// socket (PF_INET, SOCK_DGRAM, IPPROTO_IP) = NNNN + + connect(s, (struct sockaddr *)&sin1, sizeof(sin1)); + //staptest// connect (NNNN, {AF_INET, 0.0.0.0, NNNN}, 16) = 0 + + send(s, (void *)-1, sizeof(buf), 0); +#ifdef __s390__ + //staptest// send[[[[to]]]]? (NNNN, 0x[7]?[f]+, 1024, 0x0[[[[, NULL, 0]]]]?) = -NNNN (EFAULT) +#else + //staptest// send[[[[to]]]]? (NNNN, 0x[f]+, 1024, 0x0[[[[, NULL, 0]]]]?) = -NNNN (EFAULT) +#endif + + send(s, (void *)buf, -1, 0); +#if __WORDSIZE == 64 + //staptest// send[[[[to]]]]? (NNNN, XXXX, 18446744073709551615, 0x0[[[[, NULL, 0]]]]?) = -NNNN (EMSGSIZE) +#else + //staptest// send[[[[to]]]]? (NNNN, XXXX, 4294967295, 0x0[[[[, NULL, 0]]]]?) = -NNNN (EMSGSIZE) +#endif + + close(s); + //staptest// close (NNNN) = 0 + + s = socket(PF_INET, SOCK_STREAM, 0); + //staptest// socket (PF_INET, SOCK_STREAM, IPPROTO_IP) = NNNN + + connect(s, (struct sockaddr *)&sin1, sizeof(sin1)); + //staptest// connect (NNNN, {AF_INET, 0.0.0.0, NNNN}, 16) = 0 + + send(s, buf, sizeof(buf), MSG_DONTWAIT); + //staptest// send[[[[to]]]]? (NNNN, XXXX, 1024, MSG_DONTWAIT[[[[, NULL, 0]]]]?) = 1024 + + // Ignore the return value on this send() call. + send(s, buf, sizeof(buf), -1); + //staptest// send[[[[to]]]]? (NNNN, XXXX, 1024, MSG_[^ ]+|XXXX[[[[, NULL, 0]]]]?) + + close(s); + //staptest// close (NNNN) = 0 + + close(fd_null); + //staptest// close (NNNN) = 0 + + if (pid > 0) + (void)kill(pid, SIGKILL); /* kill server */ + //staptest// kill (NNNN, SIGKILL) = 0 + + return 0; +} diff --git a/testsuite/systemtap.syscall/sendto.c b/testsuite/systemtap.syscall/sendto.c new file mode 100644 index 000000000..3c27038a6 --- /dev/null +++ b/testsuite/systemtap.syscall/sendto.c @@ -0,0 +1,169 @@ +/* COVERAGE: sendto */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int sfd; /* shared between start_server and do_child */ + +void do_child() +{ + struct sockaddr_in fsin; + fd_set afds, rfds; + int nfds, cc, fd; + char buf[1024]; + + FD_ZERO(&afds); + FD_SET(sfd, &afds); + + nfds = FD_SETSIZE; + + /* accept connections until killed */ + while (1) { + socklen_t fromlen; + + memcpy(&rfds, &afds, sizeof(rfds)); + + if (select(nfds, &rfds, (fd_set *) 0, (fd_set *) 0, + (struct timeval *)0) < 0) { + if (errno != EINTR) + exit(1); + } + if (FD_ISSET(sfd, &rfds)) { + int newfd; + + fromlen = sizeof(fsin); + newfd = accept(sfd, (struct sockaddr *)&fsin, &fromlen); + if (newfd >= 0) + FD_SET(newfd, &afds); + } + for (fd = 0; fd < nfds; ++fd) { + if (fd != sfd && FD_ISSET(fd, &rfds)) { + cc = read(fd, buf, sizeof(buf)); + if (cc == 0 || (cc < 0 && errno != EINTR)) { + (void)close(fd); + FD_CLR(fd, &afds); + } + } + } + } +} + +pid_t +start_server(struct sockaddr_in *sin0) +{ + struct sockaddr_in sin1 = *sin0; + pid_t pid; + + sfd = socket(PF_INET, SOCK_STREAM, 0); + if (sfd < 0) + return -1; + if (bind(sfd, (struct sockaddr *)&sin1, sizeof(sin1)) < 0) + return -1; + if (listen(sfd, 10) < 0) + return -1; + + switch (pid = fork()) { + case 0: /* child */ + do_child(); + break; + case -1: /* fall through */ + default: /* parent */ + (void)close(sfd); + return pid; + } + + return -1; +} + +int main() +{ + int s, fd_null; + struct sockaddr_in sin1; + pid_t pid = 0; + char buf[1024]; + fd_set rdfds; + struct timeval timeout; + + /* initialize sockaddr's */ + sin1.sin_family = AF_INET; + sin1.sin_port = htons((getpid() % 32768) + 11000); + sin1.sin_addr.s_addr = INADDR_ANY; + + signal(SIGPIPE, SIG_IGN); + + pid = start_server(&sin1); + + fd_null = open("/dev/null", O_WRONLY); + + sendto(-1, buf, sizeof(buf), 0, NULL, 0); + //staptest// sendto (-1, XXXX, 1024, 0x0, NULL, 0) = -NNNN (EBADF) + + sendto(fd_null, buf, sizeof(buf), MSG_DONTWAIT, NULL, 0); + //staptest// sendto (NNNN, XXXX, 1024, MSG_DONTWAIT, NULL, 0) = -NNNN (ENOTSOCK) + + s = socket(PF_INET, SOCK_DGRAM, 0); + //staptest// socket (PF_INET, SOCK_DGRAM, IPPROTO_IP) = NNNN + + connect(s, (struct sockaddr *)&sin1, sizeof(sin1)); + //staptest// connect (NNNN, {AF_INET, 0.0.0.0, NNNN}, 16) = 0 + + sendto(s, (void *)buf, sizeof(buf), MSG_OOB, (struct sockaddr *)&sin1, + sizeof(sin1)); + //staptest// sendto (NNNN, XXXX, 1024, MSG_OOB, {AF_INET, 0.0.0.0, NNNN}, 16) = -NNNN (EOPNOTSUPP) + + sendto(s, (void *)-1, sizeof(buf), 0, (struct sockaddr *)&sin1, + sizeof(sin1)); + //staptest// sendto (NNNN, 0x[f]+, 1024, 0x0, {AF_INET, 0.0.0.0, NNNN}, 16) = -NNNN (EFAULT) + + sendto(s, (void *)buf, -1, 0, (struct sockaddr *)&sin1, sizeof(sin1)); +#if __WORDSIZE == 64 + //staptest// sendto (NNNN, XXXX, 18446744073709551615, 0x0, {AF_INET, 0.0.0.0, NNNN}, 16) = -NNNN (EMSGSIZE) +#else + //staptest// sendto (NNNN, XXXX, 4294967295, 0x0, {AF_INET, 0.0.0.0, NNNN}, 16) = -NNNN (EMSGSIZE) +#endif + + close(s); + //staptest// close (NNNN) = 0 + + s = socket(PF_INET, SOCK_STREAM, 0); + //staptest// socket (PF_INET, SOCK_STREAM, IPPROTO_IP) = NNNN + + connect(s, (struct sockaddr *)&sin1, sizeof(sin1)); + //staptest// connect (NNNN, {AF_INET, 0.0.0.0, NNNN}, 16) = 0 + + sendto(s, buf, sizeof(buf), 0, (struct sockaddr *)&sin1, sizeof(sin1)); + //staptest// sendto (NNNN, XXXX, 1024, 0x0, {AF_INET, 0.0.0.0, NNNN}, 16) = 1024 + + sendto(s, buf, sizeof(buf), 0, (struct sockaddr *)&sin1, -1); + //staptest// sendto (NNNN, XXXX, 1024, 0x0, {unknown .+}, 4294967295) = -NNNN (EINVAL) + + sendto(s, buf, sizeof(buf), 0, (struct sockaddr *)-1, sizeof(sin1)); + //staptest// sendto (NNNN, XXXX, 1024, 0x0, \[\.\.\.\], 16) = -NNNN (EFAULT) + + // Ignore the return value on this sendto() call. + sendto(s, buf, sizeof(buf), -1, (struct sockaddr *)&sin1, sizeof(sin1)); + //staptest// sendto (NNNN, XXXX, 1024, MSG_[^ ]+|XXXX, {AF_INET, 0.0.0.0, NNNN}, 16) + + close(s); + //staptest// close (NNNN) = 0 + + close(fd_null); + //staptest// close (NNNN) = 0 + + if (pid > 0) + (void)kill(pid, SIGKILL); /* kill server */ + //staptest// kill (NNNN, SIGKILL) = 0 + + return 0; +} -- 2.43.5