Add ARG_CHECKs to ensure "array of pointers" elements are non-NULL #1779

pull theStack wants to merge 2 commits into bitcoin-core:master from theStack:ARG_CHECK-array-of-pointers-elements-non-NULL changing 5 files +54 −0
  1. theStack commented at 1:05 AM on December 6, 2025: contributor

    We currently have five public API functions that take an "array of pointers" as input parameter:

    • secp256k1_ec_pubkey_combine (ins: array of pointers to public keys to add)
    • secp256k1_ec_pubkey_sort (pubkeys: array of pointers to public keys to sort)
    • secp256k1_musig_pubkey_agg (pubkeys: array of pointers to public keys to aggregate)
    • secp256k1_musig_nonce_agg (pubnonces: array of pointers to public nonces to aggregate)
    • secp256k1_musig_partial_sig_agg (partial_sigs: array of pointers to partial signatures to aggregate)

    Out of these, only _ec_pubkey_combine verifies that the individual pointer elements in the array are non-NULL each: https://github.com/bitcoin-core/secp256k1/blob/e7f7083b530a55c83ce9089a7244d2d9d67ac8b2/src/secp256k1.c#L774-L775

    This PR adds corresponding ARG_CHECKS for the other API functions as well, in order to avoid running into potential UB due to NULL pointer dereference. It seems to me that the tiny run-time overhead is worth it doing this for consistency and to help users in case the arrays are set up incorrectly (I'm thinking e.g. of language binding writers where getting this right might be a bit more involved).

    Looking into this was motivated by a review of furszy (thanks!), who pointed out that the non-NULL checks are missing in at least one API function in the silentpayments module PR as well. Happy to add some CHECK_ILLEGAL tests if there is conceptual support for this PR.

  2. Add ARG_CHECKs to ensure "array of pointers" elements are non-NULL 5a08c1bcdc
  3. furszy commented at 4:50 PM on December 6, 2025: member

    Cool, the review paid off so fast :). Would be good to add test coverage for it.

  4. in src/secp256k1.c:332 in 5a08c1bcdc outdated
     324 | @@ -325,8 +325,13 @@ static int secp256k1_ec_pubkey_sort_cmp(const void* pk1, const void* pk2, void *
     325 |  }
     326 |  
     327 |  int secp256k1_ec_pubkey_sort(const secp256k1_context* ctx, const secp256k1_pubkey **pubkeys, size_t n_pubkeys) {
     328 | +    size_t i;
     329 | +
     330 |      VERIFY_CHECK(ctx != NULL);
     331 |      ARG_CHECK(pubkeys != NULL);
     332 | +    for (i = 0; i < n_pubkeys; i++) {
    


    kevkevinpal commented at 4:40 AM on December 8, 2025:

    Does it make sense to check n_pubkeys is greater than 0?

        ARG_CHECK(n_pubkeys > 0);
        for (i = 0; i < n_pubkeys; i++) {
    

    real-or-random commented at 8:05 AM on December 8, 2025:

    I think it's okay to sort the empty array.

  5. real-or-random commented at 8:05 AM on December 8, 2025: contributor

    Concept ACK

  6. real-or-random added the label tweak/refactor on Dec 8, 2025
  7. real-or-random added the label assurance on Dec 8, 2025
  8. test: Add non-NULL checks for "pointer of array" API functions 8bcda186d2
  9. theStack commented at 12:49 AM on December 9, 2025: contributor

    Added CHECK_ILLEGAL tests to ensure NULL pointers in "array of pointer" arguments for the mentioned five functions are detected. They are placed right after (or at least as close to) successful executions with n_{pubkeys,pubnonces,sigs} >= 2 each and test with a single NULL pointer at each position.

  10. real-or-random approved
  11. real-or-random commented at 7:51 AM on December 9, 2025: contributor

    utACK 8bcda186d20e11ba9a04e6917928f062513b534f

  12. kevkevinpal commented at 1:12 PM on December 9, 2025: contributor

    utACK 8bcda18

  13. furszy commented at 4:31 PM on December 9, 2025: member

    As we have to perform these three checks in many places:

    1. Pointer to array is not null.
    2. Provided number of elements in the array is greater than zero.
    3. No element inside the array is null

    What about introducing a new macro?

    /* Check array of pointers is non-NULL, non-empty, and has no NULL entries */
    #define ARG_CHECK_ARRAY(arr, n) do {                                    \
            size_t _pos;                                                    \
            ARG_CHECK((arr) != NULL);                                       \
            ARG_CHECK((n) > 0);                                             \
            for (_pos = 0; _pos < (n); _pos++) {                            \
                ARG_CHECK((arr)[_pos] != NULL);                             \
            }                                                               \
    } while(0)
    

    Could also introduce one for when the array can be empty too.

  14. john-moffett commented at 7:18 PM on December 9, 2025: contributor

    utACK 8bcda186d20e11ba9a04e6917928f062513b534f

    I like the macro idea, but I'd make the non-empty part explicit, like ARG_CHECK_ARRAY_NONEMPTY or something.

  15. w0xlt approved
  16. w0xlt commented at 7:50 AM on December 10, 2025: contributor
  17. real-or-random commented at 8:24 AM on December 10, 2025: contributor

    What about introducing a new macro?

    Concept ~0: It's more DRY, and it will make it harder for people to forget one of the checks, e.g., that the members are non-NULL, in new code. On the other hand, I believe the code will be more difficult to read with a macro. Having the three checks explicitly is not super verbose, and noone will need to look up or remember the definition of the macro. (Note that we'd use the macro only in a handful of functions, so people may not recall the definiton.)

  18. real-or-random merged this on Dec 10, 2025
  19. real-or-random closed this on Dec 10, 2025

  20. theStack deleted the branch on Dec 10, 2025
  21. Eunovo referenced this in commit b065787ddb on Jan 19, 2026
  22. fanquake referenced this in commit c4c4e04ca1 on Jan 26, 2026
  23. fanquake referenced this in commit 2fccbea3c8 on Jan 27, 2026
  24. fjahr referenced this in commit 182197f98a on Jan 29, 2026
  25. fjahr referenced this in commit ea9a84ab3c on Jan 31, 2026
  26. fjahr referenced this in commit 23c2527f12 on Feb 8, 2026
  27. Sjors referenced this in commit d5660d3a13 on Feb 16, 2026
  28. mllwchrry referenced this in commit a736a778a6 on Feb 26, 2026
  29. github-actions[bot] referenced this in commit c3f80fff5f on Mar 1, 2026
  30. github-actions[bot] referenced this in commit 4aeff8400e on Mar 1, 2026
  31. github-actions[bot] referenced this in commit 5f15eb0c55 on Mar 1, 2026
  32. 0x000000000019d6689c085ae165831e934ff76 referenced this in commit d54574beca on Mar 2, 2026
  33. csjones referenced this in commit fb3e16af04 on Mar 2, 2026
  34. mllwchrry referenced this in commit 3b967e0e08 on Mar 2, 2026
  35. mllwchrry referenced this in commit d111d31293 on Mar 3, 2026
  36. real-or-random referenced this in commit 459eab20f2 on Mar 3, 2026
  37. vmta referenced this in commit 1ddc2f947f on Apr 26, 2026
  38. vmta referenced this in commit 56c40fe100 on Apr 27, 2026

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: 2026-05-19 06:52 UTC