-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add ARG_CHECKs to ensure "array of pointers" elements are non-NULL #1779
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ARG_CHECKs to ensure "array of pointers" elements are non-NULL #1779
Conversation
|
Cool, the review paid off so fast :). Would be good to add test coverage for it. |
real-or-random
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept ACK
|
Added |
real-or-random
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utACK 8bcda18
|
utACK 8bcda18 |
furszy
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we have to perform these three checks in many places:
- Pointer to array is not null.
- Provided number of elements in the array is greater than zero.
- 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.
|
utACK 8bcda18 I like the macro idea, but I'd make the non-empty part explicit, like |
w0xlt
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me.
ACK 8bcda18
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.) |
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_combineverifies that the individual pointer elements in the array are non-NULL each:secp256k1/src/secp256k1.c
Lines 774 to 775 in e7f7083
This PR adds corresponding
ARG_CHECKSfor 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_ILLEGALtests if there is conceptual support for this PR.