test/bntest.c:1934: error: BUFFER_OVERRUN_L3
  Offset: [1, +oo] Size: [0, 8388607] by call to `BN_div`.
Showing all 14 steps of the trace


test/bntest.c:1911:10: Call
1909.   
1910.       /* Test that BN_mul never gives negative zero. */
1911.       if (!TEST_true(BN_set_word(a, 1)))
                 ^
1912.           goto err;
1913.       BN_set_negative(a, 1);

crypto/bn/bn_lib.c:359:1: Parameter `*a->d`
  357.   }
  358.   
  359. > int BN_set_word(BIGNUM *a, BN_ULONG w)
  360.   {
  361.       bn_check_top(a);

crypto/bn/bn_lib.c:362:9: Call
  360.   {
  361.       bn_check_top(a);
  362.       if (bn_expand(a, (int)sizeof(BN_ULONG) * 8) == NULL)
                 ^
  363.           return 0;
  364.       a->neg = 0;

crypto/bn/bn_lcl.h:660:1: Parameter `*a->d`
    658.                            const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx);
    659.   
    660. > static ossl_inline BIGNUM *bn_expand(BIGNUM *a, int bits)
    661.   {
    662.       if (bits > (INT_MAX - BN_BITS2 + 1))

test/bntest.c:1934:14: Call
1932.               goto err;
1933.           BN_set_negative(numerator, 1);
1934.           if (!TEST_true(BN_div(a, b, numerator, denominator, ctx))
                     ^
1935.                   || !TEST_BN_eq_zero(a)
1936.                   || !TEST_BN_ge_zero(a))

crypto/bn/bn_div.c:229:11: Call
  227.       }
  228.   
  229.       ret = bn_div_fixed_top(dv, rm, num, divisor, ctx);
                   ^
  230.   
  231.       if (ret) {

crypto/bn/bn_div.c:264:1: Parameter `dv->top`
    262.    *       divisor's length is considered public;
    263.    */
    264. > int bn_div_fixed_top(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num,
    265.                        const BIGNUM *divisor, BN_CTX *ctx)
    266.   {

crypto/bn/bn_div.c:233:13: Call
  231.       if (ret) {
  232.           if (dv != NULL)
  233.               bn_correct_top(dv);
                     ^
  234.           if (rm != NULL)
  235.               bn_correct_top(rm);

crypto/bn/bn_lib.c:944:1: <Offset trace>
942.   }
943.   
944. > void bn_correct_top(BIGNUM *a)
945.   {
946.       BN_ULONG *ftl;

crypto/bn/bn_lib.c:944:1: Parameter `a->top`
    942.   }
    943.   
    944. > void bn_correct_top(BIGNUM *a)
    945.   {
    946.       BN_ULONG *ftl;

crypto/bn/bn_lib.c:947:5: Assignment
    945.   {
    946.       BN_ULONG *ftl;
    947.       int tmp_top = a->top;
               ^
    948.   
    949.       if (tmp_top > 0) {

crypto/bn/bn_lib.c:944:1: <Length trace>
942.   }
943.   
944. > void bn_correct_top(BIGNUM *a)
945.   {
946.       BN_ULONG *ftl;

crypto/bn/bn_lib.c:944:1: Parameter `*a->d`
    942.   }
    943.   
    944. > void bn_correct_top(BIGNUM *a)
    945.   {
    946.       BN_ULONG *ftl;

crypto/bn/bn_lib.c:950:14: Array access: Offset: [1, +oo] Size: [0, 8388607] by call to `BN_div` 
    948.   
    949.       if (tmp_top > 0) {
    950.           for (ftl = &(a->d[tmp_top]); tmp_top > 0; tmp_top--) {
                        ^
    951.               ftl--;
    952.               if (*ftl != 0)

void bn_correct_top(BIGNUM *a)
{
    BN_ULONG *ftl;
    int tmp_top = a->top;
    if (tmp_top > 0) {
        for (ftl = &(a->d[tmp_top]); tmp_top > 0; tmp_top--) {
            ftl--;
            if (*ftl != 0)
                break;
        }
        a->top = tmp_top;
    }
    if (a->top == 0)
        a->neg = 0;
    a->flags &= ~BN_FLG_FIXED_TOP;
    bn_pollute(a);
}
['static int test_negzero(void)\n{\n    BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL;\n    BIGNUM *numerator = NULL, *denominator = NULL;\n    int consttime, st = 0;\n    if (!TEST_ptr(a = BN_new())\n            || !TEST_ptr(b = BN_new())\n            || !TEST_ptr(c = BN_new())\n            || !TEST_ptr(d = BN_new()))\n        goto err;\n    if (!TEST_true(BN_set_word(a, 1)))\n        goto err;\n    BN_set_negative(a, 1);\n    BN_zero(b);\n    if (!TEST_true(BN_mul(c, a, b, ctx)))\n        goto err;\n    if (!TEST_BN_eq_zero(c)\n            || !TEST_BN_ge_zero(c))\n        goto err;\n    for (consttime = 0; consttime < 2; consttime++) {\n        if (!TEST_ptr(numerator = BN_new())\n                || !TEST_ptr(denominator = BN_new()))\n            goto err;\n        if (consttime) {\n            BN_set_flags(numerator, BN_FLG_CONSTTIME);\n            BN_set_flags(denominator, BN_FLG_CONSTTIME);\n        }\n        if (!TEST_true(BN_set_word(numerator, 1))\n                || !TEST_true(BN_set_word(denominator, 2)))\n            goto err;\n        BN_set_negative(numerator, 1);\n        if (!TEST_true(BN_div(a, b, numerator, denominator, ctx))\n                || !TEST_BN_eq_zero(a)\n                || !TEST_BN_ge_zero(a))\n            goto err;\n        if (!TEST_true(BN_set_word(denominator, 1))\n                || !TEST_true(BN_div(a, b, numerator, denominator, ctx))\n                || !TEST_BN_eq_zero(b)\n                || !TEST_BN_ge_zero(b))\n            goto err;\n        BN_free(numerator);\n        BN_free(denominator);\n        numerator = denominator = NULL;\n    }\n    BN_zero(a);\n    BN_set_negative(a, 1);\n    if (BN_is_negative(a))\n        goto err;\n    st = 1;\nerr:\n    BN_free(a);\n    BN_free(b);\n    BN_free(c);\n    BN_free(d);\n    BN_free(numerator);\n    BN_free(denominator);\n    return st;\n}', 'int BN_set_word(BIGNUM *a, BN_ULONG w)\n{\n    bn_check_top(a);\n    if (bn_expand(a, (int)sizeof(BN_ULONG) * 8) == NULL)\n        return 0;\n    a->neg = 0;\n    a->d[0] = w;\n    a->top = (w ? 1 : 0);\n    a->flags &= ~BN_FLG_FIXED_TOP;\n    bn_check_top(a);\n    return 1;\n}', 'static ossl_inline BIGNUM *bn_expand(BIGNUM *a, int bits)\n{\n    if (bits > (INT_MAX - BN_BITS2 + 1))\n        return NULL;\n    if (((bits+BN_BITS2-1)/BN_BITS2) <= (a)->dmax)\n        return a;\n    return bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2);\n}', 'int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,\n           BN_CTX *ctx)\n{\n    int ret;\n    if (BN_is_zero(divisor)) {\n        BNerr(BN_F_BN_DIV, BN_R_DIV_BY_ZERO);\n        return 0;\n    }\n    if (divisor->d[divisor->top - 1] == 0) {\n        BNerr(BN_F_BN_DIV, BN_R_NOT_INITIALIZED);\n        return 0;\n    }\n    ret = bn_div_fixed_top(dv, rm, num, divisor, ctx);\n    if (ret) {\n        if (dv != NULL)\n            bn_correct_top(dv);\n        if (rm != NULL)\n            bn_correct_top(rm);\n    }\n    return ret;\n}', 'int bn_div_fixed_top(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num,\n                     const BIGNUM *divisor, BN_CTX *ctx)\n{\n    int norm_shift, i, j, loop;\n    BIGNUM *tmp, *snum, *sdiv, *res;\n    BN_ULONG *resp, *wnum, *wnumtop;\n    BN_ULONG d0, d1;\n    int num_n, div_n;\n    assert(divisor->top > 0 && divisor->d[divisor->top - 1] != 0);\n    bn_check_top(num);\n    bn_check_top(divisor);\n    bn_check_top(dv);\n    bn_check_top(rm);\n    BN_CTX_start(ctx);\n    res = (dv == NULL) ? BN_CTX_get(ctx) : dv;\n    tmp = BN_CTX_get(ctx);\n    snum = BN_CTX_get(ctx);\n    sdiv = BN_CTX_get(ctx);\n    if (sdiv == NULL)\n        goto err;\n    if (!BN_copy(sdiv, divisor))\n        goto err;\n    norm_shift = bn_left_align(sdiv);\n    sdiv->neg = 0;\n    if (!(bn_lshift_fixed_top(snum, num, norm_shift)))\n        goto err;\n    div_n = sdiv->top;\n    num_n = snum->top;\n    if (num_n <= div_n) {\n        if (bn_wexpand(snum, div_n + 1) == NULL)\n            goto err;\n        memset(&(snum->d[num_n]), 0, (div_n - num_n + 1) * sizeof(BN_ULONG));\n        snum->top = num_n = div_n + 1;\n    }\n    loop = num_n - div_n;\n    wnum = &(snum->d[loop]);\n    wnumtop = &(snum->d[num_n - 1]);\n    d0 = sdiv->d[div_n - 1];\n    d1 = (div_n == 1) ? 0 : sdiv->d[div_n - 2];\n    if (!bn_wexpand(res, loop))\n        goto err;\n    res->neg = (num->neg ^ divisor->neg);\n    res->top = loop;\n    res->flags |= BN_FLG_FIXED_TOP;\n    resp = &(res->d[loop]);\n    if (!bn_wexpand(tmp, (div_n + 1)))\n        goto err;\n    for (i = 0; i < loop; i++, wnumtop--) {\n        BN_ULONG q, l0;\n# if defined(BN_DIV3W)\n        q = bn_div_3_words(wnumtop, d1, d0);\n# else\n        BN_ULONG n0, n1, rem = 0;\n        n0 = wnumtop[0];\n        n1 = wnumtop[-1];\n        if (n0 == d0)\n            q = BN_MASK2;\n        else {\n            BN_ULONG n2 = (wnumtop == wnum) ? 0 : wnumtop[-2];\n#  ifdef BN_LLONG\n            BN_ULLONG t2;\n#   if defined(BN_LLONG) && defined(BN_DIV2W) && !defined(bn_div_words)\n            q = (BN_ULONG)(((((BN_ULLONG) n0) << BN_BITS2) | n1) / d0);\n#   else\n            q = bn_div_words(n0, n1, d0);\n#   endif\n#   ifndef REMAINDER_IS_ALREADY_CALCULATED\n            rem = (n1 - q * d0) & BN_MASK2;\n#   endif\n            t2 = (BN_ULLONG) d1 *q;\n            for (;;) {\n                if (t2 <= ((((BN_ULLONG) rem) << BN_BITS2) | n2))\n                    break;\n                q--;\n                rem += d0;\n                if (rem < d0)\n                    break;\n                t2 -= d1;\n            }\n#  else\n            BN_ULONG t2l, t2h;\n            q = bn_div_words(n0, n1, d0);\n#   ifndef REMAINDER_IS_ALREADY_CALCULATED\n            rem = (n1 - q * d0) & BN_MASK2;\n#   endif\n#   if defined(BN_UMULT_LOHI)\n            BN_UMULT_LOHI(t2l, t2h, d1, q);\n#   elif defined(BN_UMULT_HIGH)\n            t2l = d1 * q;\n            t2h = BN_UMULT_HIGH(d1, q);\n#   else\n            {\n                BN_ULONG ql, qh;\n                t2l = LBITS(d1);\n                t2h = HBITS(d1);\n                ql = LBITS(q);\n                qh = HBITS(q);\n                mul64(t2l, t2h, ql, qh);\n            }\n#   endif\n            for (;;) {\n                if ((t2h < rem) || ((t2h == rem) && (t2l <= n2)))\n                    break;\n                q--;\n                rem += d0;\n                if (rem < d0)\n                    break;\n                if (t2l < d1)\n                    t2h--;\n                t2l -= d1;\n            }\n#  endif\n        }\n# endif\n        l0 = bn_mul_words(tmp->d, sdiv->d, div_n, q);\n        tmp->d[div_n] = l0;\n        wnum--;\n        l0 = bn_sub_words(wnum, wnum, tmp->d, div_n + 1);\n        q -= l0;\n        for (l0 = 0 - l0, j = 0; j < div_n; j++)\n            tmp->d[j] = sdiv->d[j] & l0;\n        l0 = bn_add_words(wnum, wnum, tmp->d, div_n);\n        (*wnumtop) += l0;\n        assert((*wnumtop) == 0);\n        *--resp = q;\n    }\n    snum->neg = num->neg;\n    snum->top = div_n;\n    snum->flags |= BN_FLG_FIXED_TOP;\n    if (rm != NULL)\n        bn_rshift_fixed_top(rm, snum, norm_shift);\n    BN_CTX_end(ctx);\n    return 1;\n err:\n    bn_check_top(rm);\n    BN_CTX_end(ctx);\n    return 0;\n}', 'void bn_correct_top(BIGNUM *a)\n{\n    BN_ULONG *ftl;\n    int tmp_top = a->top;\n    if (tmp_top > 0) {\n        for (ftl = &(a->d[tmp_top]); tmp_top > 0; tmp_top--) {\n            ftl--;\n            if (*ftl != 0)\n                break;\n        }\n        a->top = tmp_top;\n    }\n    if (a->top == 0)\n        a->neg = 0;\n    a->flags &= ~BN_FLG_FIXED_TOP;\n    bn_pollute(a);\n}']