From ed599301a752c999a4f84643874ee5f252ffad4e Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Thu, 7 Jul 2022 17:29:22 +1200 Subject: [PATCH] Add accept() wrapper Check an assumption that Microsoft's SOCKET type only actually holds 32 bit values even in 64 bit platforms and throw an exception if violated. (cherry picked from commit c6708b8351ee80f871ba746d517fcda1a8bc9c6d) --- xapian-core/common/safesyssocket.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/xapian-core/common/safesyssocket.h b/xapian-core/common/safesyssocket.h index 7fb42c53c..f5e00c469 100644 --- a/xapian-core/common/safesyssocket.h +++ b/xapian-core/common/safesyssocket.h @@ -64,6 +64,31 @@ inline int socket_(int domain, int type, int protocol) { # endif # define socket(D,T,P) socket_(D,T,P) +inline int accept_(int sockfd, struct sockaddr* addr, SOCKLEN_T* addrlen) { + // Winsock2's accept() returns the unsigned type SOCKET, which is a 32-bit + // type for WIN32 and a 64-bit type for WIN64. + // + // It seems we can always safely assign SOCKET to an int: failure is indicated + // by INVALID_SOCKET which will cast to -1 as an int, and it seems in + // practice that valid values all fit in 31-bits (and that we're not the + // only code to assume this since it makes it much easier to write code + // that deals with BSD sockets and winsock2's bastardised version of them) + // so Microsoft are unlikely to arbitrarily change that). + // + // But we should check and throw an exception rather than quietly mangling + // the value. + SOCKET sock = accept(sockfd, addr, addrlen); + if (rare(sock > SOCKET(0x7fffffff) && sock != INVALID_SOCKET)) { + throw Xapian::NetworkError("accept() returned value > INT_MAX"); + } + return int(sock); +} + +# ifdef accept +# undef accept +# endif +# define accept(S,A,L) accept_(S,A,L) + #elif !defined SOCK_CLOEXEC # define SOCK_CLOEXEC 0 #else -- 2.11.4.GIT