Merge pull request #6447 from SparkiDev/tests_api_expect

Tests api.c: rework for malloc failure testing
This commit is contained in:
JacobBarthelmeh
2023-05-30 09:19:54 -06:00
committed by GitHub
14 changed files with 3888 additions and 3252 deletions

View File

@ -2481,6 +2481,23 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio)
bio->shutdown = BIO_CLOSE; /* default to close things */
bio->num = WOLFSSL_BIO_ERROR;
bio->init = 1;
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
{
int ret;
wolfSSL_RefInit(&bio->ref, &ret);
#ifdef WOLFSSL_REFCNT_ERROR_RETURN
if (ret != 0) {
wolfSSL_BIO_free(bio);
WOLFSSL_MSG("wc_InitMutex failed for WOLFSSL_BIO");
return NULL;
}
#else
(void)ret;
#endif
}
#endif
if (method->type == WOLFSSL_BIO_MEMORY)
bio->eof = WOLFSSL_BIO_ERROR; /* Return value for empty buffer */
if (method->type == WOLFSSL_BIO_MEMORY ||
@ -2507,22 +2524,6 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio)
method->createCb(bio);
}
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
{
int ret;
wolfSSL_RefInit(&bio->ref, &ret);
#ifdef WOLFSSL_REFCNT_ERROR_RETURN
if (ret != 0) {
wolfSSL_BIO_free(bio);
WOLFSSL_MSG("wc_InitMutex failed for WOLFSSL_BIO");
return NULL;
}
#else
(void)ret;
#endif
}
#endif
}
return bio;
}

View File

