mirror of https://github.com/wolfSSL/wolfssl.git
tests: drive the infra cryptocb devId, memory bucket and wc_port errno guards
parent
860210a330
commit
7bbd6e2f39
|
|
@ -95,8 +95,52 @@
|
|||
* The SHA-384/SHA-512 post-cb guards additionally need dev->cb to return 0
|
||||
* (success) for the fallback attempt specifically - see wb_cb_hash_fallback_ok
|
||||
* below for how that is done without needing to inject a fault mid-dispatch.
|
||||
*
|
||||
* Third pass - the "no devId argument" guard at cryptocb.c :1159 / :1189,
|
||||
* `if (dev == NULL || dev->cb == NULL) dev = wc_CryptoCb_FindDeviceByIndex(0);`
|
||||
* in wc_CryptoCb_Curve25519MakePub() and wc_CryptoCb_Curve25519Generic().
|
||||
* These two functions take no key struct, so they resolve their device with
|
||||
* wc_CryptoCb_FindDevice(INVALID_DEVID, WC_ALGO_TYPE_PK) and the guard is
|
||||
* driven purely by the state of the gCryptoDev[] table:
|
||||
* - (F,T) at least one free slot exists. wc_CryptoCb_ClearDev() leaves
|
||||
* free slots at devId == INVALID_DEVID with cb == NULL, so
|
||||
* wc_CryptoCb_GetDevice(INVALID_DEVID) returns that slot:
|
||||
* dev != NULL but dev->cb == NULL.
|
||||
* - (T,-) every one of MAX_CRYPTO_DEVID_CALLBACKS slots is registered, so
|
||||
* no slot holds INVALID_DEVID and wc_CryptoCb_GetDevice() returns
|
||||
* NULL. This is reachable with the public registration API alone.
|
||||
* - (F,F) needs a lookup that yields a device with a non-NULL callback.
|
||||
* wc_CryptoCb_RegisterDevice() explicitly refuses devId ==
|
||||
* INVALID_DEVID ("INVALID_DEVID marks a free slot"), so no free
|
||||
* slot can ever carry a callback and the plain lookup cannot
|
||||
* produce this state. The supported mechanism that can is
|
||||
* WOLF_CRYPTO_CB_FIND: wc_CryptoCb_FindDevice() first passes the
|
||||
* requested devId through the registered find callback, so a find
|
||||
* callback that maps INVALID_DEVID onto a real registered devId
|
||||
* makes the lookup return a device WITH a callback. Neither infra
|
||||
* variant's user_settings defines WOLF_CRYPTO_CB_FIND, so this
|
||||
* file compiles it in for its own translation unit, exactly the
|
||||
* way test_memory_whitebox.c compiles WOLFSSL_STATIC_MEMORY in for
|
||||
* memory.c. It costs nothing in denominator: the only code the
|
||||
* macro adds to cryptocb.c is a file-static pointer, the setter
|
||||
* wc_CryptoCb_SetDeviceFindCb(), and a SINGLE-condition
|
||||
* `if (CryptoCb_FindCb != NULL)` inside wc_CryptoCb_FindDevice()
|
||||
* (single-condition decisions carry no MC/DC conditions), and it
|
||||
* changes no struct layout shared with the linked archive.
|
||||
* The find callback is installed only around the (F,F) vectors and
|
||||
* reset to NULL immediately afterwards, so every other decision in
|
||||
* this file is evaluated with CryptoCb_FindCb == NULL, i.e. with
|
||||
* wc_CryptoCb_FindDevice() behaving exactly as in the shipped
|
||||
* variants.
|
||||
*/
|
||||
|
||||
/* See the "third pass" note above: compiled in for this TU only, so the
|
||||
* :1159/:1189 (F,F) vector can be driven through the public
|
||||
* wc_CryptoCb_SetDeviceFindCb() API. Must precede the #include below. */
|
||||
#ifndef WOLF_CRYPTO_CB_FIND
|
||||
#define WOLF_CRYPTO_CB_FIND
|
||||
#endif
|
||||
|
||||
#include <wolfcrypt/src/cryptocb.c>
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -112,6 +156,11 @@ static int wb_fail = 0;
|
|||
#define WB_DEVID_NOCB 2
|
||||
#define WB_DEVID_NONE 424242
|
||||
|
||||
/* Base devId for the MAX_CRYPTO_DEVID_CALLBACKS "fill the whole table"
|
||||
* registrations used by the :1159/:1189 (T,-) vector. Distinct from every
|
||||
* other devId in this file and never equal to INVALID_DEVID. */
|
||||
#define WB_DEVID_FILL 500
|
||||
|
||||
static int wb_cb(int devId, wc_CryptoInfo* info, void* ctx)
|
||||
{
|
||||
(void)devId;
|
||||
|
|
@ -144,6 +193,20 @@ static int wb_cb_hash_fallback_ok(int devId, wc_CryptoInfo* info, void* ctx)
|
|||
return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
|
||||
}
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB_FIND
|
||||
/* Find callback used ONLY by the :1159/:1189 (F,F) vectors. It rewrites the
|
||||
* INVALID_DEVID lookup that wc_CryptoCb_Curve25519MakePub/Generic issue into
|
||||
* WB_DEVID, which is registered with wb_cb, so wc_CryptoCb_FindDevice()
|
||||
* returns a device whose ->cb is non-NULL. Installed and removed around
|
||||
* those two calls only. */
|
||||
static int wb_find_cb(int devId, int algoType)
|
||||
{
|
||||
(void)devId;
|
||||
(void)algoType;
|
||||
return WB_DEVID;
|
||||
}
|
||||
#endif /* WOLF_CRYPTO_CB_FIND */
|
||||
|
||||
/* WB_DRIVE3(lvalue, call): sets `lvalue` (a struct field or plain local
|
||||
* devId variable) to each of the three vectors and issues `call` once per
|
||||
* vector. One invocation completes the `dev && dev->cb` MC/DC independence
|
||||
|
|
@ -985,6 +1048,83 @@ int main(void)
|
|||
WB_NOTE("HAVE_CURVE25519 not defined; Curve25519MakePub/Generic skipped");
|
||||
#endif
|
||||
|
||||
/* ---- Curve25519MakePub/Generic: `dev == NULL || dev->cb == NULL`
|
||||
* (cryptocb.c :1159 and :1189) ----
|
||||
* Three vectors, all in this binary; see the "third pass" note in the
|
||||
* file header for why each table state produces the operand values it
|
||||
* does. Each vector rebuilds the table from wc_CryptoCb_Init() so the
|
||||
* preceding section's leftovers cannot influence it. Nothing here can
|
||||
* touch the key buffers: whichever device the guard ends up selecting,
|
||||
* its callback is wb_cb, which returns CRYPTOCB_UNAVAILABLE without
|
||||
* reading the wc_CryptoInfo it is handed. */
|
||||
#ifdef HAVE_CURVE25519
|
||||
{
|
||||
byte g25pub[CURVE25519_KEYSIZE];
|
||||
byte g25priv[CURVE25519_KEYSIZE];
|
||||
byte g25base[CURVE25519_KEYSIZE];
|
||||
int slot;
|
||||
|
||||
XMEMSET(g25pub, 0, sizeof(g25pub));
|
||||
XMEMSET(g25priv, 1, sizeof(g25priv));
|
||||
XMEMSET(g25base, 9, sizeof(g25base));
|
||||
|
||||
/* (F,T): one device registered, so free slots remain. The
|
||||
* INVALID_DEVID lookup lands on the first free slot: non-NULL, cb
|
||||
* NULL. Guard TRUE, so FindDeviceByIndex(0) supplies the device. */
|
||||
wc_CryptoCb_Init();
|
||||
if (wc_CryptoCb_RegisterDevice(WB_DEVID, wb_cb, NULL) != 0)
|
||||
wb_fail = 1;
|
||||
(void)wc_CryptoCb_Curve25519MakePub(sizeof(g25pub), g25pub,
|
||||
sizeof(g25priv), g25priv);
|
||||
(void)wc_CryptoCb_Curve25519Generic(sizeof(g25pub), g25pub,
|
||||
sizeof(g25priv), g25priv, sizeof(g25base), g25base);
|
||||
|
||||
/* (T,-): every slot registered, so no slot holds INVALID_DEVID and
|
||||
* wc_CryptoCb_GetDevice(INVALID_DEVID) returns NULL. dev == NULL is
|
||||
* TRUE and short-circuits the OR - the independence pair for the
|
||||
* first operand against the (F,T) vector above. */
|
||||
wc_CryptoCb_Init();
|
||||
for (slot = 0; slot < MAX_CRYPTO_DEVID_CALLBACKS; slot++) {
|
||||
if (wc_CryptoCb_RegisterDevice(WB_DEVID_FILL + slot, wb_cb,
|
||||
NULL) != 0)
|
||||
wb_fail = 1;
|
||||
}
|
||||
(void)wc_CryptoCb_Curve25519MakePub(sizeof(g25pub), g25pub,
|
||||
sizeof(g25priv), g25priv);
|
||||
(void)wc_CryptoCb_Curve25519Generic(sizeof(g25pub), g25pub,
|
||||
sizeof(g25priv), g25priv, sizeof(g25base), g25base);
|
||||
|
||||
/* (F,F): the find callback rewrites the INVALID_DEVID lookup into
|
||||
* WB_DEVID, which is registered with wb_cb, so the lookup returns a
|
||||
* device WITH a callback - the independence pair for the second
|
||||
* operand against the (F,T) vector above. */
|
||||
#ifdef WOLF_CRYPTO_CB_FIND
|
||||
wc_CryptoCb_Init();
|
||||
if (wc_CryptoCb_RegisterDevice(WB_DEVID, wb_cb, NULL) != 0)
|
||||
wb_fail = 1;
|
||||
wc_CryptoCb_SetDeviceFindCb(wb_find_cb);
|
||||
(void)wc_CryptoCb_Curve25519MakePub(sizeof(g25pub), g25pub,
|
||||
sizeof(g25priv), g25priv);
|
||||
(void)wc_CryptoCb_Curve25519Generic(sizeof(g25pub), g25pub,
|
||||
sizeof(g25priv), g25priv, sizeof(g25base), g25base);
|
||||
wc_CryptoCb_SetDeviceFindCb(NULL);
|
||||
WB_NOTE("Curve25519MakePub/Generic: dev==NULL||dev->cb==NULL "
|
||||
"[:1159,:1189] driven (F,T) / (T,-) / (F,F)");
|
||||
#else
|
||||
WB_NOTE("Curve25519MakePub/Generic: dev==NULL||dev->cb==NULL "
|
||||
"[:1159,:1189] driven (F,T) / (T,-); (F,F) needs "
|
||||
"WOLF_CRYPTO_CB_FIND, not compiled here");
|
||||
#endif
|
||||
|
||||
/* Leave the table the way the rest of this file expects it. */
|
||||
wc_CryptoCb_Init();
|
||||
if (wc_CryptoCb_RegisterDevice(WB_DEVID, wb_cb, NULL) != 0)
|
||||
wb_fail = 1;
|
||||
}
|
||||
#else
|
||||
WB_NOTE("HAVE_CURVE25519 not defined; :1159/:1189 vectors skipped");
|
||||
#endif
|
||||
|
||||
wc_CryptoCb_UnRegisterDevice(WB_DEVID);
|
||||
wc_CryptoCb_UnRegisterDevice(WB_DEVID_NOCB);
|
||||
wc_CryptoCb_UnRegisterDevice(WB_DEVID_HASH_OK);
|
||||
|
|
@ -992,6 +1132,11 @@ int main(void)
|
|||
(void)res;
|
||||
(void)intSize;
|
||||
(void)devId;
|
||||
#ifdef WOLF_CRYPTO_CB_FIND
|
||||
/* Keep wb_find_cb referenced even in a variant without HAVE_CURVE25519,
|
||||
* where the only call site above is preprocessed away. */
|
||||
(void)wb_find_cb;
|
||||
#endif
|
||||
|
||||
printf("done (%s)\n", wb_fail ? "with skips" : "ok");
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -83,8 +83,9 @@
|
|||
* :844 wolfSSL_StaticBufferSz_ex() same alignment pattern as :621.
|
||||
* :851 wolfSSL_StaticBufferSz_ex() same IO_POOL/IO_POOL_FIXED OR as :635.
|
||||
* :867 wolfSSL_StaticBufferSz_ex() `(ava >= sizeList[0]+padSz+memSz) &&
|
||||
* (ava > 0)` -- see RESIDUAL note below; only the first operand's
|
||||
* independence is satisfiable.
|
||||
* (ava > 0)` -- both operands' independence pairs driven; see the
|
||||
* comment above the third vector in Section 4a for why the second
|
||||
* operand needs a sizeList[0] that wraps the word32 sum to zero.
|
||||
* :1013 wolfSSL_Malloc() `heap==NULL && globalHeapHint==NULL`.
|
||||
* :1068 wolfSSL_Malloc() `mem->flag & WOLFMEM_IO_POOL_FIXED &&
|
||||
* (type==DYNAMIC_TYPE_OUT_BUFFER || type==DYNAMIC_TYPE_IN_BUFFER)`.
|
||||
|
|
@ -101,13 +102,6 @@
|
|||
*
|
||||
* RESIDUALS (structurally dead operand, provably unsatisfiable -- not a gap
|
||||
* in this test, a property of the source):
|
||||
* - :867 `ava > 0`: every bucket size in sizeList[] is a positive value
|
||||
* (callers only ever pass positive bucket sizes), so
|
||||
* `ava >= sizeList[0]+padSz+memSz` being true always implies `ava > 0`
|
||||
* (padSz+memSz >= 0, sizeList[0] > 0). The pair that would show `ava>0`
|
||||
* independently (first operand true, second false) requires
|
||||
* `sizeList[0]+padSz+memSz <= 0`, which cannot happen. Only the first
|
||||
* operand's independence pair is driven here.
|
||||
* - :1414 `res == NULL`: this check is reached solely via the `else`
|
||||
* branch of the IO-pool `if` immediately above it (memory.c ~:1387-1400
|
||||
* in this same function). Every route into that `else` branch leaves
|
||||
|
|
@ -353,11 +347,10 @@ int main(void)
|
|||
WOLFMEM_IO_POOL_FIXED);
|
||||
WB_CHECK(sz >= 0, "IO-flag OR: second true (WOLFMEM_IO_POOL_FIXED)");
|
||||
|
||||
/* :867 `ava >= sizeList[0]+padSz+memSz && ava > 0` -- only the
|
||||
* first operand's independence is satisfiable (see RESIDUAL note
|
||||
* in the header comment): "true" vector (loop iterates, ample
|
||||
* buffer) and "false" vector (buffer smaller than one bucket). */
|
||||
WB_NOTE("wolfSSL_StaticBufferSz_ex(): ava-loop [:867] (residual: ava>0 dead, see header)");
|
||||
/* :867 `ava >= sizeList[0]+padSz+memSz && ava > 0`.
|
||||
* First operand: "true" vector (loop iterates, ample buffer) and
|
||||
* "false" vector (buffer smaller than one bucket). */
|
||||
WB_NOTE("wolfSSL_StaticBufferSz_ex(): ava-loop [:867]");
|
||||
sz = wolfSSL_StaticBufferSz_ex(3, s_sizeList, s_distList, aligned,
|
||||
(word32)(sizeof(s_scratch) - (aligned - s_scratch)),
|
||||
WOLFMEM_GENERAL);
|
||||
|
|
@ -366,6 +359,43 @@ int main(void)
|
|||
sz = wolfSSL_StaticBufferSz_ex(3, s_sizeList, s_distList, aligned,
|
||||
4 /* smaller than sizeList[0]=64 + overhead */, WOLFMEM_GENERAL);
|
||||
WB_CHECK(sz == 0, "ava-loop first-operand false vector (buffer too small)");
|
||||
|
||||
/* Second operand (`ava > 0`) FALSE half, i.e. first operand TRUE and
|
||||
* second FALSE. That needs `sizeList[0] + padSz + memSz` to be 0:
|
||||
* `ava` is word32 and the sum is computed in word32 (sizeList[0],
|
||||
* padSz and memSz are all word32 == unsigned int here, so the usual
|
||||
* arithmetic conversions keep the whole sum unsigned 32-bit), and for
|
||||
* any strictly positive sum `ava >= sum` already implies `ava > 0`.
|
||||
* The sum is only zero when it wraps, which is well defined for
|
||||
* unsigned arithmetic and is reachable because sizeList[] is a caller
|
||||
* -supplied argument of the public wolfSSL_StaticBufferSz_ex() API.
|
||||
* With sum == 0 and sz == 0:
|
||||
* - the alignment while-loop at :844 cannot run (pt == buffer + sz
|
||||
* immediately), so ava stays 0 and no byte of the buffer is read
|
||||
* or written;
|
||||
* - the :863 "not enough room for even one bucket" pre-check is
|
||||
* `0 < 0`, false, so control reaches :867;
|
||||
* - :867 evaluates `0 >= 0` (TRUE) && `0 > 0` (FALSE) and the loop
|
||||
* body never executes, so distList[]/sizeList[] are never indexed
|
||||
* and the wrapped bucket size is never used for anything.
|
||||
* The function returns sz - ava == 0. */
|
||||
{
|
||||
word32 wrapMemSz;
|
||||
word32 wrapPadSz;
|
||||
word32 wrapList[3];
|
||||
|
||||
wrapMemSz = (word32)sizeof(wc_Memory);
|
||||
wrapPadSz = (word32)(-(int)wrapMemSz & (WOLFSSL_STATIC_ALIGN - 1));
|
||||
wrapList[0] = (word32)(0U - (wrapPadSz + wrapMemSz));
|
||||
wrapList[1] = 128;
|
||||
wrapList[2] = 256;
|
||||
|
||||
sz = wolfSSL_StaticBufferSz_ex(3, wrapList, s_distList,
|
||||
s_bufGeneral, 0, WOLFMEM_GENERAL);
|
||||
WB_CHECK(sz == 0,
|
||||
"ava-loop second-operand false vector (sizeList[0] chosen "
|
||||
"so sizeList[0]+padSz+memSz wraps to 0, sz==0)");
|
||||
}
|
||||
}
|
||||
|
||||
/* ==================================================================
|
||||
|
|
|
|||
|
|
@ -25,8 +25,70 @@
|
|||
* tests/api "port" group cannot reach it. Its loop guard
|
||||
* "n >= s2_len && s1[0]" needs both operands driven false independently,
|
||||
* which needs a haystack shorter than the needle and an empty haystack.
|
||||
*
|
||||
* This file also interposes accept4() for wc_accept_cloexec(), see the
|
||||
* block immediately below and the note above wb_cloexec_wrappers().
|
||||
*/
|
||||
|
||||
/* ---- accept4() macro interposition -------------------------------------- *
|
||||
*
|
||||
* wc_accept_cloexec()'s guard `if (errno != ENOSYS && errno != EINVAL)`
|
||||
* (wc_port.c ~:5684) can only see errno == ENOSYS on a kernel that does not
|
||||
* implement accept4(). Every host this campaign runs on does, so the first
|
||||
* operand has no reachable independence pair from the outside.
|
||||
*
|
||||
* The white-box TU #includes wc_port.c directly, so accept4() can be
|
||||
* replaced at PREPROCESSING time for this translation unit only - the same
|
||||
* technique mcdc_fault_hash.h uses for the hash primitives. Ordering is
|
||||
* load-bearing and mirrors that header exactly:
|
||||
* 1. define _GNU_SOURCE before the first libc header, exactly as
|
||||
* wc_port.c does at its own top. Without it glibc does not declare
|
||||
* accept4(), __USE_GNU is never set, and wc_port.c's
|
||||
* `#if defined(__USE_GNU) && ...` block - the block that CONTAINS the
|
||||
* target guard - would compile out of this TU entirely;
|
||||
* 2. include <sys/socket.h> so the REAL accept4() declaration is in scope
|
||||
* and is never rewritten by the macro;
|
||||
* 3. define the wrapper, which is compiled BEFORE the macro exists and so
|
||||
* still calls the real accept4() when disarmed;
|
||||
* 4. only then #define accept4 to the wrapper, and include wc_port.c.
|
||||
* wc_port.c's own `#include <sys/socket.h>` becomes a no-op (include guard)
|
||||
* and its own `#define _GNU_SOURCE 1` is skipped by its `!defined(_GNU_SOURCE)`
|
||||
* test, so the preprocessor state wc_port.c sees is identical to a normal
|
||||
* build. accept4 appears exactly once in wc_port.c (in wc_accept_cloexec),
|
||||
* so nothing else in the file is affected.
|
||||
* ------------------------------------------------------------------------ */
|
||||
#if (defined(__linux__) || defined(__ANDROID__)) && \
|
||||
!defined(WOLFSSL_LINUXKM) && !defined(WOLFSSL_ZEPHYR) && \
|
||||
!defined(_GNU_SOURCE)
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#if (defined(__unix__) || defined(__APPLE__)) && \
|
||||
!defined(WOLFSSL_LINUXKM) && !defined(WOLFSSL_KERNEL_MODE) && \
|
||||
!defined(WOLFSSL_ZEPHYR) && !defined(WOLFSSL_SGX)
|
||||
#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#if defined(__USE_GNU) && (defined(__linux__) || defined(__ANDROID__))
|
||||
#define WB_HAVE_ACCEPT4_HOOK
|
||||
|
||||
/* 0 = pass through to the real accept4(); otherwise fail with this errno. */
|
||||
static int wb_accept4_errno = 0;
|
||||
|
||||
static int wb_accept4(int sockfd, struct sockaddr* addr, socklen_t* addrlen,
|
||||
int flags)
|
||||
{
|
||||
if (wb_accept4_errno != 0) {
|
||||
errno = wb_accept4_errno;
|
||||
return -1;
|
||||
}
|
||||
return accept4(sockfd, addr, addrlen, flags);
|
||||
}
|
||||
|
||||
#define accept4 wb_accept4
|
||||
#endif /* __USE_GNU && (__linux__ || __ANDROID__) */
|
||||
|
||||
#include <wolfcrypt/src/wc_port.c>
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -102,6 +164,7 @@ static void wb_strnstr(void) { WB_NOTE("wolfSSL_strnstr not compiled; skipped");
|
|||
* socket(AF_INET, SOCK_STREAM, 0) -> succeeds (F,-)
|
||||
* accept on a NON-listening socket -> EINVAL (T,F) at 5684
|
||||
* accept on a bad descriptor -> EBADF (T,T) at 5684
|
||||
* accept4() interposed to fail with ENOSYS -> (F,-) at 5684
|
||||
*
|
||||
* Every failing call returns a negative fd that the wrapper only ever passes
|
||||
* to wc_set_cloexec(), which returns immediately for fd < 0; the two
|
||||
|
|
@ -109,9 +172,15 @@ static void wb_strnstr(void) { WB_NOTE("wolfSSL_strnstr not compiled; skipped");
|
|||
* no socket is ever connected or bound, so nothing outside this process is
|
||||
* touched.
|
||||
*
|
||||
* 5684's idx0 ("errno != ENOSYS") stays a justified residual: making accept4()
|
||||
* report ENOSYS needs a kernel without the syscall, which no build variant of
|
||||
* this campaign runs on, so that operand has no reachable independence pair.
|
||||
* 5684's idx0 ("errno != ENOSYS") is the one operand no argument choice can
|
||||
* reach, because it needs a kernel that does not implement accept4(). It is
|
||||
* driven instead by the macro interposition set up at the top of this file:
|
||||
* the wrapper reports ENOSYS for exactly one call, which short-circuits the
|
||||
* AND and drops wc_accept_cloexec() into its plain accept() fallback. That
|
||||
* fallback is issued on fd -1, so accept() returns -1/EBADF and
|
||||
* wc_set_cloexec(-1) returns immediately - no descriptor is produced and
|
||||
* nothing blocks. The hook is disarmed again on the next line, so every other
|
||||
* call in this file reaches the real accept4().
|
||||
* ------------------------------------------------------------------------ */
|
||||
#if (defined(__unix__) || defined(__APPLE__)) && \
|
||||
!defined(WOLFSSL_KERNEL_MODE) && !defined(WOLFSSL_ZEPHYR) && \
|
||||
|
|
@ -194,6 +263,25 @@ static void wb_cloexec_wrappers(void)
|
|||
WB_NOTE("accept on fd -1 unexpectedly succeeded");
|
||||
}
|
||||
|
||||
/* --- 5684 idx0 FALSE: accept4() reports ENOSYS, so `errno != ENOSYS` is
|
||||
* false and the AND short-circuits into the accept() fallback below it.
|
||||
* Paired in this same binary with the EBADF vector immediately above,
|
||||
* which has idx0 TRUE and the same outcome flip. --- */
|
||||
#ifdef WB_HAVE_ACCEPT4_HOOK
|
||||
errno = 0;
|
||||
wb_accept4_errno = ENOSYS;
|
||||
fd = wc_accept_cloexec(-1, NULL, NULL);
|
||||
wb_accept4_errno = 0;
|
||||
if (fd >= 0) {
|
||||
close(fd);
|
||||
WB_NOTE("accept() fallback on fd -1 unexpectedly succeeded");
|
||||
}
|
||||
WB_NOTE("accept4 ENOSYS interposition drove 5684 idx0 false");
|
||||
#else
|
||||
WB_NOTE("accept4() not compiled in this TU; 5684 idx0 false vector "
|
||||
"skipped");
|
||||
#endif
|
||||
|
||||
WB_NOTE("cloexec open/socket/accept fallback guard pairs done");
|
||||
}
|
||||
#else
|
||||
|
|
|
|||
Loading…
Reference in New Issue