UB in tests: Invalid pointer comparison in secp256k1_fe_inv_all_var #873

issue practicalswift openend this issue on January 21, 2021
  1. practicalswift commented at 10:05 am on January 21, 2021: contributor

    Is this VERIFY_CHECK pointer comparison in secp256k1_fe_inv_all_var defined when r and a are pointing to different objects?

    https://github.com/bitcoin-core/secp256k1/blob/98dac87839838b86094f1bccc71cc20e67b146cc/src/field_impl.h#L266-L273

    Nothing high priority of course, but perhaps worth fixing? :)

    This pointer comparison was introduced as part of PR #16 (“Implement batch inversion of field elements”) in f16be77ffc71ff2fdb2da5d66ecc48676c673db7 back in 2014.

  2. real-or-random renamed this:
    Potential UB: Invalid pointer comparison in secp256k1_fe_inv_all_var?
    UB in tests: Invalid pointer comparison in secp256k1_fe_inv_all_var
    on Jan 21, 2021
  3. real-or-random commented at 10:34 am on January 21, 2021: contributor

    Is this VERIFY_CHECK pointer comparison in secp256k1_fe_inv_all_var defined when r and a are pointing to different objects?

    No. Thanks for reporting.

    Note that VERIFY_CHECKs are only active in the tests.

    Are you willing to open a PR? I think the right thing to check is r != a.

  4. real-or-random commented at 10:43 am on January 21, 2021: contributor

    Are you willing to open a PR? I think the right thing to check is r != a.

    Well ok, not really. We can check r != a but what the check was supposed to do is to check that the arrays are not overlapping. I believe we should add a comment to the function that states this requirement. It’s not clear to me how to check this property in C (unless maybe with two loops and != checks), so I think we should just not check it.

  5. gmaxwell commented at 4:15 pm on January 22, 2021: contributor
    The non-overlapping status of the arrays is an important part of the interface.
  6. sipa commented at 5:16 pm on January 22, 2021: contributor

    So after reading a bit on cppreference.com (which also has pages about C), I believe:

    • == and != on between unrelated pointers is implementation defined
    • < <= > >= between unrelated pointers is UB.
    • casting from pointer to a sufficiently large integer type is implementation defined, but reversible (casting the integer back to the original pointer type gives a pointer to the original object)

    I believe that means that overlap can be checked by casting to intptr_t and doing the check we do now. It would rely on the assumption that subsequent array elements correspond to subsequent intptr_t values, which I expect to be universal, and even if not, wouldn’t be UB.

  7. gmaxwell commented at 6:23 pm on January 22, 2021: contributor

    subsequent intptr_t values, which I expect to be universal,

    It’s not necessarily true on platforms with segmented memory e.g. real-mode 16-bit dos. But I don’t think that’s a problem, because this is just a verify check. It’s probably also not true for some bizarre environments like the compcert formalism for C. But again, no problem there.

    If there were come libsecp256k1 porting guide it might deserve a line in it.

  8. real-or-random commented at 9:36 pm on January 22, 2021: contributor

    I believe that means that overlap can be checked by casting to intptr_t and doing the check we do now. It would rely on the assumption that subsequent array elements correspond to subsequent intptr_t values, which I expect to be universal, and even if not, wouldn’t be UB.

    Ugh, yeah, I guess we can do this. I didn’t expect that a pointer-to-int cast will ever “solve” a problem.

    By the way, I usually look stuff up in the standard directly: https://port70.net/~nsz/c/c89/c89-draft.html#3.3.8

    subsequent intptr_t values, which I expect to be universal,

    It’s not necessarily true on platforms with segmented memory e.g. real-mode 16-bit dos. But I don’t think that’s a problem, because this is just a verify check. It’s probably also not true for some bizarre environments like the compcert formalism for C. But again, no problem there.

    If there were come libsecp256k1 porting guide it might deserve a line in it.

    Well, the current behavior isn’t universal either. I guess we should add a comment to the line, and if we want we can also add a comment to assumptions.h. This is the closest thing to a porting guide that we currently have.

  9. real-or-random commented at 9:52 am on January 23, 2021: contributor
    Here’s a simpler solution: Remove the function, it’s currently unused. Was this function intended for ECDSA batch verification?
  10. gmaxwell commented at 5:08 pm on January 23, 2021: contributor

    It’s for building the verify context, but its functionality was inlined into its parent function ( secp256k1_ge_set_all_gej_var ) to reduce the usage of scratch space in #553.

    I agree, it should probably just be removed.

  11. sipa commented at 6:21 pm on January 23, 2021: contributor
    Haha, let’s just remove it then.
  12. sipa cross-referenced this on Jan 24, 2021 from issue Remove unused secp256k1_fe_inv_all_var by sipa
  13. sipa commented at 4:19 am on January 24, 2021: contributor
    See #878.
  14. jonasnick closed this on Jan 25, 2021


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-11-23 00:15 UTC

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