From 133a97f60d0052496550f3423cbae9e20ecf9c7b Mon Sep 17 00:00:00 2001 From: Anna Henningsen 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`. PR-URL: https://github.com/nodejs/node/pull/33917 Reviewed-By: James M Snell Reviewed-By: Denys Otrishko Reviewed-By: Matteo Collina --- 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 dest(NGTCP2_STATELESS_RESET_TOKENLEN * 2 + 1); dest[dest.size() - 1] = '\0'; size_t written = StringBytes::hex_encode( - reinterpret_cast(token_), + reinterpret_cast(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{}(token.token_[n]) + 0x9e3779b9 + + hash ^= std::hash{}(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