Use O_CLOEXEC to avoid race conditions

This commit is contained in:
Eric Blankenhorn
2026-04-07 17:07:14 -05:00
parent 178e10e42a
commit e26ab427a5
13 changed files with 182 additions and 23 deletions
+7
View File
@@ -219,6 +219,7 @@ DTLS_RECEIVEFROM_NO_TIMEOUT_ON_INVALID_PEER
ECCSI_ORDER_MORE_BITS_THAN_PRIME
ECC_DUMP_OID
ECDHE_SIZE
EFD_CLOEXEC
ENABLED_BSDKM_REGISTER
ENABLE_SECURE_SOCKETS_LOGS
ESP32
@@ -234,6 +235,7 @@ ETHERNET_AVAILABLE
ETHERNET_H
EV_TRIGGER
EXTERNAL_LOADER_APP
FD_CLOEXEC
FIPS_OPTEST_FULL_RUN_AT_MODULE_INIT
FORCE_FAILURE_GETRANDOM
FP_ECC_CONTROL
@@ -317,6 +319,7 @@ IGNORE_NETSCAPE_CERT_TYPE
INCLUDE_uxTaskGetStackHighWaterMark
INTEGRITY
INTIMEVER
IN_CLOEXEC
IOTSAFE_NO_GETDATA
IOTSAFE_SIG_8BIT_LENGTH
KCAPI_USE_XMALLOC
@@ -476,7 +479,9 @@ OPENSSL_NO_PK
OS_WINDOWS
OTHERBOARD
OTHER_BOARD
O_CLOEXEC
PEER_INFO
PERF_FLAG_FD_CLOEXEC
PKA_ECC_SCALAR_MUL_IN_B_COEFF
PLATFORMIO
PLUTON_CRYPTO_ECC
@@ -519,6 +524,7 @@ SL_SE_KEY_TYPE_ECC_X25519
SL_SE_KEY_TYPE_ECC_X448
SL_SE_PRF_HMAC_SHA1
SNIFFER_SINGLE_SESSION_CACHE
SOCK_CLOEXEC
SOFTDEVICE_PRESENT
SO_NOSIGPIPE
SO_REUSEPORT
@@ -1116,6 +1122,7 @@ __sun
__svr4__
__thumb__
__ti__
__unix__
__x86_64__
__xtensa__
byte
+28 -3
View File
@@ -1659,6 +1659,7 @@ static int SwapLists(WOLFSSL_CRL* crl)
#include <sys/time.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#ifdef __MACH__
#define XEVENT_MODE O_EVTONLY
@@ -1667,6 +1668,7 @@ static int SwapLists(WOLFSSL_CRL* crl)
#endif
/* we need a unique kqueue user filter fd for crl in case user is doing custom
* events too */
#ifndef CRL_CUSTOM_FD
@@ -1710,6 +1712,7 @@ static THREAD_RETURN WOLFSSL_THREAD DoMonitor(void* arg)
SignalSetup(crl, MONITOR_SETUP_E);
return NULL;
}
wc_set_cloexec(crl->mfd);
/* listen for custom shutdown event */
EV_SET(&change, CRL_CUSTOM_FD, EVFILT_USER, EV_ADD, 0, 0, NULL);
@@ -1724,7 +1727,7 @@ static THREAD_RETURN WOLFSSL_THREAD DoMonitor(void* arg)
fDER = -1;
if (crl->monitors[0].path) {
fPEM = open(crl->monitors[0].path, XEVENT_MODE);
fPEM = wc_open_cloexec(crl->monitors[0].path, XEVENT_MODE);
if (fPEM == -1) {
WOLFSSL_MSG("PEM event dir open failed");
SignalSetup(crl, MONITOR_SETUP_E);
@@ -1734,7 +1737,7 @@ static THREAD_RETURN WOLFSSL_THREAD DoMonitor(void* arg)
}
if (crl->monitors[1].path) {
fDER = open(crl->monitors[1].path, XEVENT_MODE);
fDER = wc_open_cloexec(crl->monitors[1].path, XEVENT_MODE);
if (fDER == -1) {
WOLFSSL_MSG("DER event dir open failed");
if (fPEM != -1)
@@ -1801,6 +1804,13 @@ static THREAD_RETURN WOLFSSL_THREAD DoMonitor(void* arg)
#include <sys/inotify.h>
#include <sys/eventfd.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
/* Fall back to no-op if EFD_CLOEXEC is unavailable. */
#ifndef EFD_CLOEXEC
#define EFD_CLOEXEC 0
#endif
#ifndef max
@@ -1836,14 +1846,29 @@ static THREAD_RETURN WOLFSSL_THREAD DoMonitor(void* arg)
WOLFSSL_ENTER("DoMonitor");
crl->mfd = eventfd(0, 0); /* our custom shutdown event */
crl->mfd = eventfd(0, EFD_CLOEXEC); /* our custom shutdown event */
#ifdef FD_CLOEXEC
if (crl->mfd < 0 && errno == EINVAL) {
crl->mfd = eventfd(0, 0);
wc_set_cloexec(crl->mfd);
}
#endif
if (crl->mfd < 0) {
WOLFSSL_MSG("eventfd failed");
SignalSetup(crl, MONITOR_SETUP_E);
return NULL;
}
#ifdef IN_CLOEXEC
notifyFd = inotify_init1(IN_CLOEXEC);
if (notifyFd < 0 && (errno == ENOSYS || errno == EINVAL)) {
notifyFd = inotify_init();
wc_set_cloexec(notifyFd);
}
#else
notifyFd = inotify_init();
wc_set_cloexec(notifyFd);
#endif
if (notifyFd < 0) {
WOLFSSL_MSG("inotify failed");
(void)close(crl->mfd);
+1 -1
View File
@@ -19601,7 +19601,7 @@ int wolfSSL_RAND_egd(const char* nm)
return WOLFSSL_FATAL_ERROR;
}
fd = socket(AF_UNIX, SOCK_STREAM, 0);
fd = wc_socket_cloexec(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0) {
WOLFSSL_MSG("Error creating socket");
WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+5 -4
View File
@@ -42,6 +42,7 @@
#include <wolfssl/wolfio.h>
#include <wolfssl/wolfcrypt/logging.h>
#ifdef NUCLEUS_PLUS_2_3
/* Holds last Nucleus networking error number */
int Nucleus_Net_Errno;
@@ -1494,7 +1495,7 @@ int wolfIO_TcpConnect(SOCKET_T* sockfd, const char* ip, word16 port, int to_sec)
}
#endif
*sockfd = (SOCKET_T)socket(addr.ss_family, SOCK_STREAM, 0);
*sockfd = (SOCKET_T)wc_socket_cloexec(addr.ss_family, SOCK_STREAM, 0);
#ifdef USE_WINDOWS_API
if (*sockfd == SOCKET_INVALID)
#else
@@ -1572,12 +1573,12 @@ int wolfIO_TcpBind(SOCKET_T* sockfd, word16 port)
sin->sin6_family = AF_INET6;
sin->sin6_addr = in6addr_any;
sin->sin6_port = XHTONS(port);
*sockfd = (SOCKET_T)socket(AF_INET6, SOCK_STREAM, 0);
*sockfd = (SOCKET_T)wc_socket_cloexec(AF_INET6, SOCK_STREAM, 0);
#else
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = INADDR_ANY;
sin->sin_port = XHTONS(port);
*sockfd = (SOCKET_T)socket(AF_INET, SOCK_STREAM, 0);
*sockfd = (SOCKET_T)wc_socket_cloexec(AF_INET, SOCK_STREAM, 0);
#endif
#ifdef USE_WINDOWS_API
@@ -1623,7 +1624,7 @@ int wolfIO_TcpBind(SOCKET_T* sockfd, word16 port)
#ifdef HAVE_SOCKADDR
int wolfIO_TcpAccept(SOCKET_T sockfd, SOCKADDR* peer_addr, XSOCKLENT* peer_len)
{
return (int)accept(sockfd, peer_addr, peer_len);
return wc_accept_cloexec((int)sockfd, peer_addr, peer_len);
}
#endif /* HAVE_SOCKADDR */
+15 -1
View File
@@ -1574,16 +1574,30 @@ static const char* bench_result_words3[][5] = {
#include <linux/perf_event.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#ifndef PERF_FLAG_FD_CLOEXEC
#define PERF_FLAG_FD_CLOEXEC (1UL << 3)
#endif
static THREAD_LS_T word64 begin_cycles;
static THREAD_LS_T word64 total_cycles;
static THREAD_LS_T int cycles = -1;
static THREAD_LS_T struct perf_event_attr atr;
/* Try with PERF_FLAG_FD_CLOEXEC first; on older kernels (< 3.14) this
* fails with EINVAL, so fall back to flags=0 and set FD_CLOEXEC via
* fcntl() as a best-effort. */
#define INIT_CYCLE_COUNTER do { \
atr.type = PERF_TYPE_HARDWARE; \
atr.config = PERF_COUNT_HW_CPU_CYCLES; \
cycles = (int)syscall(__NR_perf_event_open, &atr, 0, -1, -1, 0); \
cycles = (int)syscall(__NR_perf_event_open, &atr, 0, -1, -1, \
PERF_FLAG_FD_CLOEXEC); \
if (cycles < 0 && errno == EINVAL) { \
cycles = (int)syscall(__NR_perf_event_open, &atr, 0, -1, -1, 0); \
wc_set_cloexec(cycles); \
} \
} while (0);
#define BEGIN_CYCLES read(cycles, &begin_cycles, sizeof(begin_cycles));
+8 -2
View File
@@ -19,6 +19,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#if defined(__linux__) && !defined(_GNU_SOURCE)
#define _GNU_SOURCE 1
#endif
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
#if defined(WOLFSSL_AFALG_HASH) || (defined(WOLFSSL_AFALG_XILINX_SHA3) \
@@ -26,6 +30,8 @@
#include <wolfssl/wolfcrypt/port/af_alg/wc_afalg.h>
#include <wolfssl/wolfcrypt/port/af_alg/afalg_hash.h>
#include <errno.h>
#include <fcntl.h>
static const char WC_TYPE_HASH[] = "hash";
@@ -223,8 +229,8 @@ static int AfalgHashCopy(wolfssl_AFALG_Hash* src, wolfssl_AFALG_Hash* dst)
}
#endif
dst->rdFd = accept(src->rdFd, NULL, 0);
dst->alFd = accept(src->alFd, NULL, 0);
dst->rdFd = wc_accept_cloexec(src->rdFd, NULL, NULL);
dst->alFd = wc_accept_cloexec(src->alFd, NULL, NULL);
if (dst->rdFd == WC_SOCK_NOTSET || dst->alFd == WC_SOCK_NOTSET) {
AfalgHashFree(dst);
+11 -2
View File
@@ -19,12 +19,20 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#if defined(__linux__) && !defined(_GNU_SOURCE)
#define _GNU_SOURCE 1
#endif
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX)
#include <wolfssl/wolfcrypt/port/af_alg/wc_afalg.h>
#include <linux/if_alg.h>
#include <sys/socket.h>
#include <errno.h>
#include <fcntl.h>
/* Sets the type of socket address to use */
@@ -56,7 +64,7 @@ int wc_Afalg_Accept(struct sockaddr_alg* in, int inSz, int sock)
return WC_AFALG_SOCK_E;
}
return accept(sock, NULL, 0);
return wc_accept_cloexec(sock, NULL, NULL);
}
@@ -66,7 +74,8 @@ int wc_Afalg_Socket(void)
{
int sock;
if ((sock = socket(AF_ALG, SOCK_SEQPACKET, 0)) < 0) {
sock = wc_socket_cloexec(AF_ALG, SOCK_SEQPACKET, 0);
if (sock < 0) {
WOLFSSL_MSG("Failed to get AF_ALG socket");
return WC_AFALG_SOCK_E;
}
+1 -2
View File
@@ -34,7 +34,6 @@
#include <sys/ioctl.h>
#include <devctl.h>
#include <errno.h>
/* for devctl use */
int caamFd = -1;
@@ -48,7 +47,7 @@ int wc_CAAMInitInterface()
return -1;
}
caamFd = open("/dev/wolfCrypt", O_RDWR);
caamFd = wc_open_cloexec("/dev/wolfCrypt", O_RDWR);
if (caamFd < 0) {
WOLFSSL_MSG("Could not open /dev/wolfCrypt");
return -1;
+3 -1
View File
@@ -26,11 +26,13 @@
static volatile int fd;
#include <wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h>
#include <fcntl.h>
int wc_DevCryptoInit(void)
{
/* create descriptor */
if ((fd = open("/dev/crypto", O_RDWR, 0)) < 0) {
fd = wc_open_cloexec("/dev/crypto", O_RDWR);
if (fd < 0) {
WOLFSSL_MSG("Error opening /dev/crypto is cryptodev module loaded?");
return WC_DEVCRYPTO_E;
}
+3 -1
View File
@@ -57,6 +57,8 @@
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <errno.h>
#ifdef SAL_IOMMU_CODE
#include <icp_sal_iommu.h>
@@ -714,7 +716,7 @@ CpaStatus qaeMemInit(void)
{
if (g_qaeMemFd < 0) {
#ifndef QAT_V2
g_qaeMemFd = open(QAE_MEM, O_RDWR);
g_qaeMemFd = wc_open_cloexec(QAE_MEM, O_RDWR);
if (g_qaeMemFd < 0) {
printf("unable to open %s %d\n", QAE_MEM, g_qaeMemFd);
return CPA_STATUS_FAIL;
+6 -6
View File
@@ -204,8 +204,8 @@ This library contains implementation for the random number generator.
#elif defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD)
#include "wolfssl/wolfcrypt/port/maxim/max3266x.h"
#else
#include <errno.h>
#if defined(WOLFSSL_GETRANDOM) || defined(HAVE_GETRANDOM)
#include <errno.h>
#include <sys/random.h>
#endif
/* include headers that may be needed to get good seed */
@@ -3829,7 +3829,7 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
if (!os->seedFdOpen)
{
#ifndef NO_DEV_URANDOM /* way to disable use of /dev/urandom */
os->fd = open("/dev/urandom", O_RDONLY);
os->fd = wc_open_cloexec("/dev/urandom", O_RDONLY);
#if defined(DEBUG_WOLFSSL)
WOLFSSL_MSG("opened /dev/urandom.");
#endif /* DEBUG_WOLFSSL */
@@ -3837,7 +3837,7 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
#endif /* NO_DEV_URANDOM */
{
/* may still have /dev/random */
os->fd = open("/dev/random", O_RDONLY);
os->fd = wc_open_cloexec("/dev/random", O_RDONLY);
#if defined(DEBUG_WOLFSSL)
WOLFSSL_MSG("opened /dev/random.");
#endif /* DEBUG_WOLFSSL */
@@ -3855,7 +3855,7 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
}
#else /* WOLFSSL_KEEP_RNG_SEED_FD_OPEN */
#ifndef NO_DEV_URANDOM /* way to disable use of /dev/urandom */
os->fd = open("/dev/urandom", O_RDONLY);
os->fd = wc_open_cloexec("/dev/urandom", O_RDONLY);
#if defined(DEBUG_WOLFSSL)
WOLFSSL_MSG("opened /dev/urandom.");
#endif /* DEBUG_WOLFSSL */
@@ -3863,7 +3863,7 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
#endif /* !NO_DEV_URANDOM */
{
/* may still have /dev/random */
os->fd = open("/dev/random", O_RDONLY);
os->fd = wc_open_cloexec("/dev/random", O_RDONLY);
#if defined(DEBUG_WOLFSSL)
WOLFSSL_MSG("opened /dev/random.");
#endif /* DEBUG_WOLFSSL */
@@ -3944,7 +3944,7 @@ int wc_hwrng_generate_block(byte *output, word32 sz)
{
int fd;
int ret = 0;
fd = open("/dev/hwrng", O_RDONLY);
fd = wc_open_cloexec("/dev/hwrng", O_RDONLY);
if (fd == -1)
return OPEN_RAN_E;
while(sz)
+76
View File
@@ -19,6 +19,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#if (defined(__linux__) || defined(__ANDROID__)) && \
!defined(WOLFSSL_LINUXKM) && !defined(WOLFSSL_ZEPHYR) && \
!defined(_GNU_SOURCE)
#define _GNU_SOURCE 1
#endif
/*
wolfCrypt Porting Build Options:
@@ -5130,6 +5136,76 @@ char* wolfSSL_strnstr(const char* s1, const char* s2, unsigned int n)
#endif /* not SINGLE_THREADED */
#if (defined(__unix__) || defined(__APPLE__)) && \
!defined(WOLFSSL_LINUXKM) && !defined(WOLFSSL_ZEPHYR)
#include <fcntl.h>
#include <errno.h>
#include <sys/socket.h>
#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#endif
#ifndef SOCK_CLOEXEC
#define SOCK_CLOEXEC 0
#endif
void wc_set_cloexec(int fd)
{
#ifdef FD_CLOEXEC
int fdFlags;
if (fd < 0)
return;
fdFlags = fcntl(fd, F_GETFD);
if (fdFlags >= 0)
(void)fcntl(fd, F_SETFD, fdFlags | FD_CLOEXEC);
#else
(void)fd;
#endif
}
int wc_open_cloexec(const char* path, int flags)
{
int fd = open(path, flags | O_CLOEXEC);
#ifdef FD_CLOEXEC
if (fd < 0 && errno == EINVAL) {
fd = open(path, flags);
wc_set_cloexec(fd);
}
#endif
return fd;
}
int wc_socket_cloexec(int domain, int type, int protocol)
{
int fd = socket(domain, type | SOCK_CLOEXEC, protocol);
#ifdef FD_CLOEXEC
if (fd < 0 && errno == EINVAL) {
fd = socket(domain, type, protocol);
wc_set_cloexec(fd);
}
#endif
return fd;
}
int wc_accept_cloexec(int sockfd, void* addr, void* addrlen)
{
int fd;
#if defined(__linux__) || defined(__ANDROID__)
fd = accept4(sockfd, (struct sockaddr*)addr, (socklen_t*)addrlen,
SOCK_CLOEXEC);
if (fd >= 0)
return fd;
if (errno != ENOSYS && errno != EINVAL)
return fd;
#endif
fd = accept(sockfd, (struct sockaddr*)addr, (socklen_t*)addrlen);
wc_set_cloexec(fd);
return fd;
}
#endif /* (__unix__ || __APPLE__) && !WOLFSSL_LINUXKM && !WOLFSSL_ZEPHYR */
#if defined(WOLFSSL_LINUXKM) && defined(CONFIG_ARM64) && \
defined(WC_SYM_RELOC_TABLES)
#ifndef CONFIG_ARCH_TEGRA
+18
View File
@@ -1860,6 +1860,24 @@ WOLFSSL_ABI WOLFSSL_API int wolfCrypt_Cleanup(void);
#define WC_GENERATE_SEED_DEFAULT wc_GenerateSeed
#endif
#if (defined(__unix__) || defined(__APPLE__)) && \
!defined(WOLFSSL_LINUXKM) && !defined(WOLFSSL_ZEPHYR)
WOLFSSL_LOCAL void wc_set_cloexec(int fd);
WOLFSSL_LOCAL int wc_open_cloexec(const char* path, int flags);
WOLFSSL_LOCAL int wc_socket_cloexec(int domain, int type, int protocol);
WOLFSSL_LOCAL int wc_accept_cloexec(int sockfd, void* addr, void* addrlen);
#else
/* Platforms without POSIX close-on-exec semantics (Windows, OS/2 OW,
* Linux kernel module, Zephyr, etc.): pass through to plain syscalls
* where the underlying headers are available in the caller. */
#define wc_set_cloexec(fd) ((void)(fd))
#define wc_open_cloexec(path, flags) open((path), (flags))
#define wc_socket_cloexec(domain, type, protocol) \
socket((domain), (type), (protocol))
#define wc_accept_cloexec(sockfd, addr, addrlen) \
accept((sockfd), (addr), (addrlen))
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif