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 9863599d69 #18502
Follow-up to 3bb5e58c10 #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

@ -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)
;