Skip to content

Commit 94014ee

Browse files
committed
rsa: address review - drop XMEMSET, free uninitialized temporaries instead
Restore the original short-circuit XMALLOC chains and leave the zeroing to mp_init_multi(). On a partial allocation failure mp_init_multi() is skipped, so nothing is initialized: free whatever was allocated right there and NULL the pointers, so the shared cleanup at the end of the function never calls mp_clear()/mp_forcezero() on an allocated-but-uninitialized mp_int. No extra mp_init() calls, no XMEMSET, and the returned error codes are unchanged.
1 parent 2e985f4 commit 94014ee

1 file changed

Lines changed: 35 additions & 37 deletions

File tree

wolfcrypt/src/rsa.c

Lines changed: 35 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5062,19 +5062,18 @@ static int wc_CompareDiffPQ(mp_int* p, mp_int* q, int size, int* valid)
50625062
return BAD_FUNC_ARG;
50635063

50645064
#ifdef WOLFSSL_SMALL_STACK
5065-
c = (mp_int *)XMALLOC(sizeof(*c), NULL, DYNAMIC_TYPE_WOLF_BIGINT);
5066-
d = (mp_int *)XMALLOC(sizeof(*d), NULL, DYNAMIC_TYPE_WOLF_BIGINT);
5067-
/* Zero any struct that was allocated so the cleanup path's mp_clear()/
5068-
* mp_forcezero() are safe even when the sibling allocation fails and the
5069-
* mp_init_multi() below is skipped on MEMORY_E. Without this, clearing an
5070-
* allocated-but-uninitialized mp_int reads a garbage ->used and corrupts
5071-
* the heap. */
5072-
if (c != NULL)
5073-
XMEMSET(c, 0, sizeof(*c));
5074-
if (d != NULL)
5075-
XMEMSET(d, 0, sizeof(*d));
5076-
if (c == NULL || d == NULL)
5065+
if (((c = (mp_int *)XMALLOC(sizeof(*c), NULL, DYNAMIC_TYPE_WOLF_BIGINT)) == NULL) ||
5066+
((d = (mp_int *)XMALLOC(sizeof(*d), NULL, DYNAMIC_TYPE_WOLF_BIGINT)) == NULL)) {
5067+
/* mp_init_multi() below is skipped, so nothing was initialized: free
5068+
* what was allocated here and NULL the pointers. The cleanup at the
5069+
* end must not see an allocated-but-uninitialized mp_int - clearing
5070+
* one reads a garbage used/size and corrupts the heap. */
5071+
XFREE(c, NULL, DYNAMIC_TYPE_WOLF_BIGINT);
5072+
XFREE(d, NULL, DYNAMIC_TYPE_WOLF_BIGINT);
5073+
c = NULL;
5074+
d = NULL;
50775075
ret = MEMORY_E;
5076+
}
50785077
else
50795078
ret = 0;
50805079

