Skip to content

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

@niooss-ledger

Description

@niooss-ledger

Hello,

In the tests, function test_ecmult_accumulate calls secp256k1_ecmult_multi_var with error_callback = NULL (since version 0.2.0, PR #920):

secp256k1/src/tests.c

Lines 5497 to 5498 in 7712a53

secp256k1_ecmult_multi_var(NULL, scratch, &rj4, x, NULL, NULL, 0);
secp256k1_ecmult_multi_var(NULL, scratch, &rj5, &secp256k1_scalar_zero, test_ecmult_accumulate_cb, (void*)x, 1);

This function eventually calls secp256k1_scratch_max_allocation:

static size_t secp256k1_scratch_max_allocation(const secp256k1_callback* error_callback, const secp256k1_scratch* scratch, size_t objects) {
if (secp256k1_memcmp_var(scratch->magic, "scratch", 8) != 0) {
secp256k1_callback_call(error_callback, "invalid scratch space");

... which directly dereferences the callback parameter:

secp256k1/src/util.h

Lines 86 to 87 in 7712a53

static SECP256K1_INLINE void secp256k1_callback_call(const secp256k1_callback * const cb, const char * const text) {
cb->fn(text, (void*)cb->data);

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:

diff --git a/src/tests.c b/src/tests.c
index 2eb3fbfdcea7..dab47608c2e5 100644
--- a/src/tests.c
+++ b/src/tests.c
@@ -5494,8 +5494,8 @@ static void test_ecmult_accumulate(secp256k1_sha256* acc, const secp256k1_scalar
     secp256k1_ecmult_gen(&CTX->ecmult_gen_ctx, &rj1, x);
     secp256k1_ecmult(&rj2, &gj, x, &secp256k1_scalar_zero);
     secp256k1_ecmult(&rj3, &infj, &secp256k1_scalar_zero, x);
-    secp256k1_ecmult_multi_var(NULL, scratch, &rj4, x, NULL, NULL, 0);
-    secp256k1_ecmult_multi_var(NULL, scratch, &rj5, &secp256k1_scalar_zero, test_ecmult_accumulate_cb, (void*)x, 1);
+    CHECK(secp256k1_ecmult_multi_var(&CTX->error_callback, scratch, &rj4, x, NULL, NULL, 0));
+    CHECK(secp256k1_ecmult_multi_var(&CTX->error_callback, scratch, &rj5, &secp256k1_scalar_zero, test_ecmult_accumulate_cb, (void*)x, 1));
     secp256k1_ecmult_const(&rj6, &secp256k1_ge_const_g, x);
     secp256k1_ge_set_gej_var(&r, &rj1);
     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?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions