summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoah Misch <noah@leadboat.com>2015-02-02 10:00:45 -0500
committerNoah Misch <noah@leadboat.com>2015-02-02 10:00:52 -0500
commit8d412e02ebfb106aedc2edef8e3b26e802311151 (patch)
tree215c3a90656040134cda8240cae5a9f57b3e6cb1
parent11f738a8afb9e93ca31cd37331fc640d92b9ec96 (diff)
Cherry-pick security-relevant fixes from upstream imath library.
This covers alterations to buffer sizing and zeroing made between imath 1.3 and imath 1.20. Valgrind Memcheck identified the buffer overruns and reliance on uninitialized data; their exploit potential is unknown. Builds specifying --with-openssl are unaffected, because they use the OpenSSL BIGNUM facility instead of imath. Back-patch to 9.0 (all supported versions). Security: CVE-2015-0243
-rw-r--r--contrib/pgcrypto/imath.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/contrib/pgcrypto/imath.c b/contrib/pgcrypto/imath.c
index 1bb90faa75d..26cf7c4970f 100644
--- a/contrib/pgcrypto/imath.c
+++ b/contrib/pgcrypto/imath.c
@@ -818,7 +818,8 @@ mp_int_mul(mp_int a, mp_int b, mp_int c)
*/
ua = MP_USED(a);
ub = MP_USED(b);
- osize = ua + ub;
+ osize = MAX(ua, ub);
+ osize = 4 * ((osize + 1) / 2);
if (c == a || c == b)
{
@@ -907,7 +908,7 @@ mp_int_sqr(mp_int a, mp_int c)
CHECK(a != NULL && c != NULL);
/* Get a temporary buffer big enough to hold the result */
- osize = (mp_size) 2 *MP_USED(a);
+ osize = (mp_size) 4 *((MP_USED(a) + 1) / 2);
if (a == c)
{
@@ -2605,8 +2606,8 @@ s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc,
* Now we'll get t1 = a0b0 and t2 = a1b1, and subtract them out so
* that we're left with only the pieces we want: t3 = a1b0 + a0b1
*/
- ZERO(t1, bot_size + 1);
- ZERO(t2, bot_size + 1);
+ ZERO(t1, buf_size);
+ ZERO(t2, buf_size);
(void) s_kmul(da, db, t1, bot_size, bot_size); /* t1 = a0 * b0 */
(void) s_kmul(a_top, b_top, t2, at_size, bt_size); /* t2 = a1 * b1 */
@@ -2616,11 +2617,13 @@ s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc,
/* Assemble the output value */
COPY(t1, dc, buf_size);
- (void) s_uadd(t3, dc + bot_size, dc + bot_size,
- buf_size + 1, buf_size + 1);
+ carry = s_uadd(t3, dc + bot_size, dc + bot_size,
+ buf_size + 1, buf_size);
+ assert(carry == 0);
- (void) s_uadd(t2, dc + 2 * bot_size, dc + 2 * bot_size,
- buf_size, buf_size);
+ carry = s_uadd(t2, dc + 2 * bot_size, dc + 2 * bot_size,
+ buf_size, buf_size);
+ assert(carry == 0);
s_free(t1); /* note t2 and t3 are just internal pointers
* to t1 */
@@ -3307,7 +3310,10 @@ s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c)
dbt = db + MP_USED(b) - 1;
while (last < 3)
- SETUP(mp_int_init_size(TEMP(last), 2 * umu), last);
+ {
+ SETUP(mp_int_init_size(TEMP(last), 4 * umu), last);
+ ZERO(MP_DIGITS(TEMP(last - 1)), MP_ALLOC(TEMP(last - 1)));
+ }
(void) mp_int_set_value(c, 1);