Skip to content

Commit

Permalink
introduce MP_MAX_SIZE to prevent overflow
Browse files Browse the repository at this point in the history
  • Loading branch information
minad committed Dec 4, 2019
1 parent 3a744dc commit 1606388
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 17 deletions.
2 changes: 1 addition & 1 deletion demo/shared.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,5 @@ void print_header(void)
printf("Size of mp_digit: %u\n", (unsigned int)sizeof(mp_digit));
printf("Size of mp_word: %u\n", (unsigned int)sizeof(mp_word));
printf("MP_DIGIT_BIT: %d\n", MP_DIGIT_BIT);
printf("MP_PREC: %d\n", MP_PREC);
printf("MP_DEFAULT_SIZE: %d\n", MP_DEFAULT_SIZE);
}
7 changes: 7 additions & 0 deletions demo/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -2220,6 +2220,8 @@ static int test_s_mp_radix_size_overestimate(void)
284u, 283u, 281u, 280u, 279u, 278u, 277u, 276u, 275u,
273u, 272u
};

#if 0
size_t big_results[65] = {
0u, 0u, 0u, 1354911329u, 1073741825u,
924870867u, 830760078u, 764949110u, 715827883u, 677455665u,
Expand All @@ -2235,6 +2237,7 @@ static int test_s_mp_radix_size_overestimate(void)
371449582u, 369786879u, 368168034u, 366591092u, 365054217u,
363555684u, 362093873u, 360667257u, 359274399u, 357913942
};
#endif

/* *INDENT-ON* */
if ((err = mp_init(&a)) != MP_OKAY) goto LBL_ERR;
Expand Down Expand Up @@ -2265,6 +2268,8 @@ static int test_s_mp_radix_size_overestimate(void)
}
a.sign = MP_ZPOS;
}

#if 0
if ((err = mp_2expt(&a, INT_MAX - 1)) != MP_OKAY) {
goto LBL_ERR;
}
Expand Down Expand Up @@ -2292,6 +2297,8 @@ static int test_s_mp_radix_size_overestimate(void)
}
a.sign = MP_ZPOS;
}
#endif

mp_clear(&a);
return EXIT_SUCCESS;
LBL_ERR:
Expand Down
13 changes: 9 additions & 4 deletions mp_grow.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,21 @@ mp_err mp_grow(mp_int *a, int size)
{
/* if the alloc size is smaller alloc more ram */
if (a->alloc < size) {
/* TODO */
mp_digit *dp;

if (size > MP_MAX_SIZE) {
return MP_MEM;
}

/* reallocate the array a->dp
*
* We store the return in a temporary variable
* in case the operation failed we don't want
* to overwrite the dp member of a.
*/
mp_digit *dp = (mp_digit *) MP_REALLOC(a->dp,
(size_t)a->alloc * sizeof(mp_digit),
(size_t)size * sizeof(mp_digit));
dp = (mp_digit *) MP_REALLOC(a->dp,
(size_t)a->alloc * sizeof(mp_digit),
(size_t)size * sizeof(mp_digit));
if (dp == NULL) {
/* reallocation failed but "a" is still valid [can be freed] */
return MP_MEM;
Expand Down
4 changes: 2 additions & 2 deletions mp_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
mp_err mp_init(mp_int *a)
{
/* allocate memory required and clear it */
a->dp = (mp_digit *) MP_CALLOC((size_t)MP_PREC, sizeof(mp_digit));
a->dp = (mp_digit *) MP_CALLOC((size_t)MP_DEFAULT_SIZE, sizeof(mp_digit));
if (a->dp == NULL) {
return MP_MEM;
}

/* set the used to zero, allocated digits to the default precision
* and sign to positive */
a->used = 0;
a->alloc = MP_PREC;
a->alloc = MP_DEFAULT_SIZE;
a->sign = MP_ZPOS;

return MP_OKAY;
Expand Down
7 changes: 5 additions & 2 deletions mp_init_size.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@
/* init an mp_init for a given size */
mp_err mp_init_size(mp_int *a, int size)
{
size = MP_MAX(MP_MIN_PREC, size);
size = MP_MAX(MP_MIN_SIZE, size);

if (size > MP_MAX_SIZE) {
return MP_MEM;
}

/*TODO*/
/* alloc mem */
a->dp = (mp_digit *) MP_CALLOC((size_t)size, sizeof(mp_digit));
if (a->dp == NULL) {
Expand Down
2 changes: 1 addition & 1 deletion mp_shrink.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
/* shrink a bignum */
mp_err mp_shrink(mp_int *a)
{
int alloc = MP_MAX(MP_MIN_PREC, a->used);
int alloc = MP_MAX(MP_MIN_SIZE, a->used);
if (a->alloc != alloc) {
mp_digit *dp = (mp_digit *) MP_REALLOC(a->dp,
(size_t)a->alloc * sizeof(mp_digit),
Expand Down
21 changes: 14 additions & 7 deletions tommath_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,22 +140,29 @@ typedef uint64_t mp_word;

MP_STATIC_ASSERT(correct_word_size, sizeof(mp_word) == (2u * sizeof(mp_digit)))

/* default precision */
#ifndef MP_PREC
/* default number of digits */
#ifndef MP_DEFAULT_SIZE
# ifndef MP_LOW_MEM
# define MP_PREC 32 /* default digits of precision */
# define MP_DEFAULT_SIZE 32
# else
# define MP_PREC 8 /* default digits of precision */
# define MP_DEFAULT_SIZE 8
# endif
#endif

/* Minimum number of available digits in mp_int, MP_PREC >= MP_MIN_PREC
/* Minimum number of available digits in mp_int, MP_DEFAULT_SIZE >= MP_MIN_SIZE
* - Must be at least 3 for s_mp_div_school.
* - Must be large enough such that the mp_set_u64 setter can
* store uint64_t in the mp_int without growing
*/
#define MP_MIN_PREC MP_MAX(3, (((int)MP_SIZEOF_BITS(uint64_t) + MP_DIGIT_BIT) - 1) / MP_DIGIT_BIT)
MP_STATIC_ASSERT(prec_geq_min_prec, MP_PREC >= MP_MIN_PREC)
#define MP_MIN_SIZE MP_MAX(3, (((int)MP_SIZEOF_BITS(uint64_t) + MP_DIGIT_BIT) - 1) / MP_DIGIT_BIT)
MP_STATIC_ASSERT(prec_geq_min_prec, MP_DEFAULT_SIZE >= MP_MIN_SIZE)

/* Maximum number of digits.
* - Must be small enough such that mp_bit_count does not overflow.
* - Must be small enough such that mp_radix_size for base 2 does not overflow.
* mp_radix_size needs two additional bytes for zero termination and sign.
*/
#define MP_MAX_SIZE ((INT_MAX - 2) / MP_DIGIT_BIT)

/* random number source */
extern MP_PRIVATE mp_err(*s_mp_rand_source)(void *out, size_t size);
Expand Down

0 comments on commit 1606388

Please sign in to comment.