File nss-fix_mpi_division.patch of Package mozilla-nss.1915

# HG changeset patch
# User Wan-Teh Chang <wtc@google.com>
# Date 1440523271 25200
#      Tue Aug 25 10:21:11 2015 -0700
# Branch NSS_3_20_BRANCH
# Node ID f78a7cba9a4f91dfe6ed85b47884a7361800fbdf
# Parent  099b97bb90938a11c1b826312be1b613655517c2
CVE-2016-1938
MFSA 2016-07
bmo#1190248
bsc#963731

Import of changesets:

a555bf0fc23a981f22ed8ea6da89ef8d0c5ecf56
Bug 1190248: Compute a guess for the next quotient digit correctly in s_mp_div.
r=rrelyea.

608645309ab97aff5f6bf5bb71ddf13cc8a820f5
Bug 1190248: Delete a space at the end of a line.

cfd0ad4726cb1ba1d90946ac194390f56c40fd5b
Bug 1190248: Just initialize the |sign| field of |part| in s_mp_div().
r=rrelyea.

from 3.21

diff --git a/lib/freebl/mpi/mpi.c b/lib/freebl/mpi/mpi.c
--- a/lib/freebl/mpi/mpi.c
+++ b/lib/freebl/mpi/mpi.c
@@ -4191,66 +4191,77 @@ mp_err   s_mp_div(mp_int *rem, 	/* i: di
     s_mp_div_2d(quot, (mp_digit)ix);
     s_mp_mod_2d(rem,  (mp_digit)ix);
 
     return MP_OKAY;
   }
 
   MP_SIGN(rem) = ZPOS;
   MP_SIGN(div) = ZPOS;
+  MP_SIGN(&part) = ZPOS;
 
   /* A working temporary for division     */
   MP_CHECKOK( mp_init_size(&t, MP_ALLOC(rem)));
 
   /* Normalize to optimize guessing       */
   MP_CHECKOK( s_mp_norm(rem, div, &d) );
 
-  part = *rem;
-
   /* Perform the division itself...woo!   */
   MP_USED(quot) = MP_ALLOC(quot);
 
   /* Find a partial substring of rem which is at least div */
   /* If we didn't find one, we're finished dividing    */
   while (MP_USED(rem) > MP_USED(div) || s_mp_cmp(rem, div) >= 0) {
     int i;
     int unusedRem;
+    int partExtended = 0;  /* set to true if we need to extend part */
 
     unusedRem = MP_USED(rem) - MP_USED(div);
     MP_DIGITS(&part) = MP_DIGITS(rem) + unusedRem;
     MP_ALLOC(&part)  = MP_ALLOC(rem)  - unusedRem;
     MP_USED(&part)   = MP_USED(div);
+
+    /* We have now truncated the part of the remainder to the same length as
+     * the divisor. If part is smaller than div, extend part by one digit. */
     if (s_mp_cmp(&part, div) < 0) {
       -- unusedRem;
 #if MP_ARGCHK == 2
       assert(unusedRem >= 0);
 #endif
       -- MP_DIGITS(&part);
       ++ MP_USED(&part);
       ++ MP_ALLOC(&part);
+      partExtended = 1;
     }
 
     /* Compute a guess for the next quotient digit       */
     q_msd = MP_DIGIT(&part, MP_USED(&part) - 1);
     div_msd = MP_DIGIT(div, MP_USED(div) - 1);
-    if (q_msd >= div_msd) {
+    if (!partExtended) {
+      /* In this case, q_msd /= div_msd is always 1. First, since div_msd is
+       * normalized to have the high bit set, 2*div_msd > MP_DIGIT_MAX. Since
+       * we didn't extend part, q_msd >= div_msd. Therefore we know that
+       * div_msd <= q_msd <= MP_DIGIT_MAX < 2*div_msd. Dividing by div_msd we
+       * get 1 <= q_msd/div_msd < 2. So q_msd /= div_msd must be 1. */
       q_msd = 1;
-    } else if (MP_USED(&part) > 1) {
+    } else {
 #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
       q_msd = (q_msd << MP_DIGIT_BIT) | MP_DIGIT(&part, MP_USED(&part) - 2);
       q_msd /= div_msd;
       if (q_msd == RADIX)
         --q_msd;
 #else
-      mp_digit r;
-      MP_CHECKOK( s_mpv_div_2dx1d(q_msd, MP_DIGIT(&part, MP_USED(&part) - 2), 
-				  div_msd, &q_msd, &r) );
+      if (q_msd == div_msd) {
+        q_msd = MP_DIGIT_MAX;
+      } else {
+        mp_digit r;
+        MP_CHECKOK( s_mpv_div_2dx1d(q_msd, MP_DIGIT(&part, MP_USED(&part) - 2),
+				    div_msd, &q_msd, &r) );
+      }
 #endif
-    } else {
-      q_msd = 0;
     }
 #if MP_ARGCHK == 2
     assert(q_msd > 0); /* This case should never occur any more. */
 #endif
     if (q_msd <= 0)
       break;
 
     /* See what that multiplies out to                   */
openSUSE Build Service is sponsored by