Fix various things -fsanitize complains about #9512

pull sipa wants to merge 6 commits into bitcoin:master from sipa:sanitize changing 6 files +49 −25
  1. sipa commented at 11:17 pm on January 10, 2017: member
    • The ReadLE32 etc functions in crypto/common.h where dereferencing type-punned pointers, which is undefined behaviour (and can cause consistent failure on some platforms due to misaligned reads). Fix this by memcpy()ing into a local variable first (as accessing a type’s representation through a char* is always allowed).
    • The scriptnum tests were testing running several arithmetic operations on large integers, triggering signed integer overflow, which is undefined. Fix the tests by using integers limited to +/- 2^40 (larger than anything actually supported in script).
    • Fix a memory leak in the wallet tests: CWalletTx objects that weren’t freed - wrap them in a unique_ptr.
    • Fix a memory leak in the net tests: a CNode object wasn’t being freed - wrap them in a unique_ptr.
    • Fix a memory leak in the rpc auth: a buffer that wasn’t being freed - switch it to a stack-allocated array.
    • The REST code for getutxos was using boost::dynamic_bitset, which apparently issues a rightshift by a negative amount. Fix this by replacing it with normal bit/byte vectors.

    Now all unit tests and rpc tests run succesfully with -fsanitize=address -fsanitize=undefined -fsanitize=leak in GCC 6.2.0.

    Thanks to @kcc for pointing me to these tools.

  2. fanquake added the label Refactoring on Jan 10, 2017
  3. in src/test/scriptnum_tests.cpp: in 4fde6a8b8b outdated
    12@@ -13,7 +13,7 @@
    13 BOOST_FIXTURE_TEST_SUITE(scriptnum_tests, BasicTestingSetup)
    14 
    15 static const int64_t values[] = \
    16-{ 0, 1, CHAR_MIN, CHAR_MAX, UCHAR_MAX, SHRT_MIN, USHRT_MAX, INT_MIN, INT_MAX, UINT_MAX, LONG_MIN, LONG_MAX };
    17+{ 0, 1, CHAR_MIN, CHAR_MAX, UCHAR_MAX, SHRT_MIN, USHRT_MAX, INT_MIN, INT_MAX, UINT_MAX, (1LL << 40), (1LL << 40) - 1, -(1LL << 40), 1 - (1LL << 40)};
    


    dcousens commented at 0:17 am on January 11, 2017:
    maybe define these constants ourselves rather than inlining them?

    laanwj commented at 12:49 pm on January 11, 2017:
    What is the problem that sanitize reports here? I don’t understand the rationale for using “40” here.

    sipa commented at 5:05 pm on January 11, 2017:
    I’ve just replaced them with integer constants and added a comment.

    sipa commented at 5:07 pm on January 11, 2017:
    Overflow of signed integers is undefined behaviour. These numbers are added/subtracted from eachother, so that behaviour triggers. However, it doesn’t matter in practice, as we only use scriptnums up to 4 bytes (which can turn into 5 bytes after arithmetic).
  4. dcousens approved
  5. in src/crypto/common.h: in 4fde6a8b8b outdated
    30 }
    31 
    32 uint64_t static inline ReadLE64(const unsigned char* ptr)
    33 {
    34-    return le64toh(*((uint64_t*)ptr));
    35+    return ((uint64_t)(ptr[0])) |
    


    laanwj commented at 12:47 pm on January 11, 2017:
    Interesting. This would also have failed on CPUs that don’t support non-aligned reads (though I know of no such instances reported).

    sipa commented at 5:05 pm on January 11, 2017:
    Seems ARM supports unaligned reads pretty much since the architecture we support.
  6. sipa force-pushed on Jan 11, 2017
  7. sipa commented at 6:19 pm on January 11, 2017: member
    I measure a 1.5% slowdown from these changes for the SHA256_32b benchmark (i7-6820HQ CPU @ 2.70GHz).
  8. in src/crypto/common.h: in c6400a5ff5 outdated
    44 
    45 void static inline WriteLE16(unsigned char* ptr, uint16_t x)
    46 {
    47-    *((uint16_t*)ptr) = htole16(x);
    48+    ptr[0] = x & 0xFF;
    49+    ptr[1] = (x >> 8) & 0xFF;
    


    JeremyRubin commented at 8:11 pm on January 11, 2017:
    I think the & 0xFF is redundant here, no? Unless you think there is some pipelining advantage…
  9. in src/crypto/common.h: in c6400a5ff5 outdated
    53 {
    54-    *((uint32_t*)ptr) = htole32(x);
    55+    ptr[0] = x & 0xFF;
    56+    ptr[1] = (x >> 8) & 0xFF;
    57+    ptr[2] = (x >> 16) & 0xFF;
    58+    ptr[3] = (x >> 24) & 0xFF;
    


    JeremyRubin commented at 8:12 pm on January 11, 2017:
    I think the & 0xFF is redundant here, no? Unless you think there is some pipelining advantage…
  10. in src/crypto/common.h: in c6400a5ff5 outdated
    66+    ptr[2] = (x >> 16) & 0xFF;
    67+    ptr[3] = (x >> 24) & 0xFF;
    68+    ptr[4] = (x >> 32) & 0xFF;
    69+    ptr[5] = (x >> 40) & 0xFF;
    70+    ptr[6] = (x >> 48) & 0xFF;
    71+    ptr[7] = (x >> 56) & 0xFF;
    


    JeremyRubin commented at 8:13 pm on January 11, 2017:
    I think the & 0xFF is redundant here, no? Unless you think there is some pipelining advantage…
  11. in src/crypto/common.h: in c6400a5ff5 outdated
    94 }
    95 
    96 void static inline WriteBE32(unsigned char* ptr, uint32_t x)
    97 {
    98-    *((uint32_t*)ptr) = htobe32(x);
    99+    ptr[0] = (x >> 24) & 0xFF;
    


    JeremyRubin commented at 8:14 pm on January 11, 2017:
    I think the & 0xFF is redundant here, no? Unless you think there is some pipelining advantage…
  12. in src/crypto/common.h: in c6400a5ff5 outdated
    103 }
    104 
    105 void static inline WriteBE64(unsigned char* ptr, uint64_t x)
    106 {
    107-    *((uint64_t*)ptr) = htobe64(x);
    108+    ptr[0] = (x >> 56) & 0xFF;
    


    JeremyRubin commented at 8:15 pm on January 11, 2017:
    I think the & 0xFF is redundant here, no? Unless you think there is some pipelining advantage…
  13. JeremyRubin approved
  14. JeremyRubin commented at 8:18 pm on January 11, 2017: contributor

    utACK.

    It seems there are some extra bitmasks in the write procedures; I’ve marked where they are. Maybe the optimized missed these and that’s your 1.5% ;)

  15. gmaxwell commented at 10:09 pm on January 11, 2017: contributor
    @sipa it’s frustrating that the compiler doesn’t recognize that pattern and peephole optimize it on platforms that support unaligned reads. At the same time, we really should be using platform optimized SIMD sha256 on our primary platforms, so the performance of this code won’t matter once we do.
  16. laanwj commented at 10:50 am on January 12, 2017: member

    Specifying &0xff for an unsigned char operation will just be ignored by the compiler (this is a no-brainer optimization). I doubt that is the cause of the slowdown.

    I wonder, isn’t there some compiler intrinsic for “non-aligned read of larger type” that could be detected by autoconf and used if available?

  17. sipa force-pushed on Jan 12, 2017
  18. Avoid unaligned access in crypto i/o 843c560003
  19. Avoid integer overflows in scriptnum tests f94f3e0df8
  20. Fix memory leak in wallet tests 6b03bfb840
  21. Fix memory leak in net_tests 5a0b7e4106
  22. Fix memory leak in multiUserAuthorized 99f001eb52
  23. Avoid boost dynamic_bitset in rest_getutxos 82e8baab3c
  24. sipa force-pushed on Jan 12, 2017
  25. sipa commented at 8:32 pm on January 12, 2017: member

    Updated to use a different approach to avoiding unaligned access, which seems as fast as master for the SHA256_32b benchmark (or even faster, I consistently across different runs see a minimum duration speedup of 0.02-0.025%).

    I’ve also added a commit to remove the use of boost::dynamic_bitset (which ubsan complains about, though I can’t see exactly how or why).

    Now all unit tests and rpc tests run succesfully with -fsanitize=address -fsanitize=undefined -fsanitize=leak in GCC 6.2.0.

  26. jtimon commented at 1:14 am on January 13, 2017: contributor

    utACK individual commits: 5a0b7e4106bc97a7a67bda6bf6fbd7f26d892420 99f001eb52dda703bd326833430054b108de35a1

    Note: I will edit this post as I go, the list with 2 will hopefully grow, maybe up to 6

  27. gmaxwell commented at 6:22 am on January 13, 2017: contributor
    utACK.
  28. gmaxwell commented at 2:28 pm on January 17, 2017: contributor
    ACK.
  29. laanwj commented at 2:31 pm on January 17, 2017: member
    utACK 82e8baa
  30. laanwj merged this on Jan 18, 2017
  31. laanwj closed this on Jan 18, 2017

  32. laanwj referenced this in commit 6012967c47 on Jan 18, 2017
  33. codablock referenced this in commit e97839722d on Jan 19, 2018
  34. codablock referenced this in commit b0d5b63f64 on Jan 20, 2018
  35. codablock referenced this in commit 197fbea84b on Jan 21, 2018
  36. zkbot referenced this in commit 10517df5c6 on Apr 19, 2018
  37. zkbot referenced this in commit 0e65c245f7 on Apr 21, 2018
  38. andvgal referenced this in commit 3833126870 on Jan 6, 2019
  39. CryptoCentric referenced this in commit e11d1ae195 on Feb 27, 2019
  40. furszy referenced this in commit 99f478be04 on Mar 1, 2021
  41. MarcoFalke locked this on Sep 8, 2021

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: 2024-11-17 15:12 UTC

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