summaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorSiddhesh Poyarekar <siddhesh@redhat.com>2013-01-02 11:33:11 +0530
committerSiddhesh Poyarekar <siddhesh@redhat.com>2013-01-02 11:33:11 +0530
commit4d55b4e596d63705b86200d15d905b2549dd25df (patch)
tree83db5fc21391432d05946d31ca96b29634586392 /sysdeps
parentda08f647d58d674db08cdb3e61c8826c89470e2e (diff)
Add assert for potential access beyond array bounds in m1np
The mpexp code has an access into m1np: for (i=n-1; i>0; i--,n--) { if (m1np[i][p]+m2>0) break; } which could break for p >= 18 or i >= 7. Fortunately this code is never called due to the way the exp function is implemented since values having exponent less than -55 return 1.0. Make sure that if it gets called in future, it is trapped.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/ieee754/dbl-64/mpexp.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/sysdeps/ieee754/dbl-64/mpexp.c b/sysdeps/ieee754/dbl-64/mpexp.c
index 92399a3096..3814fe2b29 100644
--- a/sysdeps/ieee754/dbl-64/mpexp.c
+++ b/sysdeps/ieee754/dbl-64/mpexp.c
@@ -31,6 +31,7 @@
#include "endian.h"
#include "mpa.h"
#include "mpexp.h"
+#include <assert.h>
#ifndef SECTION
# define SECTION
@@ -71,10 +72,22 @@ __mpexp(mp_no *x, mp_no *y, int p) {
for (i=2; i<=p; i++) { if (X[i]!=ZERO) break; }
if (i==p+1) { m2--; a *= TWO; }
}
- if ((m=m1+m2) <= 0) {
- m=0; a=ONE;
- for (i=n-1; i>0; i--,n--) { if (m1np[i][p]+m2>0) break; }
- }
+
+ m = m1 + m2;
+ if (__glibc_unlikely (m <= 0))
+ {
+ /* The m1np array which is used to determine if we can reduce the
+ polynomial expansion iterations, has only 18 elements. Besides,
+ numbers smaller than those required by p >= 18 should not come here
+ at all since the fast phase of exp returns 1.0 for anything less
+ than 2^-55. */
+ assert (p < 18);
+ m = 0;
+ a = ONE;
+ for (i = n - 1; i > 0; i--, n--)
+ if (m1np[i][p] + m2 > 0)
+ break;
+ }
/* Compute s=x*2**(-m). Put result in mps */
__dbl_mp(a,&mpt1,p);