summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinun Dragonation <minun@mewmew.cn>2019-05-05 21:46:34 +0800
committerMinun Dragonation <minun@mewmew.cn>2019-05-05 21:46:34 +0800
commit4a94ce6326c51a2071025e929a3ab2a5263206f7 (patch)
tree199eb30a1c917a6e09f3eeabacfde08925cb7583
parent82252440de09067d46772da727dbc69c2e83fcf1 (diff)
fix bugs for optlen output on size not big enough for timeout events
-rw-r--r--sockcompat.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/sockcompat.c b/sockcompat.c
index 7e5b6a7..38cb9e5 100644
--- a/sockcompat.c
+++ b/sockcompat.c
@@ -191,11 +191,16 @@ int win32_connect(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen)
int win32_getsockopt(SOCKET sockfd, int level, int optname, void *optval, socklen_t *optlen) {
int ret = 0;
if ((level == SOL_SOCKET) && ((optname == SO_RCVTIMEO) || (optname == SO_SNDTIMEO))) {
- struct timeval *tv = (struct timeval *)optval;
- DWORD timeout = 0; socklen_t dwlen = 0;
- ret = getsockopt(sockfd, level, optname, (char *)&timeout, &dwlen);
- tv->tv_sec = timeout / 1000;
- tv->tv_usec = timeout * 1000;
+ if (*optlen >= sizeof (struct timeval)) {
+ struct timeval *tv = (struct timeval *)optval;
+ DWORD timeout = 0;
+ socklen_t dwlen = 0;
+ ret = getsockopt(sockfd, level, optname, (char *)&timeout, &dwlen);
+ tv->tv_sec = timeout / 1000;
+ tv->tv_usec = timeout * 1000;
+ } else {
+ ret = WSAEFAULT;
+ }
*optlen = sizeof (struct timeval);
} else {
ret = getsockopt(sockfd, level, optname, (char*)optval, optlen);