From 755ee7d82a26a1f85bdd315bb366fccf3feefa7d Mon Sep 17 00:00:00 2001 From: Anna Henningsen <anna@addaleax.net> Date: Wed, 17 Jun 2020 01:46:19 +0200 Subject: [PATCH] quic: always copy stateless reset token Take ownership of the token value, since the memory for it is allocated anyway and the buffer size is just 16, i.e. copyable very cheaply. This makes valgrind stop complaining about a use-after-free error when running `sequential/test-quic-preferred-address-ipv6`. --- src/quic/node_quic_util-inl.h | 15 ++++++++++----- src/quic/node_quic_util.h | 8 +++----- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/quic/node_quic_util-inl.h b/src/quic/node_quic_util-inl.h index dbd5648aecd3a5..d51dc8d7e63d23 100644 --- a/src/quic/node_quic_util-inl.h +++ b/src/quic/node_quic_util-inl.h @@ -287,22 +287,27 @@ bool PreferredAddress::ResolvePreferredAddress( StatelessResetToken::StatelessResetToken( uint8_t* token, const uint8_t* secret, - const QuicCID& cid) : token_(token) { + const QuicCID& cid) { GenerateResetToken(token, secret, cid); + memcpy(buf_, token, sizeof(buf_)); } StatelessResetToken::StatelessResetToken( const uint8_t* secret, - const QuicCID& cid) - : token_(buf_) { + const QuicCID& cid) { GenerateResetToken(buf_, secret, cid); } +StatelessResetToken::StatelessResetToken( + const uint8_t* token) { + memcpy(buf_, token, sizeof(buf_)); +} + std::string StatelessResetToken::ToString() const { std::vector<char> dest(NGTCP2_STATELESS_RESET_TOKENLEN * 2 + 1); dest[dest.size() - 1] = '\0'; size_t written = StringBytes::hex_encode( - reinterpret_cast<const char*>(token_), + reinterpret_cast<const char*>(buf_), NGTCP2_STATELESS_RESET_TOKENLEN, dest.data(), dest.size()); @@ -313,7 +318,7 @@ size_t StatelessResetToken::Hash::operator()( const StatelessResetToken& token) const { size_t hash = 0; for (size_t n = 0; n < NGTCP2_STATELESS_RESET_TOKENLEN; n++) - hash ^= std::hash<uint8_t>{}(token.token_[n]) + 0x9e3779b9 + + hash ^= std::hash<uint8_t>{}(token.buf_[n]) + 0x9e3779b9 + (hash << 6) + (hash >> 2); return hash; } diff --git a/src/quic/node_quic_util.h b/src/quic/node_quic_util.h index 6fdfb99cc688a3..e1490941aa3224 100644 --- a/src/quic/node_quic_util.h +++ b/src/quic/node_quic_util.h @@ -386,13 +386,12 @@ class StatelessResetToken : public MemoryRetainer { const uint8_t* secret, const QuicCID& cid); - explicit StatelessResetToken( - const uint8_t* token) - : token_(token) {} + explicit inline StatelessResetToken( + const uint8_t* token); inline std::string ToString() const; - const uint8_t* data() const { return token_; } + const uint8_t* data() const { return buf_; } struct Hash { inline size_t operator()(const StatelessResetToken& token) const; @@ -414,7 +413,6 @@ class StatelessResetToken : public MemoryRetainer { private: uint8_t buf_[NGTCP2_STATELESS_RESET_TOKENLEN]{}; - const uint8_t* token_; }; template <typename T>