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 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c
index 94d15f2..ab9476d 100644
--- a/coregrind/m_syswrap/syswrap-generic.c
+++ b/coregrind/m_syswrap/syswrap-generic.c
@@ -1146,10 +1146,17 @@
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 @@
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 d1c2876..7eb1906 100644
--- a/include/vki-amd64-linux.h
+++ b/include/vki-amd64-linux.h
@@ -44,6 +44,7 @@
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 6868e3b..5d6df36 100644
--- a/include/vki-linux.h
+++ b/include/vki-linux.h
@@ -587,6 +587,8 @@
#define VKI_MSG_NOSIGNAL 0x4000 /* Do not generate SIGPIPE */
+#define VKI_SOL_SCTP 132
+
//----------------------------------------------------------------------
// From linux-2.6.8.1/include/linux/in.h
//----------------------------------------------------------------------
@@ -772,6 +774,73 @@
};
//----------------------------------------------------------------------
+// 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 5d385a5..cc3d071 100644
--- a/include/vki-ppc32-linux.h
+++ b/include/vki-ppc32-linux.h
@@ -44,6 +44,7 @@
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 f713fb3..ae73305 100644
--- a/include/vki-x86-linux.h
+++ b/include/vki-x86-linux.h
@@ -43,6 +43,7 @@
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;