From: Tom Hughes Date: Sun, 28 Aug 2005 10:16:29 +0000 (+0000) Subject: Handle the SCTP_GET_LOCAL_ADDRS and SCTP_GET_PEER_ADDRS getsockopt X-Git-Tag: svn/VALGRIND_3_1_0~500 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cf8c1b047f1ee7834e778832a36a60b39fa28f2d;p=thirdparty%2Fvalgrind.git Handle the SCTP_GET_LOCAL_ADDRS and SCTP_GET_PEER_ADDRS getsockopt calls correctly. Fix to bug #111231. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@4549 --- diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c index 94d15f2b15..ab9476d955 100644 --- a/coregrind/m_syswrap/syswrap-generic.c +++ b/coregrind/m_syswrap/syswrap-generic.c @@ -1146,10 +1146,17 @@ ML_(generic_PRE_sys_getsockopt) ( ThreadId tid, Addr optval_p = arg3; Addr optlen_p = arg4; /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */ - if (optval_p != (Addr)NULL) + if (optval_p != (Addr)NULL) { buf_and_len_pre_check ( tid, optval_p, optlen_p, "socketcall.getsockopt(optval)", "socketcall.getsockopt(optlen)" ); + if (arg1 == VKI_SOL_SCTP && + (arg2 == VKI_SCTP_GET_PEER_ADDRS || arg2 == VKI_SCTP_GET_LOCAL_ADDRS)) { + struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3; + int address_bytes = sizeof(struct vki_sockaddr_in6) * ga->addr_num; + PRE_MEM_WRITE( "socketcall.getsockopt(optval.addrs)", (Addr)ga->addrs, address_bytes ); + } + } } void @@ -1161,9 +1168,28 @@ ML_(generic_POST_sys_getsockopt) ( ThreadId tid, Addr optval_p = arg3; Addr optlen_p = arg4; vg_assert(!res.isError); /* guaranteed by caller */ - if (optval_p != (Addr)NULL) + if (optval_p != (Addr)NULL) { buf_and_len_post_check ( tid, res, optval_p, optlen_p, "socketcall.getsockopt(optlen_out)" ); + if (arg1 == VKI_SOL_SCTP && + (arg2 == VKI_SCTP_GET_PEER_ADDRS || arg2 == VKI_SCTP_GET_LOCAL_ADDRS)) { + struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3; + struct vki_sockaddr *a = ga->addrs; + int i; + for (i = 0; i < ga->addr_num; i++) { + int sl = 0; + if (a->sa_family == VKI_AF_INET) + sl = sizeof(struct vki_sockaddr_in); + else if (a->sa_family == VKI_AF_INET6) + sl = sizeof(struct vki_sockaddr_in6); + else { + VG_(message)(Vg_UserMsg, "Warning: getsockopt: unhandled address type %d", a->sa_family); + } + a = (struct vki_sockaddr*)((char*)a + sl); + } + POST_MEM_WRITE( (Addr)ga->addrs, (char*)a - (char*)ga->addrs ); + } + } } /* ------ */ diff --git a/include/vki-amd64-linux.h b/include/vki-amd64-linux.h index d1c2876990..7eb1906f33 100644 --- a/include/vki-amd64-linux.h +++ b/include/vki-amd64-linux.h @@ -44,6 +44,7 @@ typedef unsigned char __vki_u8; typedef __signed__ short __vki_s16; typedef unsigned short __vki_u16; +typedef __signed__ int __vki_s32; typedef unsigned int __vki_u32; typedef __signed__ long long __vki_s64; diff --git a/include/vki-linux.h b/include/vki-linux.h index 6868e3b3ac..5d6df36c67 100644 --- a/include/vki-linux.h +++ b/include/vki-linux.h @@ -587,6 +587,8 @@ __KINLINE struct vki_cmsghdr * vki_cmsg_nxthdr (struct vki_msghdr *__msg, struct #define VKI_MSG_NOSIGNAL 0x4000 /* Do not generate SIGPIPE */ +#define VKI_SOL_SCTP 132 + //---------------------------------------------------------------------- // From linux-2.6.8.1/include/linux/in.h //---------------------------------------------------------------------- @@ -771,6 +773,73 @@ struct vki_rtentry unsigned short rt_irtt; /* Initial RTT */ }; +//---------------------------------------------------------------------- +// From linux-2.6.13-rc5/include/net/sctp/user.h +//---------------------------------------------------------------------- + +typedef __vki_s32 vki_sctp_assoc_t; + +enum vki_sctp_optname { + VKI_SCTP_RTOINFO, +#define VKI_SCTP_RTOINFO VKI_SCTP_RTOINFO + VKI_SCTP_ASSOCINFO, +#define VKI_SCTP_ASSOCINFO VKI_SCTP_ASSOCINFO + VKI_SCTP_INITMSG, +#define VKI_SCTP_INITMSG VKI_SCTP_INITMSG + VKI_SCTP_NODELAY, /* Get/set nodelay option. */ +#define VKI_SCTP_NODELAY VKI_SCTP_NODELAY + VKI_SCTP_AUTOCLOSE, +#define VKI_SCTP_AUTOCLOSE VKI_SCTP_AUTOCLOSE + VKI_SCTP_SET_PEER_PRIMARY_ADDR, +#define VKI_SCTP_SET_PEER_PRIMARY_ADDR VKI_SCTP_SET_PEER_PRIMARY_ADDR + VKI_SCTP_PRIMARY_ADDR, +#define VKI_SCTP_PRIMARY_ADDR VKI_SCTP_PRIMARY_ADDR + VKI_SCTP_ADAPTION_LAYER, +#define VKI_SCTP_ADAPTION_LAYER VKI_SCTP_ADAPTION_LAYER + VKI_SCTP_DISABLE_FRAGMENTS, +#define VKI_SCTP_DISABLE_FRAGMENTS VKI_SCTP_DISABLE_FRAGMENTS + VKI_SCTP_PEER_ADDR_PARAMS, +#define VKI_SCTP_PEER_ADDR_PARAMS VKI_SCTP_PEER_ADDR_PARAMS + VKI_SCTP_DEFAULT_SEND_PARAM, +#define VKI_SCTP_DEFAULT_SEND_PARAM VKI_SCTP_DEFAULT_SEND_PARAM + VKI_SCTP_EVENTS, +#define VKI_SCTP_EVENTS VKI_SCTP_EVENTS + VKI_SCTP_I_WANT_MAPPED_V4_ADDR, /* Turn on/off mapped v4 addresses */ +#define VKI_SCTP_I_WANT_MAPPED_V4_ADDR VKI_SCTP_I_WANT_MAPPED_V4_ADDR + VKI_SCTP_MAXSEG, /* Get/set maximum fragment. */ +#define VKI_SCTP_MAXSEG VKI_SCTP_MAXSEG + VKI_SCTP_STATUS, +#define VKI_SCTP_STATUS VKI_SCTP_STATUS + VKI_SCTP_GET_PEER_ADDR_INFO, +#define VKI_SCTP_GET_PEER_ADDR_INFO VKI_SCTP_GET_PEER_ADDR_INFO + + /* Internal Socket Options. Some of the sctp library functions are + * implemented using these socket options. + */ + VKI_SCTP_SOCKOPT_BINDX_ADD = 100,/* BINDX requests for adding addresses. */ +#define VKI_SCTP_SOCKOPT_BINDX_ADD VKI_SCTP_SOCKOPT_BINDX_ADD + VKI_SCTP_SOCKOPT_BINDX_REM, /* BINDX requests for removing addresses. */ +#define VKI_SCTP_SOCKOPT_BINDX_REM VKI_SCTP_SOCKOPT_BINDX_REM + VKI_SCTP_SOCKOPT_PEELOFF, /* peel off association. */ +#define VKI_SCTP_SOCKOPT_PEELOFF VKI_SCTP_SOCKOPT_PEELOFF + VKI_SCTP_GET_PEER_ADDRS_NUM, /* Get number of peer addresss. */ +#define VKI_SCTP_GET_PEER_ADDRS_NUM VKI_SCTP_GET_PEER_ADDRS_NUM + VKI_SCTP_GET_PEER_ADDRS, /* Get all peer addresss. */ +#define VKI_SCTP_GET_PEER_ADDRS VKI_SCTP_GET_PEER_ADDRS + VKI_SCTP_GET_LOCAL_ADDRS_NUM, /* Get number of local addresss. */ +#define VKI_SCTP_GET_LOCAL_ADDRS_NUM VKI_SCTP_GET_LOCAL_ADDRS_NUM + VKI_SCTP_GET_LOCAL_ADDRS, /* Get all local addresss. */ +#define VKI_SCTP_GET_LOCAL_ADDRS VKI_SCTP_GET_LOCAL_ADDRS + VKI_SCTP_SOCKOPT_CONNECTX, /* CONNECTX requests. */ +#define VKI_SCTP_SOCKOPT_CONNECTX VKI_SCTP_SOCKOPT_CONNECTX +}; + +struct vki_sctp_getaddrs { + vki_sctp_assoc_t assoc_id; + int addr_num; + struct vki_sockaddr *addrs; +}; + //---------------------------------------------------------------------- // From linux-2.6.8.1/include/linux/resource.h //---------------------------------------------------------------------- diff --git a/include/vki-ppc32-linux.h b/include/vki-ppc32-linux.h index 5d385a5c4f..cc3d071579 100644 --- a/include/vki-ppc32-linux.h +++ b/include/vki-ppc32-linux.h @@ -44,6 +44,7 @@ typedef unsigned char __vki_u8; typedef __signed__ short __vki_s16; typedef unsigned short __vki_u16; +typedef __signed__ int __vki_s32; typedef unsigned int __vki_u32; typedef __signed__ long long __vki_s64; diff --git a/include/vki-x86-linux.h b/include/vki-x86-linux.h index f713fb32ba..ae73305aea 100644 --- a/include/vki-x86-linux.h +++ b/include/vki-x86-linux.h @@ -43,6 +43,7 @@ typedef unsigned char __vki_u8; typedef __signed__ short __vki_s16; typedef unsigned short __vki_u16; +typedef __signed__ int __vki_s32; typedef unsigned int __vki_u32; typedef __signed__ long long __vki_s64;