Use of uninitialized memory when validating successfully deserialized CPubKey #19235

issue practicalswift opened this issue on June 10, 2020
  1. practicalswift commented at 11:27 AM on June 10, 2020: contributor

    Travis errors on #18912 (PR adding Valgrind checking) due to the following CPubKey deserialization issue. See Travis log for details.

    Issue:

    It is possible to successfully deserialize a public key (CPubKey) which when used -- such as checking for validity using IsFullyValid() -- leads to use of uninitialized memory (UUM):

    Example:

    const std::vector<uint8_t> serialized_pub_key{4, 4, 0, 0, 0};
    CDataStream data_stream{serialized_pub_key, SER_NETWORK, INIT_PROTO_VERSION};
    CPubKey pub_key;
    data_stream >> pub_key;
    if (pub_key.IsValid()) {
        (void)pub_key.IsFullyValid();
    }
    

    The example code leads to the following use of uninitialized memory (UUM) (in IsFullyValid()) ...

    ==6417== Conditional jump or move depends on uninitialised value(s)
    ==6417==    at 0x1077684: secp256k1_fe_set_b32 (field_5x52_impl.h:320)
    ==6417==    by 0x1056B82: secp256k1_eckey_pubkey_parse (eckey_impl.h:23)
    ==6417==    by 0x1056B82: secp256k1_ec_pubkey_parse (secp256k1.c:178)
    ==6417==    by 0xF4A6A3: CPubKey::IsFullyValid() const (pubkey.cpp:213)
    

    ... instead of the expected std::ios_base::failure when deserializing (on data_stream >> pub_key).


    Uses of uninitialized memory (UUM) is unfortunately a quite common type of bug, but luckily MemorySanitizer and Valgrind can help us guard against such issues entering our code base. Travis MSan checking and Valgrind checking is provided in the following two PRs which should be ready for merge pending final code review (they have multiple "Concept ACKs"):

    • #18288 -- "build: Add MemorySanitizer (MSan) in Travis to detect use of uninitialized memory"
    • #18912 -- "ci: Run fuzz testing test cases (bitcoin-core/qa-assets) under valgrind to catch memory errors"

    Hopefully uses of uninitialized memory will soon be a thing of the past when we have the proper UUM detection in place :)

  2. MarcoFalke added the label Bug on Jun 10, 2020
  3. MarcoFalke commented at 11:35 AM on June 10, 2020: member

    Does this still happen with #19228 ?

  4. practicalswift commented at 12:58 PM on June 10, 2020: contributor

    @MarcoFalke I would assume so: AFAICT the problem isn't in libsecp256k1 but in CPubKey::Unserialize. More specifically I think the problem is that CPubKey::Unserialize isn't throwing the expected serialization error: we wan't std::ios_base::failure to be thrown when deserializating an invalid object :)

    Or alternatively I guess Invalidate() could be called from CPubKey::Unserialize to invalidate the object. That would make GetLen(…) return a size of zero which avoids the issue.

  5. elichai commented at 1:30 PM on June 10, 2020: contributor

    CPubKey::Unserialize Doesn't validate anything (except a max size) https://github.com/bitcoin/bitcoin/blob/bc933aeaf04420218b46318e316ee5eaa772823c/src/pubkey.h#L144 And then when you call IsFullyValid() it will get the length via GetLen which will check the first byte and return a size accordingly, so in you example the first byte is 4 so it will return 65. https://github.com/bitcoin/bitcoin/blob/bc933aeaf04420218b46318e316ee5eaa772823c/src/pubkey.h#L57-L64.

    I believe one solution can be calling CPubKey::Set from CPubKey::Unserialize OR check after reading if(len != GetLen(vch[0])) Invalidate();

  6. MarcoFalke closed this on Jun 25, 2020

  7. sidhujag referenced this in commit 6b2e80699a on Jul 8, 2020
  8. DrahtBot locked this on Feb 15, 2022
  9. vijaydasmp referenced this in commit 1a3b81193e on Jan 9, 2023
  10. vijaydasmp referenced this in commit f2e880f59d on Jan 13, 2023
  11. vijaydasmp referenced this in commit 96da206fb7 on Jan 18, 2023
  12. vijaydasmp referenced this in commit a6df05a213 on Jan 19, 2023
  13. vijaydasmp referenced this in commit 80df60b06f on Feb 17, 2023
  14. vijaydasmp referenced this in commit 14515c4d64 on Feb 19, 2023
  15. vijaydasmp referenced this in commit 32db5985b3 on Feb 20, 2023
  16. vijaydasmp referenced this in commit 87985b33d4 on Feb 20, 2023
  17. vijaydasmp referenced this in commit b47879e44d on Feb 24, 2023
  18. vijaydasmp referenced this in commit 2f0e5a61ac on Mar 5, 2023
  19. vijaydasmp referenced this in commit 132e267b89 on Mar 10, 2023
  20. vijaydasmp referenced this in commit 407a91e007 on Mar 13, 2023
  21. vijaydasmp referenced this in commit db8923d543 on Mar 14, 2023
  22. PastaPastaPasta referenced this in commit 00a277f981 on Apr 15, 2023
  23. PastaPastaPasta referenced this in commit 22e7ad4d0e on Apr 15, 2023

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-15 00:14 UTC

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