Skip to content

Commit 7b899aa

Browse files
divVerentBoringssl LUCI CQ
authored andcommitted
Array::CopyFrom and InPlaceVector::TryCopyFrom: do not allow in to alias this.
Also, fix one "theoretical" use-after-free in tls13_enc that happens in the tls13_rotate_traffic_key -> tls13_set_traffic_key call chain by resetting the secret to the same secret we already have. This reads the secret after having called std::destroy_n() on it. This is not detected by asan and msan, as the std::destroy_n() call compiles to nothing when the declared type is a built-in integer type like here (uint8_t). At the same time this means that it also is harmless - at least for now, as long as all types this happens with are POD and as long as std::destroy_n() will keep doing nothing on them. Issue found by asking #Gemini to analyze the code. Change-Id: I65ef3b45a6fd3b394f85c79a658dfc2e6a6a6964 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/90987 Commit-Queue: Xiangfei Ding <xfding@google.com> Reviewed-by: Xiangfei Ding <xfding@google.com>
1 parent 8496dec commit 7b899aa

File tree

3 files changed

+18
-5
lines changed

3 files changed

+18
-5
lines changed

crypto/internal.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,13 @@ inline int buffers_alias(const void *a, size_t a_bytes, const void *b,
186186
return a_u + a_bytes > b_u && b_u + b_bytes > a_u;
187187
}
188188

189+
// spans_alias returns one if |a| and |b| alias, and zero otherwise.
190+
template <typename T>
191+
inline int spans_alias(Span<const T> a, Span<const T> b) {
192+
return buffers_alias(a.data(), a.size() * sizeof(T), b.data(),
193+
b.size() * sizeof(T));
194+
}
195+
189196
// align_pointer returns |ptr|, advanced to |alignment|. |alignment| must be a
190197
// power of two, and |ptr| must have at least |alignment - 1| bytes of scratch
191198
// space.

crypto/mem_internal.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,10 @@ class Array {
265265

266266
// CopyFrom replaces the array with a newly-allocated copy of |in|. It returns
267267
// true on success and false on error.
268+
//
269+
// |in| may not alias |this|.
268270
[[nodiscard]] bool CopyFrom(Span<const T> in) {
271+
BSSL_CHECK(!spans_alias(MakeConstSpan(*this), in));
269272
if (!InitUninitialized(in.size())) {
270273
return false;
271274
}
@@ -585,7 +588,10 @@ class InplaceVector {
585588

586589
// TryCopyFrom sets the vector to a copy of |in| and returns true, or returns
587590
// false if |in| is too large.
591+
//
592+
// |in| may not alias |this|.
588593
[[nodiscard]] bool TryCopyFrom(Span<const T> in) {
594+
BSSL_CHECK(!spans_alias(MakeConstSpan(*this), in));
589595
if (in.size() > capacity()) {
590596
return false;
591597
}

ssl/tls13_enc.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -399,17 +399,17 @@ bool tls13_derive_application_secrets(SSL_HANDSHAKE *hs) {
399399
static const char kTLS13LabelApplicationTraffic[] = "traffic upd";
400400

401401
bool tls13_rotate_traffic_key(SSL *ssl, enum evp_aead_direction_t direction) {
402-
Span<uint8_t> secret = direction == evp_aead_open
403-
? Span(ssl->s3->read_traffic_secret)
404-
: Span(ssl->s3->write_traffic_secret);
402+
InplaceVector<uint8_t, SSL_MAX_MD_SIZE> secret(
403+
direction == evp_aead_open ? ssl->s3->read_traffic_secret
404+
: ssl->s3->write_traffic_secret);
405405

406406
const SSL_SESSION *session = SSL_get_session(ssl);
407407
const EVP_MD *digest = ssl_session_get_digest(session);
408-
return hkdf_expand_label(secret, digest, secret,
408+
return hkdf_expand_label(Span(secret), digest, secret,
409409
kTLS13LabelApplicationTraffic, {},
410410
SSL_is_dtls(ssl)) &&
411411
tls13_set_traffic_key(ssl, ssl_encryption_application, direction,
412-
session, secret);
412+
session, Span(secret));
413413
}
414414

415415
static const char kTLS13LabelResumption[] = "res master";

0 commit comments

Comments
 (0)