Skip to content

Commit 6012967

Browse files
committed
Merge #9512: Fix various things -fsanitize complains about
82e8baa Avoid boost dynamic_bitset in rest_getutxos (Pieter Wuille) 99f001e Fix memory leak in multiUserAuthorized (Pieter Wuille) 5a0b7e4 Fix memory leak in net_tests (Pieter Wuille) 6b03bfb Fix memory leak in wallet tests (Pieter Wuille) f94f3e0 Avoid integer overflows in scriptnum tests (Pieter Wuille) 843c560 Avoid unaligned access in crypto i/o (Pieter Wuille)
2 parents b0b57a1 + 82e8baa commit 6012967

File tree

6 files changed

+49
-25
lines changed

6 files changed

+49
-25
lines changed

src/crypto/common.h

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,57 +10,73 @@
1010
#endif
1111

1212
#include <stdint.h>
13+
#include <string.h>
1314

1415
#include "compat/endian.h"
1516

1617
uint16_t static inline ReadLE16(const unsigned char* ptr)
1718
{
18-
return le16toh(*((uint16_t*)ptr));
19+
uint16_t x;
20+
memcpy((char*)&x, ptr, 2);
21+
return le16toh(x);
1922
}
2023

2124
uint32_t static inline ReadLE32(const unsigned char* ptr)
2225
{
23-
return le32toh(*((uint32_t*)ptr));
26+
uint32_t x;
27+
memcpy((char*)&x, ptr, 4);
28+
return le32toh(x);
2429
}
2530

2631
uint64_t static inline ReadLE64(const unsigned char* ptr)
2732
{
28-
return le64toh(*((uint64_t*)ptr));
33+
uint64_t x;
34+
memcpy((char*)&x, ptr, 8);
35+
return le64toh(x);
2936
}
3037

3138
void static inline WriteLE16(unsigned char* ptr, uint16_t x)
3239
{
33-
*((uint16_t*)ptr) = htole16(x);
40+
uint16_t v = htole16(x);
41+
memcpy(ptr, (char*)&v, 2);
3442
}
3543

3644
void static inline WriteLE32(unsigned char* ptr, uint32_t x)
3745
{
38-
*((uint32_t*)ptr) = htole32(x);
46+
uint32_t v = htole32(x);
47+
memcpy(ptr, (char*)&v, 4);
3948
}
4049

4150
void static inline WriteLE64(unsigned char* ptr, uint64_t x)
4251
{
43-
*((uint64_t*)ptr) = htole64(x);
52+
uint64_t v = htole64(x);
53+
memcpy(ptr, (char*)&v, 8);
4454
}
4555

4656
uint32_t static inline ReadBE32(const unsigned char* ptr)
4757
{
48-
return be32toh(*((uint32_t*)ptr));
58+
uint32_t x;
59+
memcpy((char*)&x, ptr, 4);
60+
return be32toh(x);
4961
}
5062

5163
uint64_t static inline ReadBE64(const unsigned char* ptr)
5264
{
53-
return be64toh(*((uint64_t*)ptr));
65+
uint64_t x;
66+
memcpy((char*)&x, ptr, 8);
67+
return be64toh(x);
5468
}
5569

5670
void static inline WriteBE32(unsigned char* ptr, uint32_t x)
5771
{
58-
*((uint32_t*)ptr) = htobe32(x);
72+
uint32_t v = htobe32(x);
73+
memcpy(ptr, (char*)&v, 4);
5974
}
6075

6176
void static inline WriteBE64(unsigned char* ptr, uint64_t x)
6277
{
63-
*((uint64_t*)ptr) = htobe64(x);
78+
uint64_t v = htobe64(x);
79+
memcpy(ptr, (char*)&v, 8);
6480
}
6581

6682
#endif // BITCOIN_CRYPTO_COMMON_H

src/httprpc.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@ static bool multiUserAuthorized(std::string strUserPass)
113113
std::string strHash = vFields[2];
114114

115115
unsigned int KEY_SIZE = 32;
116-
unsigned char *out = new unsigned char[KEY_SIZE];
117-
116+
unsigned char out[KEY_SIZE];
117+
118118
CHMAC_SHA256(reinterpret_cast<const unsigned char*>(strSalt.c_str()), strSalt.size()).Write(reinterpret_cast<const unsigned char*>(strPass.c_str()), strPass.size()).Finalize(out);
119119
std::vector<unsigned char> hexvec(out, out+KEY_SIZE);
120120
std::string strHashFromPass = HexStr(hexvec);

src/rest.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include "version.h"
1818

1919
#include <boost/algorithm/string.hpp>
20-
#include <boost/dynamic_bitset.hpp>
2120

2221
#include <univalue.h>
2322