@@ -5215,17 +5214,16 @@ static int _CheckProbablePrime(mp_int* p, mp_int* q, mp_int* e, int nlen,
52155214
*isPrime = MP_NO;
52165215

52175216
#ifdef WOLFSSL_SMALL_STACK
5218-
tmp1 = (mp_int *)XMALLOC(sizeof(*tmp1), NULL, DYNAMIC_TYPE_WOLF_BIGINT);
5219-
tmp2 = (mp_int *)XMALLOC(sizeof(*tmp2), NULL, DYNAMIC_TYPE_WOLF_BIGINT);
5220-
/* Zero any allocated struct so the notOkay cleanup's mp_forcezero()/
5221-
* mp_clear() are safe when the sibling allocation fails and the
5222-
* mp_init_multi() below is skipped: clearing an allocated-but-
5223-
* uninitialized mp_int reads a garbage ->used and corrupts the heap. */
5224-
if (tmp1 != NULL)
5225-
XMEMSET(tmp1, 0, sizeof(*tmp1));
5226-
if (tmp2 != NULL)
5227-
XMEMSET(tmp2, 0, sizeof(*tmp2));
5228-
if (tmp1 == NULL || tmp2 == NULL) {
5217+
if (((tmp1 = (mp_int *)XMALLOC(sizeof(*tmp1), NULL, DYNAMIC_TYPE_WOLF_BIGINT)) == NULL) ||
5218+
((tmp2 = (mp_int *)XMALLOC(sizeof(*tmp2), NULL, DYNAMIC_TYPE_WOLF_BIGINT)) == NULL)) {
5219+
/* mp_init_multi() below is skipped, so nothing was initialized: free
5220+
* what was allocated here and NULL the pointers. The notOkay cleanup
5221+
* must not see an allocated-but-uninitialized mp_int - clearing one
5222+
* reads a garbage used/size and corrupts the heap. */
5223+
XFREE(tmp1, NULL, DYNAMIC_TYPE_WOLF_BIGINT);
5224+
XFREE(tmp2, NULL, DYNAMIC_TYPE_WOLF_BIGINT);
5225+
tmp1 = NULL;
5226+
tmp2 = NULL;
52295227
ret = MEMORY_E;
52305228
goto notOkay;
52315229
}
@@ -5328,21 +5326,21 @@ int wc_CheckProbablePrime_ex(const byte* pRaw, word32 pRawSz,
53285326

53295327
#ifdef WOLFSSL_SMALL_STACK
53305328

5331-
p = (mp_int *)XMALLOC(sizeof(*p), NULL, DYNAMIC_TYPE_RSA_BUFFER);
5332-
q = (mp_int *)XMALLOC(sizeof(*q), NULL, DYNAMIC_TYPE_RSA_BUFFER);
5333-
e = (mp_int *)XMALLOC(sizeof(*e), NULL, DYNAMIC_TYPE_RSA_BUFFER);
5334-
/* Zero any allocated struct so the cleanup path's mp_forcezero()/
5335-
* mp_clear() are safe when a later allocation in the chain fails and the
5336-
* mp_init_multi() below is skipped on MEMORY_E: clearing an allocated-but-
5337-
* uninitialized mp_int reads a garbage ->used and corrupts the heap. */
5338-
if (p != NULL)
5339-
XMEMSET(p, 0, sizeof(*p));
5340-
if (q != NULL)
5341-
XMEMSET(q, 0, sizeof(*q));
5342-
if (e != NULL)
5343-
XMEMSET(e, 0, sizeof(*e));
5344-
if (p == NULL || q == NULL || e == NULL)
5329+
if (((p = (mp_int *)XMALLOC(sizeof(*p), NULL, DYNAMIC_TYPE_RSA_BUFFER)) == NULL) ||
5330+
((q = (mp_int *)XMALLOC(sizeof(*q), NULL, DYNAMIC_TYPE_RSA_BUFFER)) == NULL) ||
5331+
((e = (mp_int *)XMALLOC(sizeof(*e), NULL, DYNAMIC_TYPE_RSA_BUFFER)) == NULL)) {
5332+
/* mp_init_multi() below is skipped, so nothing was initialized: free
5333+
* what was allocated here and NULL the pointers. The cleanup at the
5334+
* end must not see an allocated-but-uninitialized mp_int - clearing
5335+
* one reads a garbage used/size and corrupts the heap. */
5336+
XFREE(p, NULL, DYNAMIC_TYPE_RSA_BUFFER);
5337+
XFREE(q, NULL, DYNAMIC_TYPE_RSA_BUFFER);
5338+
XFREE(e, NULL, DYNAMIC_TYPE_RSA_BUFFER);
5339+
p = NULL;
5340+
q = NULL;
5341+
e = NULL;
53455342
ret = MEMORY_E;
5343+
}
53465344
else
53475345
ret = 0;
53485346
if (ret == 0)

0 commit comments

Comments
 (0)