Skip to content

Commit 1358fa4

Browse files
committed
test improvement
1 parent c00f0a6 commit 1358fa4

1 file changed

Lines changed: 20 additions & 34 deletions

File tree

tests/api/test_rsa.c

Lines changed: 20 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,17 +1160,15 @@ int test_wc_RsaKeyToDer_SizeOverflow(void)
11601160
EXPECT_DECLS;
11611161
#if !defined(NO_RSA) && defined(USE_INTEGER_HEAP_MATH) && \
11621162
defined(WOLFSSL_ASN_TEMPLATE) && \
1163-
(defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_KEY_TO_DER)) && \
1164-
!defined(_WIN32)
1165-
#include <sys/mman.h>
1163+
(defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_KEY_TO_DER))
11661164
RsaKey key;
11671165
int i;
11681166
int derRet;
11691167
int crafted_used;
11701168
int top_bits;
11711169
mp_digit top_digit;
1172-
mp_digit* crafted_dp = MAP_FAILED;
1173-
size_t dp_bytes = 0;
1170+
mp_digit storage = 0; /* the only digit mp_count_bits ever reads */
1171+
mp_digit* fake_dp = NULL;
11741172

11751173
int orig_used = 0;
11761174
int orig_alloc = 0;
@@ -1181,6 +1179,11 @@ int test_wc_RsaKeyToDer_SizeOverflow(void)
11811179

11821180
XMEMSET(&key, 0, sizeof(key));
11831181

1182+
/* Skip on 32-bit: biasing dp by ~half the address space is unsafe. */
1183+
if (sizeof(void*) < 8) {
1184+
return TEST_SKIPPED;
1185+
}
1186+
11841187
/* Find 'used' count that makes (used-1)*DIGIT_BIT + top_bits = -48
11851188
* as signed int, causing mp_unsigned_bin_size to return -6. */
11861189
{
@@ -1205,8 +1208,6 @@ int test_wc_RsaKeyToDer_SizeOverflow(void)
12051208
}
12061209
}
12071210

1208-
dp_bytes = (size_t)crafted_used * sizeof(mp_digit);
1209-
12101211
ExpectIntEQ(wc_InitRsaKey(&key, HEAP_HINT), 0);
12111212

12121213
/* Set up dummy RSA private key fields. */
@@ -1234,31 +1235,20 @@ int test_wc_RsaKeyToDer_SizeOverflow(void)
12341235
orig_dp = key.p.dp;
12351236
}
12361237

1237-
/* Sparse mmap — only the page at dp[used-1] is faulted in. */
1238+
/* The vulnerable path (mp_unsigned_bin_size -> mp_count_bits, and
1239+
* mp_leading_bit) only reads dp[used-1]. Bias dp so that index
1240+
* (used-1) lands on our single real digit -- no giant allocation
1241+
* (and no mmap/VirtualAlloc) needed. */
12381242
if (EXPECT_SUCCESS()) {
1239-
crafted_dp = (mp_digit*)mmap(NULL, dp_bytes,
1240-
PROT_READ | PROT_WRITE,
1241-
MAP_PRIVATE | MAP_ANONYMOUS
1242-
#ifdef MAP_NORESERVE
1243-
| MAP_NORESERVE
1244-
#endif
1245-
, -1, 0);
1243+
storage = top_digit;
1244+
fake_dp = (mp_digit*)((wc_ptr_t)&storage
1245+
- (wc_ptr_t)(crafted_used - 1) * sizeof(mp_digit));
1246+
1247+
key.p.dp = fake_dp;
1248+
key.p.used = crafted_used;
1249+
key.p.alloc = crafted_used;
1250+
key.p.sign = 0; /* MP_ZPOS */
12461251
}
1247-
if (crafted_dp == MAP_FAILED) {
1248-
key.p.dp = orig_dp;
1249-
key.p.used = orig_used;
1250-
key.p.alloc = orig_alloc;
1251-
key.p.sign = orig_sign;
1252-
DoExpectIntEQ(wc_FreeRsaKey(&key), 0);
1253-
return TEST_SKIPPED;
1254-
}
1255-
1256-
crafted_dp[crafted_used - 1] = top_digit;
1257-
1258-
key.p.dp = crafted_dp;
1259-
key.p.used = crafted_used;
1260-
key.p.alloc = crafted_used;
1261-
key.p.sign = 0; /* MP_ZPOS */
12621252

12631253
/* Should return an error, not a bogus small size. */
12641254
derRet = wc_RsaKeyToDer(&key, NULL, 0);
@@ -1270,10 +1260,6 @@ int test_wc_RsaKeyToDer_SizeOverflow(void)
12701260
key.p.alloc = orig_alloc;
12711261
key.p.sign = orig_sign;
12721262

1273-
if (crafted_dp != MAP_FAILED) {
1274-
munmap(crafted_dp, dp_bytes);
1275-
}
1276-
12771263
DoExpectIntEQ(wc_FreeRsaKey(&key), 0);
12781264
#endif
12791265
return EXPECT_RESULT();

0 commit comments

Comments
 (0)