tests: secp256k1_ecmult_multi_var is called with a NULL error callback #1527

issue niooss-ledger openend this issue on May 8, 2024
  1. niooss-ledger commented at 4:16 pm on May 8, 2024: contributor

    Hello,

    In the tests, function test_ecmult_accumulate calls secp256k1_ecmult_multi_var with error_callback = NULL (since version 0.2.0, PR #920): https://github.com/bitcoin-core/secp256k1/blob/7712a53061b1e36ecf47a3a46ea1e67ef31904d9/src/tests.c#L5497-L5498

    This function eventually calls secp256k1_scratch_max_allocation: https://github.com/bitcoin-core/secp256k1/blob/7712a53061b1e36ecf47a3a46ea1e67ef31904d9/src/scratch_impl.h#L58-L60

    … which directly dereferences the callback parameter: https://github.com/bitcoin-core/secp256k1/blob/7712a53061b1e36ecf47a3a46ea1e67ef31904d9/src/util.h#L86-L87

    In short, it seems secp256k1_ecmult_multi_var does not expect error_callback to be NULL.

    The consequence of test_ecmult_accumulate not following this expectation would be a possible crash (by null pointer dereference) if something ever go wrong in the test. While this bug does not directly impact secp256k1 library (it occurs in the test suite), I believe this issue should be fixed because I think tests should follow the calling convention of the library functions (such as not passing NULL where functions expects non-NULL parameters).

    Moreover, CHECK() could probably be added to verify the result of secp256k1_ecmult_multi_var. Therefore, I am suggesting this change:

     0diff --git a/src/tests.c b/src/tests.c
     1index 2eb3fbfdcea7..dab47608c2e5 100644
     2--- a/src/tests.c
     3+++ b/src/tests.c
     4@@ -5494,8 +5494,8 @@ static void test_ecmult_accumulate(secp256k1_sha256* acc, const secp256k1_scalar
     5     secp256k1_ecmult_gen(&CTX->ecmult_gen_ctx, &rj1, x);
     6     secp256k1_ecmult(&rj2, &gj, x, &secp256k1_scalar_zero);
     7     secp256k1_ecmult(&rj3, &infj, &secp256k1_scalar_zero, x);
     8-    secp256k1_ecmult_multi_var(NULL, scratch, &rj4, x, NULL, NULL, 0);
     9-    secp256k1_ecmult_multi_var(NULL, scratch, &rj5, &secp256k1_scalar_zero, test_ecmult_accumulate_cb, (void*)x, 1);
    10+    CHECK(secp256k1_ecmult_multi_var(&CTX->error_callback, scratch, &rj4, x, NULL, NULL, 0));
    11+    CHECK(secp256k1_ecmult_multi_var(&CTX->error_callback, scratch, &rj5, &secp256k1_scalar_zero, test_ecmult_accumulate_cb, (void*)x, 1));
    12     secp256k1_ecmult_const(&rj6, &secp256k1_ge_const_g, x);
    13     secp256k1_ge_set_gej_var(&r, &rj1);
    14     CHECK(secp256k1_gej_eq_ge_var(&rj2, &r));
    

    Would such a change be acceptable? (If yes, I can submit a pull request)

    Moreover, should some attributes SECP256K1_ARG_NONNULL be added to functions expecting non-NULL error_callback too?

  2. real-or-random commented at 4:59 pm on May 8, 2024: contributor

    Thanks, I agree with the analysis. Note that secp256k1_ecmult_multi_var (and the entire scratch space machinery) is currently unused. It was added for future performance improvements such as batch verification.

    Can I ask you how you found this? Simply by eyeballing or using some (semi-)automated analysis?

    Would such a change be acceptable? (If yes, I can submit a pull request)

    Yes. (Yes!)

    Moreover, should some attributes SECP256K1_ARG_NONNULL be added to functions expecting non-NULL error_callback too?

    Hm, I don’t think so. I mean, it’s not wrong to do this, but our convention so far is that SECP256K1_ARG_NONNULL is only used for arguments of public API functions. You could, however, add VERIFY_CHECK(error_callback != NULL) inside the affected functions instead.

  3. real-or-random added the label bug on May 8, 2024
  4. real-or-random added the label assurance on May 8, 2024
  5. niooss-ledger referenced this in commit 9554362b15 on May 8, 2024
  6. niooss-ledger commented at 5:24 pm on May 8, 2024: contributor

    Thanks for your quick reply :)

    Can I ask you how you found this? Simply by eyeballing or using some (semi-)automated analysis?

    I was running some static analysis tools against the latest release (0.5.0) and reviewed the findings from clang’s static analyzer (scan-build with many options, such as -enable-checker security -enable-checker unix). There were many false positives but it also reported Access to field 'fn' results in a dereference of a null pointer (loaded from variable 'cb'). I tried to understand whether this was an actual issue and analyzed this report more deeply, which led to this issue.

    Would such a change be acceptable? (If yes, I can submit a pull request)

    Yes. (Yes!)

    Ok, I created #1528

    Moreover, should some attributes SECP256K1_ARG_NONNULL be added to functions expecting non-NULL error_callback too?

    Hm, I don’t think so. I mean, it’s not wrong to do this, but our convention so far is that SECP256K1_ARG_NONNULL is only used for arguments of public API functions. You could, however, add VERIFY_CHECK(error_callback != NULL) inside the affected functions instead.

    All right. This makes sense and I will not add such VERIFY_CHECK invocations.

  7. real-or-random closed this on May 13, 2024

  8. real-or-random referenced this in commit 06bff6dec8 on May 13, 2024

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin-core/secp256k1. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-12-09 07:15 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me