util: Fix `ReadBinaryFile` reading beyond maxsize #24371

pull klementtan wants to merge 1 commits into bitcoin:master from klementtan:fix-readwritefile changing 2 files +50 −3
  1. klementtan commented at 3:38 PM on February 17, 2022: contributor

    Currently ReadBinaryFile will read beyond maxsize if maxsize is not a multiple of 128 (size of buffer)

    This is due to fread being called with count = 128 instead of count = min(128, maxsize - retval.size() at every iteration

    The following unit test will fail:

    BOOST_AUTO_TEST_CASE(util_ReadWriteFile)
    {
      fs::path tmpfolder = m_args.GetDataDirBase();
      fs::path tmpfile = tmpfolder / "read_binary.dat";
      std::string expected_text(300,'c');
      {
          std::ofstream file{tmpfile};
          file << expected_text;
      }
      {
          // read half the contents in file
          auto [valid, text] = ReadBinaryFile(tmpfile, expected_text.size() / 2);
          BOOST_CHECK_EQUAL(text.size(), 150);
      }
    }
    

    Error:

    test/util_tests.cpp:2593: error: in "util_tests/util_ReadWriteFile": check text.size() == 150 has failed [256 != 150]
    
  2. klementtan renamed this:
    util: Fix `ReadBinaryFile` beyond maxsize
    util: Fix `ReadBinaryFile` reading beyond maxsize
    on Feb 17, 2022
  3. DrahtBot added the label Utils/log/libs on Feb 17, 2022
  4. MarcoFalke commented at 4:27 PM on February 17, 2022: member

    Looks like your patch causes a "global buffer overflow" in the ASan CI task

  5. luke-jr commented at 12:45 AM on February 19, 2022: member

    Concept ACK.

    Is there a reason we don't read directly into the std::string?

  6. klementtan force-pushed on Feb 19, 2022
  7. klementtan force-pushed on Feb 19, 2022
  8. util: Fix ReadBinaryFile reading beyond maxsize a84650ebd5
  9. klementtan force-pushed on Feb 19, 2022
  10. klementtan commented at 11:31 AM on February 19, 2022: contributor

    Is there a reason we don't read directly into the std::string? @luke-jr If I am not wrong, it is not advisable to fread into std::string as c_str() is const and we will also need to know the size of the file beforehand to allocate the right number of characters. More Details

    Looks like your patch causes a "global buffer overflow" in the ASan CI task @MarcoFalke fixed the ASan issue in the unit test.

  11. luke-jr commented at 4:10 PM on February 19, 2022: member

    If I am not wrong, it is not advisable to fread into std::string as c_str() is const

    I would expect to use .begin(), not .c_str()

    and we will also need to know the size of the file beforehand to allocate the right number of characters.

    I would be surprised if repeatedly calling .resize was slower than repeatedly calling .append.

  12. theStack commented at 6:19 PM on February 20, 2022: member

    Concept ACK

  13. klementtan commented at 1:04 PM on February 21, 2022: contributor

    I would expect to use .begin(), not .c_str() @luke-jr I am not sure how to do that. From what I understand fread takes in void * but .begin() returns an iterator. Do you have an example of how I can change it to use .begin()?

  14. theStack approved
  15. theStack commented at 12:08 AM on February 22, 2022: member

    Code-review ACK a84650ebd5ac2cbb49f14eb7c98736a3f8215bf1

  16. luke-jr commented at 11:43 PM on February 22, 2022: member

    @luke-jr I am not sure how to do that.

    Let's consider it out of scope for this PR and stick to a simpler fix. :)

  17. laanwj commented at 11:34 AM on March 9, 2022: member

    Code review ACK a84650ebd5ac2cbb49f14eb7c98736a3f8215bf1

    @luke-jr If I am not wrong, it is not advisable to fread into std::string as c_str() is const and we will also need to know the size of the file beforehand to allocate the right number of characters.

    I would really discourage such hacks if not absolutely required. ReadBinaryFile is not used in any performance critical contexts, and it's only used to read like 64 bytes maximum, so please go with a simple and straightforward solution even if not the fastest.

    Edit: and thinking of it, conceptually std::string is the wrong type for a binary blob. Something like std::vector<byte> would be better. In any case, out of scope.

  18. luke-jr approved
  19. luke-jr commented at 5:29 AM on March 10, 2022: member

    utACK

  20. MarcoFalke merged this on Mar 10, 2022
  21. MarcoFalke closed this on Mar 10, 2022

  22. klementtan deleted the branch on Mar 10, 2022
  23. sidhujag referenced this in commit 9767a6f02a on Mar 11, 2022
  24. DrahtBot locked this on Mar 10, 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-13 15:14 UTC

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