diff options
author | Minun Dragonation <minun@mewmew.cn> | 2019-05-05 21:46:34 +0800 |
---|---|---|
committer | Minun Dragonation <minun@mewmew.cn> | 2019-05-05 21:46:34 +0800 |
commit | 4a94ce6326c51a2071025e929a3ab2a5263206f7 (patch) | |
tree | 199eb30a1c917a6e09f3eeabacfde08925cb7583 | |
parent | 82252440de09067d46772da727dbc69c2e83fcf1 (diff) |
fix bugs for optlen output on size not big enough for timeout events
-rw-r--r-- | sockcompat.c | 15 |
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); |