@ -913,6 +913,7 @@ static int ImportCipherSpecState(WOLFSSL* ssl, const byte* exp, word32 len,
word32 tmp_seq_peer_hi;
word32 tmp_seq_lo;
word32 tmp_seq_hi;
int ret;
WOLFSSL_ENTER("ImportCipherSpecState");
@ -951,7 +952,9 @@ static int ImportCipherSpecState(WOLFSSL* ssl, const byte* exp, word32 len,
tmp_seq_lo = ssl->keys.sequence_number_lo;
tmp_seq_hi = ssl->keys.sequence_number_hi;
SetKeysSide(ssl, ENCRYPT_AND_DECRYPT_SIDE);
if ((ret = SetKeysSide(ssl, ENCRYPT_AND_DECRYPT_SIDE)) < 0) {
return ret;
}
/* reset sequence numbers after setting keys */
ssl->keys.peer_sequence_number_lo = tmp_seq_peer_lo;

View File

@ -938,8 +938,10 @@ WOLFSSL_OCSP_BASICRESP* wolfSSL_OCSP_response_get1_basic(OcspResponse* response)
DYNAMIC_TYPE_OCSP_ENTRY);
bs->source = (byte*)XMALLOC(bs->maxIdx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (bs->single == NULL || bs->source == NULL) {
if (bs->single) XFREE(bs->single, NULL, DYNAMIC_TYPE_OCSP_ENTRY);
if (bs->source) XFREE(bs->source, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (bs->single) {
XFREE(bs->single, NULL, DYNAMIC_TYPE_OCSP_ENTRY);
bs->single = NULL;
}
wolfSSL_OCSP_RESPONSE_free(bs);
bs = NULL;
}

View File

@ -7365,7 +7365,7 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
#ifdef HAVE_PKCS8
/* if private key try and remove PKCS8 header */
if (type == PRIVATEKEY_TYPE) {
if (ret == 0 && type == PRIVATEKEY_TYPE) {
if ((ret = ToTraditional_ex(der->buffer, der->length,
&algId)) > 0) {
/* Found PKCS8 header */
@ -8013,7 +8013,10 @@ static int ProcessChainBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
ret = ProcessBuffer(ctx, buff + used, sz - used, format, type, ssl,
&consumed, 0, verify);
if (ret < 0) {
if (ret == MEMORY_E) {
return ret;
}
else if (ret < 0) {
#if defined(WOLFSSL_WPAS) && defined(HAVE_CRL)
DerBuffer* der = NULL;
EncryptedInfo info;
@ -38466,7 +38469,7 @@ int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
}
if (certData != NULL) {
XFREE(*cert, heap, DYNAMIC_TYPE_PKCS); *cert = NULL;
XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
}
/* Free up WC_DerCertList and move on */
while (current != NULL) {
@ -38580,6 +38583,7 @@ int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
}
wolfSSL_X509_free(*cert); *cert = NULL;
XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
ret = WOLFSSL_FAILURE;
goto out;
}

View File

@ -623,7 +623,7 @@ static int wolfssl_asn1_integer_require_len(WOLFSSL_ASN1_INTEGER* a, int len,
if ((!a->isDynamic) && (len > (int)a->dataMax)) {
/* Create a new buffer to hold large integer value. */
data = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL);
if (a->data == NULL) {
if (data == NULL) {
ret = 0;
}
else {

View File

@ -9007,9 +9007,6 @@ int wolfSSL_X509_ALGOR_set0(WOLFSSL_X509_ALGOR *algor, WOLFSSL_ASN1_OBJECT *aobj
if (!algor) {
return WOLFSSL_FAILURE;
}
if (aobj) {
algor->algorithm = aobj;
}
if (!algor->parameter) {
algor->parameter = wolfSSL_ASN1_TYPE_new();
@ -9018,6 +9015,9 @@ int wolfSSL_X509_ALGOR_set0(WOLFSSL_X509_ALGOR *algor, WOLFSSL_ASN1_OBJECT *aobj
}
}
if (aobj) {
algor->algorithm = aobj;
}
wolfSSL_ASN1_TYPE_set(algor->parameter, ptype, pval);
return WOLFSSL_SUCCESS;
@ -9991,8 +9991,8 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_chain_up_ref(
{
ret = wc_InitRng(&rng);
if (ret != 0) {
XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
return WOLFSSL_FAILURE;
ret = WOLFSSL_FAILURE;
goto cleanup;
}
ret = wc_MakeCert_ex(cert, der, *derSz, type, key, &rng);

File diff suppressed because it is too large Load Diff

View File

@ -34,6 +34,7 @@
int allTesting = 1;
int apiTesting = 1;
int myoptind = 0;
char* myoptarg = NULL;
int unit_test(int argc, char** argv);
@ -185,21 +186,26 @@ int unit_test(int argc, char** argv)
goto exit;
}
else if (XSTRCMP(argv[1], "--api") == 0) {
allTesting = 0;
}
else if (XSTRCMP(argv[1], "--no-api") == 0) {
apiTesting = 0;
}
else if (argv[1][1] >= '0' && argv[1][1] <= '9') {
ret = ApiTest_RunIdx(atoi(argv[1] + 1));
if (ret != 0) {
goto exit;
}
allTesting = 0;
}
else {
ret = ApiTest_RunName(argv[1] + 1);
if (ret != 0) {
goto exit;
}
allTesting = 0;
}
allTesting = 0;
argc--;
argv++;
}
@ -208,7 +214,11 @@ int unit_test(int argc, char** argv)
if (argc == 1)
#endif
{
ApiTest();
if (apiTesting) {
ret = ApiTest();
if (ret != 0)
goto exit;
}
if (!allTesting) {
goto exit;

View File

@ -122,10 +122,111 @@
#define AssertPtrLE(x, y) AssertPtr(x, y, <=, >)
#define EXPECT_DECLS \
int _ret = 0
#define EXPECT_RESULT() \
((_ret == 0) ? TEST_SUCCESS : TEST_FAIL)
#define EXPECT_SUCCESS() \
(_ret == 0)
#define EXPECT_FAIL() \
(_ret != 0)
#define ExpFail(description, result) do { \
printf("\nERROR - %s line %d failed with:", __FILE__, __LINE__); \
fputs("\n expected: ", stdout); printf description; \
fputs("\n result: ", stdout); printf result; fputs("\n\n", stdout); \
fflush(stdout); \
_ret = -1; \
} while (0)
#define Expect(test, description, result) \
if ((_ret == 0) && (!(test))) ExpFail(description, result)
#define ExpectTrue(x) Expect( (x), ("%s is true", #x), (#x " => FALSE"))
#define ExpectFalse(x) Expect(!(x), ("%s is false", #x), (#x " => TRUE"))
#define ExpectNotNull(x) Expect( (x), ("%s is not null", #x), (#x " => NULL"))
#define ExpectNull(x) do { \
if (_ret == 0) { \
PEDANTIC_EXTENSION void* _x = (void*)(x); \
Expect(!_x, ("%s is null", #x), (#x " => %p", _x)); \
} \
} while(0)
#define ExpectInt(x, y, op, er) do { \
if (_ret == 0) { \
int _x = (int)(x); \
int _y = (int)(y); \
Expect(_x op _y, ("%s " #op " %s", #x, #y), ("%d " #er " %d", _x, _y));\
} \
} while(0)
#define ExpectIntEQ(x, y) ExpectInt(x, y, ==, !=)
#define ExpectIntNE(x, y) ExpectInt(x, y, !=, ==)
#define ExpectIntGT(x, y) ExpectInt(x, y, >, <=)
#define ExpectIntLT(x, y) ExpectInt(x, y, <, >=)
#define ExpectIntGE(x, y) ExpectInt(x, y, >=, <)
#define ExpectIntLE(x, y) ExpectInt(x, y, <=, >)
#define ExpectStr(x, y, op, er) do { \
if (_ret == 0) { \
const char* _x = (const char*)(x); \
const char* _y = (const char*)(y); \
int _z = (_x && _y) ? strcmp(_x, _y) : -1; \
Expect(_z op 0, ("%s " #op " %s", #x, #y), \
("\"%s\" " #er " \"%s\"", _x, _y));\
} \
} while(0)
#define ExpectStrEQ(x, y) ExpectStr(x, y, ==, !=)
#define ExpectStrNE(x, y) ExpectStr(x, y, !=, ==)
#define ExpectStrGT(x, y) ExpectStr(x, y, >, <=)
#define ExpectStrLT(x, y) ExpectStr(x, y, <, >=)
#define ExpectStrGE(x, y) ExpectStr(x, y, >=, <)
#define ExpectStrLE(x, y) ExpectStr(x, y, <=, >)
#define ExpectPtr(x, y, op, er) do { \
if (_ret == 0) { \
PRAGMA_GCC_DIAG_PUSH; \
/* remarkably, without this inhibition, */ \
/* the _Pragma()s make the declarations warn. */ \
PRAGMA_GCC("GCC diagnostic ignored \"-Wdeclaration-after-statement\"");\
/* inhibit "ISO C forbids conversion of function pointer */ \
/* to object pointer type [-Werror=pedantic]" */ \
PRAGMA_GCC("GCC diagnostic ignored \"-Wpedantic\""); \
void* _x = (void*)(x); \
void* _y = (void*)(y); \
Expect(_x op _y, ("%s " #op " %s", #x, #y), ("%p " #er " %p", _x, _y));\
PRAGMA_GCC_DIAG_POP; \
} \
} while(0)
#define ExpectPtrEq(x, y) ExpectPtr(x, y, ==, !=)
#define ExpectPtrNE(x, y) ExpectPtr(x, y, !=, ==)
#define ExpectPtrGT(x, y) ExpectPtr(x, y, >, <=)
#define ExpectPtrLT(x, y) ExpectPtr(x, y, <, >=)
#define ExpectPtrGE(x, y) ExpectPtr(x, y, >=, <)
#define ExpectPtrLE(x, y) ExpectPtr(x, y, <=, >)
#define ExpectBuf(x, y, z, op, er) do { \
if (_ret == 0) { \
const byte* _x = (const byte*)(x); \
const byte* _y = (const byte*)(y); \
int _z = (int)(z); \
int _w = ((_x) && (_y)) ? XMEMCMP(_x, _y, _z) : -1; \
Expect(_w op 0, ("%s " #op " %s for %s", #x, #y, #z), \
("\"%p\" " #er " \"%p\" for \"%d\"", _x, _y, _z));\
} \
} while(0)
#define ExpectBufEQ(x, y, z) ExpectBuf(x, y, z, ==, !=)
#define ExpectBufNE(x, y, z) ExpectBuf(x, y, z, !=, ==)
void ApiTest_PrintTestCases(void);
int ApiTest_RunIdx(int idx);
int ApiTest_RunName(char* name);
void ApiTest(void);
int ApiTest(void);
int SuiteTest(int argc, char** argv);
int HashTest(void);

View File

@ -15390,15 +15390,18 @@ static int ConfirmSignature(SignatureCtx* sigCtx,
sigCtx->key.rsa = (RsaKey*)XMALLOC(sizeof(RsaKey),
sigCtx->heap, DYNAMIC_TYPE_RSA);
sigCtx->sigCpy = (byte*)XMALLOC(sigSz, sigCtx->heap,
DYNAMIC_TYPE_SIGNATURE);
if (sigCtx->key.rsa == NULL || sigCtx->sigCpy == NULL) {
if (sigCtx->key.rsa == NULL) {
ERROR_OUT(MEMORY_E, exit_cs);
}
if ((ret = wc_InitRsaKey_ex(sigCtx->key.rsa, sigCtx->heap,
sigCtx->devId)) != 0) {
goto exit_cs;
}
sigCtx->sigCpy = (byte*)XMALLOC(sigSz, sigCtx->heap,
DYNAMIC_TYPE_SIGNATURE);
if (sigCtx->sigCpy == NULL) {
ERROR_OUT(MEMORY_E, exit_cs);
}
if (sigSz > MAX_ENCODED_SIG_SZ) {
WOLFSSL_MSG("Verify Signature is too big");
ERROR_OUT(BUFFER_E, exit_cs);

View File

@ -24,10 +24,6 @@
#include <config.h>
#endif
#ifdef WOLFSSL_LINUXKM
#define WOLFSSL_NEED_LINUX_CURRENT
#endif
#include <wolfssl/wolfcrypt/settings.h>
/* check old macros @wc_fips */
@ -55,6 +51,8 @@ Possible memory options:
* WOLFSSL_MALLOC_CHECK: Reports malloc or alignment failure using WOLFSSL_STATIC_ALIGN
* WOLFSSL_FORCE_MALLOC_FAIL_TEST: Used for internal testing to induce random malloc failures.
* WOLFSSL_HEAP_TEST: Used for internal testing of heap hint
* WOLFSSL_MEM_FAIL_COUNT: Fail memory allocation at a count from
* environment variable: MEM_FAIL_CNT.
*/
#ifdef WOLFSSL_ZEPHYR
@ -264,6 +262,50 @@ void wc_MemZero_Check(void* addr, size_t len)
}
#endif /* WOLFSSL_CHECK_MEM_ZERO */
#ifdef WOLFSSL_MEM_FAIL_COUNT
static wolfSSL_Mutex memFailMutex;
int mem_fail_allocs = 0;
int mem_fail_frees = 0;
int mem_fail_cnt = 0;
void wc_MemFailCount_Init()
{
wc_InitMutex(&memFailMutex);
char* cnt = getenv("MEM_FAIL_CNT");
if (cnt != NULL) {
fprintf(stderr, "MemFailCount At: %d\n", mem_fail_cnt);
mem_fail_cnt = atoi(cnt);
}
}
static int wc_MemFailCount_AllocMem(void)
{
int ret = 1;
wc_LockMutex(&memFailMutex);
if ((mem_fail_cnt > 0) && (mem_fail_cnt <= mem_fail_allocs + 1)) {
ret = 0;
}
else {
mem_fail_allocs++;
}
wc_UnLockMutex(&memFailMutex);
return ret;
}
static void wc_MemFailCount_FreeMem(void)
{
wc_LockMutex(&memFailMutex);
mem_fail_frees++;
wc_UnLockMutex(&memFailMutex);
}
void wc_MemFailCount_Free()
{
wc_FreeMutex(&memFailMutex);
fprintf(stderr, "MemFailCount Total: %d\n", mem_fail_allocs);
fprintf(stderr, "MemFailCount Frees: %d\n", mem_fail_frees);
}
#endif
#ifdef WOLFSSL_DEBUG_MEMORY
void* wolfSSL_Malloc(size_t size, const char* func, unsigned int line)
#else
@ -272,6 +314,13 @@ void* wolfSSL_Malloc(size_t size)
{
void* res = 0;
#ifdef WOLFSSL_MEM_FAIL_COUNT
if (!wc_MemFailCount_AllocMem()) {
WOLFSSL_MSG("MemFailCnt: Fail malloc");
return NULL;
}
#endif
#ifdef WOLFSSL_CHECK_MEM_ZERO
/* Space for requested size. */
size += MEM_ALIGN;
@ -365,6 +414,9 @@ void wolfSSL_Free(void *ptr)
/* Check that the pointer is zero where required. */
wc_MemZero_Check(((unsigned char*)ptr) + MEM_ALIGN, *(size_t*)ptr);
#endif
#ifdef WOLFSSL_MEM_FAIL_COUNT
wc_MemFailCount_FreeMem();
#endif
if (free_function) {
#ifdef WOLFSSL_DEBUG_MEMORY
@ -417,6 +469,13 @@ void* wolfSSL_Realloc(void *ptr, size_t size)
#else
void* res = 0;
#ifdef WOLFSSL_MEM_FAIL_COUNT
if (!wc_MemFailCount_AllocMem()) {
WOLFSSL_MSG("MemFailCnt: Fail realloc");
return NULL;
}
#endif
if (realloc_function) {
#ifdef WOLFSSL_DEBUG_MEMORY
res = realloc_function(ptr, size, func, line);
@ -432,6 +491,12 @@ void* wolfSSL_Realloc(void *ptr, size_t size)
#endif
}
#ifdef WOLFSSL_MEM_FAIL_COUNT
if (ptr != NULL) {
wc_MemFailCount_FreeMem();
}
#endif
return res;
#endif
}
@ -1245,6 +1310,13 @@ void *xmalloc(size_t n, void* heap, int type, const char* func,
void* p = NULL;
word32* p32;
#ifdef WOLFSSL_MEM_FAIL_COUNT
if (!wc_MemFailCount_AllocMem()) {
WOLFSSL_MSG("MemFailCnt: Fail malloc");
return NULL;
}
#endif
if (malloc_function)
p32 = malloc_function(n + sizeof(word32) * 4);
else
@ -1270,6 +1342,13 @@ void *xrealloc(void *p, size_t n, void* heap, int type, const char* func,
word32* oldp32 = NULL;
word32 oldLen;
#ifdef WOLFSSL_MEM_FAIL_COUNT
if (!wc_MemFailCount_AllocMem()) {
WOLFSSL_MSG("MemFailCnt: Fail malloc");
return NULL;
}
#endif
if (p != NULL) {
oldp32 = (word32*)p;
oldp32 -= 4;
@ -1293,6 +1372,12 @@ void *xrealloc(void *p, size_t n, void* heap, int type, const char* func,
type, func, file, line);
}
#ifdef WOLFSSL_MEM_FAIL_COUNT
if (p != NULL) {
wc_MemFailCount_FreeMem();
}
#endif
(void)heap;
return newp;
@ -1303,6 +1388,9 @@ void xfree(void *p, void* heap, int type, const char* func, const char* file,
word32* p32 = (word32*)p;
if (p != NULL) {
#ifdef WOLFSSL_MEM_FAIL_COUNT
wc_MemFailCount_FreeMem();
#endif
p32 -= 4;
fprintf(stderr, "Free: %p -> %u (%d) at %s:%s:%u\n", p, p32[0], type,

View File

@ -144,6 +144,9 @@ int wolfCrypt_Init(void)
* must be freed. */
wc_MemZero_Init();
#endif
#ifdef WOLFSSL_MEM_FAIL_COUNT
wc_MemFailCount_Init();
#endif
#ifdef WOLFSSL_FORCE_MALLOC_FAIL_TEST
{
@ -474,6 +477,9 @@ int wolfCrypt_Cleanup(void)
Entropy_Final();
#endif
#ifdef WOLFSSL_MEM_FAIL_COUNT
wc_MemFailCount_Free();
#endif
#ifdef WOLFSSL_CHECK_MEM_ZERO
/* Free the mutex for access to the list of memory locations that
* must be freed. */

View File

@ -2930,12 +2930,13 @@ static WC_INLINE int myVerify(int preverify, WOLFSSL_X509_STORE_CTX* store)
wolfSSL_X509_get_subject_name(peer), 0, 0);
printf("\tPeer's cert info:\n issuer : %s\n subject: %s\n", issuer,
subject);
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
/* preverify needs to be self-signer error for Qt compat.
* Should be ASN_SELF_SIGNED_E */
if (XSTRCMP(issuer, subject) == 0 && preverify == ASN_NO_SIGNER_E)
return 0;
if (issuer != NULL && subject != NULL) {
/* preverify needs to be self-signer error for Qt compat.
* Should be ASN_SELF_SIGNED_E */
if (XSTRCMP(issuer, subject) == 0 && preverify == ASN_NO_SIGNER_E)
return 0;
}
#endif
XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);

View File

@ -238,6 +238,11 @@ WOLFSSL_API int wolfSSL_GetAllocators(wolfSSL_Malloc_cb* mf,
__cyg_profile_func_exit(void *func, void *caller);
#endif /* WOLFSSL_STACK_LOG */
#ifdef WOLFSSL_MEM_FAIL_COUNT
WOLFSSL_LOCAL void wc_MemFailCount_Init(void);
WOLFSSL_LOCAL void wc_MemFailCount_Free(void);
#endif
#ifdef WOLFSSL_CHECK_MEM_ZERO
WOLFSSL_LOCAL void wc_MemZero_Init(void);
WOLFSSL_LOCAL void wc_MemZero_Free(void);