Do not memcpy from an empty span in the stream decoder

An empty read before the IV arrived passed a null source to memcpy,
which UBSan reports (and the ASan CI job turns into a failure).
This commit is contained in:
Max Lv
2026-10-14 22:53:07 +08:00
parent bf5bc2f216
commit 8cf10ba890
2 changed files with 6 additions and 1 deletions
+3 -1
View File
@@ -217,7 +217,9 @@ Result<StreamTcpDecryptor::Step> StreamTcpDecryptor::decrypt(std::span<const std
if (!ready_) {
std::size_t want = key_.spec.iv_len - iv_have_;
std::size_t take = std::min(want, in.size());
std::memcpy(iv_.data() + iv_have_, in.data(), take);
if (take != 0) { // an empty span may have a null data()
std::memcpy(iv_.data() + iv_have_, in.data(), take);
}
iv_have_ += take;
step.consumed += take;
in = in.subspan(take);
+3
View File
@@ -179,6 +179,9 @@ void replay(const sc::StreamKey &key)
std::uint8_t out[16];
sc::StreamTcpDecryptor first, second;
SS_CHECK(first.init(key, seen.filter()) && second.init(key, seen.filter()));
// An empty read before the IV arrives is a no-op.
auto none = first.decrypt(std::span<const std::uint8_t>(), out);
SS_CHECK(none && none->consumed == 0 && none->produced == 0 && !first.iv_received());
// The IV alone is enough to register it.
auto step = first.decrypt(std::span<const std::uint8_t>(wire.data(), key.spec.iv_len), out);
SS_CHECK(step && step->produced == 0 && first.iv_received());