build: avoid overriding system symbols for socket functions

Before this patch `accept4()`, `socket()`, `socketpair()`, `send()` and
`recv()` system symbols were remapped via macros, using the same name,
to local curl debug wrappers. This patch replaces these overrides by
introducing curl-namespaced macros that map either to the system symbols
or to their curl debug wrappers in `CURLDEBUG` (TrackMemory) builds.

This follows a patch that implemented the same for `accept()`.

The old method required tricks to make these redefines work in unity
builds, and avoid them interfering with system headers. These tricks
did not work for system symbols implemented as macros.

The new method allows to setup these mappings once, without interfering
with system headers, upstream macros, or unity builds. It makes builds
more robust.

Also:
- checksrc: ban all mapped functions.
- docs/examples: tidy up checksrc rules.

Follow-up to 9863599d69b79d290928a89bf9160f4e4e023d4e #18502
Follow-up to 3bb5e58c105d7be450b667858d1b8e7ae3ded555 #17827

Closes #18503
This commit is contained in:
Viktor Szakats 2025-09-09 15:29:12 +02:00
parent 2fe95cb0e3
commit bf7375ecc5
No known key found for this signature in database
GPG Key ID: B5ABD165E2AEF201
24 changed files with 74 additions and 57 deletions

View File

@ -40,6 +40,7 @@ path = [
"tests/data/test**",
"tests/valgrind.supp",
# checksrc control files
"docs/examples/.checksrc",
"lib/.checksrc",
"lib/curlx/.checksrc",
"lib/vauth/.checksrc",

3
docs/examples/.checksrc Normal file
View File

@ -0,0 +1,3 @@
allowfunc gmtime
allowfunc localtime
allowfunc socket

View File

@ -24,7 +24,7 @@
AUTOMAKE_OPTIONS = foreign nostdinc
EXTRA_DIST = CMakeLists.txt README.md Makefile.example $(COMPLICATED_EXAMPLES)
EXTRA_DIST = CMakeLists.txt .checksrc README.md Makefile.example $(COMPLICATED_EXAMPLES)
# Specify our include paths here, and do it relative to $(top_srcdir) and
# $(top_builddir), to ensure that these paths which belong to the library

View File

@ -161,7 +161,6 @@ int my_trace(CURL *handle, curl_infotype type,
known_offset = 1;
}
secs = epoch_offset + tv.tv_sec;
/* !checksrc! disable BANNEDFUNC 1 */
now = localtime(&secs); /* not thread safe but we do not care */
curl_msnprintf(timebuf, sizeof(timebuf), "%02d:%02d:%02d.%06ld",
now->tm_hour, now->tm_min, now->tm_sec, (long)tv.tv_usec);

View File

@ -298,10 +298,8 @@ int main(int argc, char *argv[])
/* Calculating time diff between GMT and localtime */
tt = time(0);
/* !checksrc! disable BANNEDFUNC 1 */
lt = localtime(&tt);
tt_local = mktime(lt);
/* !checksrc! disable BANNEDFUNC 1 */
gmt = gmtime(&tt);
tt_gmt = mktime(gmt);
tzonediffFloat = difftime(tt_local, tt_gmt);

View File

@ -369,7 +369,7 @@ static CURLcode socket_open(struct Curl_easy *data,
}
else {
/* opensocket callback not set, so simply create the socket now */
*sockfd = socket(addr->family, addr->socktype, addr->protocol);
*sockfd = CURL_SOCKET(addr->family, addr->socktype, addr->protocol);
}
if(*sockfd == CURL_SOCKET_BAD)
@ -2113,8 +2113,8 @@ static CURLcode cf_tcp_accept_connect(struct Curl_cfilter *cf,
if(!getsockname(ctx->sock, (struct sockaddr *) &add, &size)) {
size = sizeof(add);
#ifdef HAVE_ACCEPT4
s_accepted = accept4(ctx->sock, (struct sockaddr *) &add, &size,
SOCK_NONBLOCK | SOCK_CLOEXEC);
s_accepted = CURL_ACCEPT4(ctx->sock, (struct sockaddr *) &add, &size,
SOCK_NONBLOCK | SOCK_CLOEXEC);
#else
s_accepted = CURL_ACCEPT(ctx->sock, (struct sockaddr *) &add, &size);
#endif

View File

@ -507,9 +507,11 @@ curl_dbg_freeaddrinfo(struct addrinfo *freethis,
if(env)
r_freeaddrinfo(freethis);
else
/* !checksrc! disable BANNEDFUNC 1 */
freeaddrinfo(freethis);
}
#else
/* !checksrc! disable BANNEDFUNC 1 */
freeaddrinfo(freethis);
#endif
}
@ -540,8 +542,10 @@ curl_dbg_getaddrinfo(const char *hostname,
if(env)
res = r_getaddrinfo(hostname, service, hints, result);
else
/* !checksrc! disable BANNEDFUNC 1 */
res = getaddrinfo(hostname, service, hints, result);
#else
/* !checksrc! disable BANNEDFUNC 1 */
int res = getaddrinfo(hostname, service, hints, result);
#endif
if(res == 0)

View File

@ -35,17 +35,6 @@
#ifdef CURLDEBUG
#undef send
#undef recv
#undef socket
#ifdef HAVE_ACCEPT4
#undef accept4
#endif
#ifdef HAVE_SOCKETPAIR
#undef socketpair
#endif
#undef fopen
#ifdef CURL_FOPEN
#define fopen(fname, mode) CURL_FOPEN(fname, mode)

View File

@ -1083,9 +1083,21 @@ CURL_EXTERN ALLOC_FUNC
curl_dbg_getaddrinfo(host, serv, hint, res, __LINE__, __FILE__)
#define CURL_FREEADDRINFO(data) \
curl_dbg_freeaddrinfo(data, __LINE__, __FILE__)
#define CURL_SOCKET(domain,type,protocol) \
curl_dbg_socket((int)domain, type, protocol, __LINE__, __FILE__)
#ifdef HAVE_SOCKETPAIR
#define CURL_SOCKETPAIR(domain,type,protocol,socket_vector) \
curl_dbg_socketpair((int)domain, type, protocol, socket_vector, \
__LINE__, __FILE__)
#endif
#define CURL_ACCEPT(sock,addr,len) \
curl_dbg_accept(sock, addr, len, __LINE__, __FILE__)
#ifdef HAVE_ACCEPT4
#define CURL_ACCEPT4(sock,addr,len,flags) \
curl_dbg_accept4(sock, addr, len, flags, __LINE__, __FILE__)
#endif
#define CURL_SEND(a,b,c,d) curl_dbg_send(a,b,c,d, __LINE__, __FILE__)
#define CURL_RECV(a,b,c,d) curl_dbg_recv(a,b,c,d, __LINE__, __FILE__)
#else /* !CURLDEBUG */
@ -1094,8 +1106,16 @@ CURL_EXTERN ALLOC_FUNC
#define CURL_GETADDRINFO getaddrinfo
#define CURL_FREEADDRINFO freeaddrinfo
#define CURL_SOCKET socket
#ifdef HAVE_SOCKETPAIR
#define CURL_SOCKETPAIR socketpair
#endif
#define CURL_ACCEPT accept
#ifdef HAVE_ACCEPT4
#define CURL_ACCEPT4 accept4
#endif
#define CURL_SEND send
#define CURL_RECV recv
#endif /* CURLDEBUG */

View File

@ -709,7 +709,7 @@ bool Curl_ipv6works(struct Curl_easy *data)
else {
int ipv6_works = -1;
/* probe to see if we have a working IPv6 stack */
curl_socket_t s = socket(PF_INET6, SOCK_DGRAM, 0);
curl_socket_t s = CURL_SOCKET(PF_INET6, SOCK_DGRAM, 0);
if(s == CURL_SOCKET_BAD)
/* an IPv6 address was requested but we cannot get/use one */
ipv6_works = 0;

View File

@ -208,7 +208,7 @@ if2ip_result_t Curl_if2ip(int af,
if(len >= sizeof(req.ifr_name))
return IF2IP_NOT_FOUND;
dummy = socket(AF_INET, SOCK_STREAM, 0);
dummy = CURL_SOCKET(AF_INET, SOCK_STREAM, 0);
if(CURL_SOCKET_BAD == dummy)
return IF2IP_NOT_FOUND;

View File

@ -311,7 +311,8 @@ curl_socket_t curl_dbg_socket(int domain, int type, int protocol,
if(countcheck("socket", line, source))
return CURL_SOCKET_BAD;
sockfd = (socket)(domain, type, protocol);
/* !checksrc! disable BANNEDFUNC 1 */
sockfd = socket(domain, type, protocol);
if(source && (sockfd != CURL_SOCKET_BAD))
curl_dbg_log("FD %s:%d socket() = %" FMT_SOCKET_T "\n",
@ -328,7 +329,8 @@ SEND_TYPE_RETV curl_dbg_send(SEND_TYPE_ARG1 sockfd,
SEND_TYPE_RETV rc;
if(countcheck("send", line, source))
return -1;
rc = (send)(sockfd, buf, len, flags);
/* !checksrc! disable BANNEDFUNC 1 */
rc = send(sockfd, buf, len, flags);
if(source)
curl_dbg_log("SEND %s:%d send(%lu) = %ld\n",
source, line, (unsigned long)len, (long)rc);
@ -342,7 +344,8 @@ RECV_TYPE_RETV curl_dbg_recv(RECV_TYPE_ARG1 sockfd, RECV_TYPE_ARG2 buf,
RECV_TYPE_RETV rc;
if(countcheck("recv", line, source))
return -1;
rc = (recv)(sockfd, buf, len, flags);
/* !checksrc! disable BANNEDFUNC 1 */
rc = recv(sockfd, buf, len, flags);
if(source)
curl_dbg_log("RECV %s:%d recv(%lu) = %ld\n",
source, line, (unsigned long)len, (long)rc);
@ -354,7 +357,8 @@ int curl_dbg_socketpair(int domain, int type, int protocol,
curl_socket_t socket_vector[2],
int line, const char *source)
{
int res = (socketpair)(domain, type, protocol, socket_vector);
/* !checksrc! disable BANNEDFUNC 1 */
int res = socketpair(domain, type, protocol, socket_vector);
if(source && (res == 0))
curl_dbg_log("FD %s:%d socketpair() = "
@ -371,6 +375,7 @@ curl_socket_t curl_dbg_accept(curl_socket_t s, void *saddr, void *saddrlen,
struct sockaddr *addr = (struct sockaddr *)saddr;
curl_socklen_t *addrlen = (curl_socklen_t *)saddrlen;
/* !checksrc! disable BANNEDFUNC 1 */
curl_socket_t sockfd = accept(s, addr, addrlen);
if(source && (sockfd != CURL_SOCKET_BAD))
@ -388,7 +393,8 @@ curl_socket_t curl_dbg_accept4(curl_socket_t s, void *saddr, void *saddrlen,
struct sockaddr *addr = (struct sockaddr *)saddr;
curl_socklen_t *addrlen = (curl_socklen_t *)saddrlen;
curl_socket_t sockfd = (accept4)(s, addr, addrlen, flags);
/* !checksrc! disable BANNEDFUNC 1 */
curl_socket_t sockfd = accept4(s, addr, addrlen, flags);
if(source && (sockfd != CURL_SOCKET_BAD))
curl_dbg_log("FD %s:%d accept() = %" FMT_SOCKET_T "\n",

View File

@ -42,10 +42,6 @@
#define realloc(ptr,size) curl_dbg_realloc(ptr, size, __LINE__, __FILE__)
#undef free
#define free(ptr) curl_dbg_free(ptr, __LINE__, __FILE__)
#undef send
#define send(a,b,c,d) curl_dbg_send(a,b,c,d, __LINE__, __FILE__)
#undef recv
#define recv(a,b,c,d) curl_dbg_recv(a,b,c,d, __LINE__, __FILE__)
#ifdef _WIN32
#undef Curl_tcsdup
@ -56,20 +52,6 @@
#endif
#endif /* _WIN32 */
#undef socket
#define socket(domain,type,protocol) \
curl_dbg_socket((int)domain, type, protocol, __LINE__, __FILE__)
#ifdef HAVE_ACCEPT4
#undef accept4 /* for those with accept4 as a macro */
#define accept4(sock,addr,len,flags) \
curl_dbg_accept4(sock, addr, len, flags, __LINE__, __FILE__)
#endif
#ifdef HAVE_SOCKETPAIR
#define socketpair(domain,type,protocol,socket_vector) \
curl_dbg_socketpair((int)domain, type, protocol, socket_vector, \
__LINE__, __FILE__)
#endif
#undef fopen
#define fopen(file,mode) curl_dbg_fopen(file,mode,__LINE__,__FILE__)
#undef fdopen

View File

@ -1277,7 +1277,7 @@ static void reset_socket_fdwrite(curl_socket_t s)
int t;
int l = (int)sizeof(t);
if(!getsockopt(s, SOL_SOCKET, SO_TYPE, (char *)&t, &l) && t == SOCK_STREAM)
send(s, NULL, 0, 0);
CURL_SEND(s, NULL, 0, 0);
}
#endif

View File

@ -91,7 +91,7 @@ int Curl_socketpair(int domain, int type, int protocol,
#ifdef SOCK_NONBLOCK
type = nonblocking ? type | SOCK_NONBLOCK : type;
#endif
if(socketpair(domain, type, protocol, socks))
if(CURL_SOCKETPAIR(domain, type, protocol, socks))
return -1;
#ifndef SOCK_NONBLOCK
if(nonblocking) {
@ -154,7 +154,7 @@ int Curl_socketpair(int domain, int type, int protocol,
(void)type;
(void)protocol;
listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
listener = CURL_SOCKET(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(listener == CURL_SOCKET_BAD)
return -1;
@ -188,7 +188,7 @@ int Curl_socketpair(int domain, int type, int protocol,
goto error;
if(listen(listener, 1) == -1)
goto error;
socks[0] = socket(AF_INET, SOCK_STREAM, 0);
socks[0] = CURL_SOCKET(AF_INET, SOCK_STREAM, 0);
if(socks[0] == CURL_SOCKET_BAD)
goto error;
if(connect(socks[0], &a.addr, sizeof(a.inaddr)) == -1)

View File

@ -196,8 +196,8 @@ static CURLcode do_sendmsg(struct Curl_cfilter *cf,
*psent = 0;
while((sent = send(qctx->sockfd,
(const char *)pkt, (SEND_TYPE_ARG3)pktlen, 0)) == -1 &&
while((sent = CURL_SEND(qctx->sockfd, (const char *)pkt,
(SEND_TYPE_ARG3)pktlen, 0)) == -1 &&
SOCKERRNO == SOCKEINTR)
;

View File

@ -333,6 +333,7 @@ Curl_getaddrinfo_a(const char *nodename, const char *servname,
eservname[i] = '\0';
}
/* !checksrc! disable BANNEDFUNC 1 */
status = getaddrinfo(enodename, eservname, hints, res);
free(enodename);
free(eservname);

View File

@ -77,6 +77,14 @@ my %banfunc = (
"_waccess" => 1,
"_access" => 1,
"access" => 1,
"accept" => 1,
"accept4" => 1,
"freeaddrinfo" => 1,
"getaddrinfo" => 1,
"recv" => 1,
"send" => 1,
"socket" => 1,
"socketpair" => 1,
);
my %warnings_extended = (

View File

@ -92,7 +92,7 @@ size_t tool_read_cb(char *buffer, size_t sz, size_t nmemb, void *userdata)
execute */
if(per->uploadfile && !strcmp(per->uploadfile, ".") && per->infd > 0) {
#if defined(_WIN32) && !defined(CURL_WINDOWS_UWP) && !defined(UNDER_CE)
rc = recv(per->infd, buffer, curlx_uztosi(sz * nmemb), 0);
rc = CURL_RECV(per->infd, buffer, curlx_uztosi(sz * nmemb), 0);
if(rc < 0) {
if(SOCKERRNO == SOCKEWOULDBLOCK) {
CURL_SETERRNO(0);

View File

@ -54,5 +54,5 @@ curl_socket_t tool_socket_open_mptcp_cb(void *clientp,
return CURL_SOCKET_BAD;
#endif
return socket(addr->family, addr->socktype, protocol);
return CURL_SOCKET(addr->family, addr->socktype, protocol);
}

View File

@ -785,7 +785,7 @@ static DWORD WINAPI win_stdin_thread_func(void *thread_data)
break;
if(n == 0)
break;
nwritten = send(socket_w, buffer, n, 0);
nwritten = CURL_SEND(socket_w, buffer, n, 0);
if(nwritten == SOCKET_ERROR)
break;
if((DWORD)nwritten != n)
@ -889,7 +889,7 @@ curl_socket_t win32_stdin_read_thread(void)
}
/* Connect to the thread and rearrange our own STDIN handles */
socket_r = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
socket_r = CURL_SOCKET(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(socket_r == CURL_SOCKET_BAD) {
errorf("socket error: %08lx", GetLastError());
break;

View File

@ -96,7 +96,7 @@ static CURLcode test_lib1960(const char *URL)
* over this socket as "already connected" to libcurl and make sure that
* this works.
*/
client_fd = socket(AF_INET, SOCK_STREAM, 0);
client_fd = CURL_SOCKET(AF_INET, SOCK_STREAM, 0);
if(client_fd == CURL_SOCKET_BAD) {
curl_mfprintf(stderr, "socket creation error\n");
goto test_cleanup;

View File

@ -35,7 +35,7 @@ static curl_socket_t tst_opensocket(void *clientp,
(void)clientp;
(void)purpose;
curl_mprintf("[OPEN] counter: %d\n", ++testcounter);
return socket(addr->family, addr->socktype, addr->protocol);
return CURL_SOCKET(addr->family, addr->socktype, addr->protocol);
}
static int tst_closesocket(void *clientp, curl_socket_t sock)

View File

@ -1 +1,7 @@
allowfunc accept
allowfunc freeaddrinfo
allowfunc getaddrinfo
allowfunc recv
allowfunc send
allowfunc socket
allowfunc strtoul