@@ -502,7 +501,8 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
502501
vector<unsigned char> bitmap;
503502
vector<CCoin> outs;
504503
std::string bitmapStringRepresentation;
505-
boost::dynamic_bitset<unsigned char> hits(vOutPoints.size());
504+
std::vector<bool> hits;
505+
bitmap.resize((vOutPoints.size() + 7) / 8);
506506
{
507507
LOCK2(cs_main, mempool.cs);
508508

@@ -518,10 +518,11 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
518518
for (size_t i = 0; i < vOutPoints.size(); i++) {
519519
CCoins coins;
520520
uint256 hash = vOutPoints[i].hash;
521+
bool hit = false;
521522
if (view.GetCoins(hash, coins)) {
522523
mempool.pruneSpent(hash, coins);
523524
if (coins.IsAvailable(vOutPoints[i].n)) {
524-
hits[i] = true;
525+
hit = true;
525526
// Safe to index into vout here because IsAvailable checked if it's off the end of the array, or if
526527
// n is valid but points to an already spent output (IsNull).
527528
CCoin coin;
@@ -533,10 +534,11 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
533534
}
534535
}
535536

536-
bitmapStringRepresentation.append(hits[i] ? "1" : "0"); // form a binary string representation (human-readable for json output)
537+
hits.push_back(hit);
538+
bitmapStringRepresentation.append(hit ? "1" : "0"); // form a binary string representation (human-readable for json output)
539+
bitmap[i / 8] |= ((uint8_t)hit) << (i % 8);
537540
}
538541
}
539-
boost::to_block_range(hits, std::back_inserter(bitmap));
540542

541543
switch (rf) {
542544
case RF_BINARY: {

src/test/net_tests.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,12 +162,12 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test)
162162
bool fInboundIn = false;
163163

164164
// Test that fFeeler is false by default.
165-
CNode* pnode1 = new CNode(id++, NODE_NETWORK, height, hSocket, addr, 0, 0, pszDest, fInboundIn);
165+
std::unique_ptr<CNode> pnode1(new CNode(id++, NODE_NETWORK, height, hSocket, addr, 0, 0, pszDest, fInboundIn));
166166
BOOST_CHECK(pnode1->fInbound == false);
167167
BOOST_CHECK(pnode1->fFeeler == false);
168168

169169
fInboundIn = true;
170-
CNode* pnode2 = new CNode(id++, NODE_NETWORK, height, hSocket, addr, 1, 1, pszDest, fInboundIn);
170+
std::unique_ptr<CNode> pnode2(new CNode(id++, NODE_NETWORK, height, hSocket, addr, 1, 1, pszDest, fInboundIn));
171171
BOOST_CHECK(pnode2->fInbound == true);
172172
BOOST_CHECK(pnode2->fFeeler == false);
173173
}

src/test/scriptnum_tests.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212

1313
BOOST_FIXTURE_TEST_SUITE(scriptnum_tests, BasicTestingSetup)
1414

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 };
15+
/** A selection of numbers that do not trigger int64_t overflow
16+
* when added/subtracted. */
17+
static const int64_t values[] = { 0, 1, -2, 127, 128, -255, 256, (1LL << 15) - 1, -(1LL << 16), (1LL << 24) - 1, (1LL << 31), 1 - (1LL << 32), 1LL << 40 };
18+
1719
static const int64_t offsets[] = { 1, 0x79, 0x80, 0x81, 0xFF, 0x7FFF, 0x8000, 0xFFFF, 0x10000};
1820

1921
static bool verify(const CScriptNum10& bignum, const CScriptNum& scriptnum)

src/wallet/test/wallet_tests.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323

2424
using namespace std;
2525

26+
std::vector<std::unique_ptr<CWalletTx>> wtxn;
27+
2628
typedef set<pair<const CWalletTx*,unsigned int> > CoinSet;
2729

2830
BOOST_FIXTURE_TEST_SUITE(wallet_tests, WalletTestingSetup)
@@ -42,21 +44,21 @@ static void add_coin(const CAmount& nValue, int nAge = 6*24, bool fIsFromMe = fa
4244
// so stop vin being empty, and cache a non-zero Debit to fake out IsFromMe()
4345
tx.vin.resize(1);
4446
}
45-
CWalletTx* wtx = new CWalletTx(&wallet, MakeTransactionRef(std::move(tx)));
47+
std::unique_ptr<CWalletTx> wtx(new CWalletTx(&wallet, MakeTransactionRef(std::move(tx))));
4648
if (fIsFromMe)
4749
{
4850
wtx->fDebitCached = true;
4951
wtx->nDebitCached = 1;
5052
}
51-
COutput output(wtx, nInput, nAge, true, true);
53+
COutput output(wtx.get(), nInput, nAge, true, true);
5254
vCoins.push_back(output);
55+
wtxn.emplace_back(std::move(wtx));
5356
}
5457

5558
static void empty_wallet(void)
5659
{
57-
BOOST_FOREACH(COutput output, vCoins)
58-
delete output.tx;
5960
vCoins.clear();
61+
wtxn.clear();
6062
}
6163

6264
static bool equal_sets(CoinSet a, CoinSet b)
@@ -349,6 +351,8 @@ BOOST_AUTO_TEST_CASE(ApproximateBestSubset)
349351
BOOST_CHECK(wallet.SelectCoinsMinConf(1003 * COIN, 1, 6, 0, vCoins, setCoinsRet, nValueRet));
350352
BOOST_CHECK_EQUAL(nValueRet, 1003 * COIN);
351353
BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U);
354+
355+
empty_wallet();
352356
}
353357

354358
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)