-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Fix GH-16501: gmp_random_bits overflow. #16503
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1803,15 +1803,21 @@ ZEND_FUNCTION(gmp_random_bits) | |
RETURN_THROWS(); | ||
} | ||
|
||
if (bits <= 0) { | ||
zend_argument_value_error(1, "must be greater than or equal to 1"); | ||
#if SIZEOF_SIZE_T == 4 | ||
const zend_long maxbits = ULONG_MAX / GMP_NUMB_BITS; | ||
#else | ||
const zend_long maxbits = INT_MAX; | ||
#endif | ||
|
||
if (bits <= 0 || bits > maxbits) { | ||
zend_argument_value_error(1, "must be between 1 and " ZEND_LONG_FMT, maxbits); | ||
RETURN_THROWS(); | ||
} | ||
|
||
INIT_GMP_RETVAL(gmpnum_result); | ||
gmp_init_random(); | ||
|
||
mpz_urandomb(gmpnum_result, GMPG(rand_state), bits); | ||
mpz_urandomb(gmpnum_result, GMPG(rand_state), (mp_bitcnt_t)bits); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It s just to avoid pedantic build warning I guess, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, just extraneous; I'd remove it (could still trigger some compiler/analyser diagnostic without the cast). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I overlooked your comment. Let's leave it as is. |
||
} | ||
/* }}} */ | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
--TEST-- | ||
GH-16501 (gmp_random_bits overflow) | ||
--EXTENSIONS-- | ||
gmp | ||
--FILE-- | ||
<?php | ||
try { | ||
gmp_random_bits(PHP_INT_MAX); | ||
} catch (\ValueError $e) { | ||
echo $e->getMessage(); | ||
} | ||
?> | ||
--EXPECTF-- | ||
gmp_random_bits(): Argument #1 ($bits) must be between 1 and %d |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This still can overflow. libgmp does this check, but afterwards calculates ((new_alloc) * sizeof (mp_limb_t)), where
sizeof(mp_limb_t)
is certainly larger than 2 (I assume it's usually four or eight).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Disregard. This is fine; I was confused by 32bit using ULONG_MAX, but 64bit using INT_MAX. The 32bit case looks fishy (for LP64), though.