From b0f50ab9c9cb54d58e91eee7fce0a42a47edd8ba Mon Sep 17 00:00:00 2001 From: Mark Yen Date: Thu, 11 Jan 2024 10:49:03 -0800 Subject: [PATCH] WSL-Helper: Certs: Make a copy of foreign memory We enumerate system certificates on Windows asynchronously and return the results (as *x509.Certificate objects) in a channel. It turns out that those certificates can refer to memory passed in via ParseCertificate(), so we ended up using a certificate that referred to freed memory. Avoid the issue by explicitly making a copy of that slice. Signed-off-by: Mark Yen --- .../wsl-helper/pkg/certificates/certificates_windows.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/go/wsl-helper/pkg/certificates/certificates_windows.go b/src/go/wsl-helper/pkg/certificates/certificates_windows.go index 80c98b7482b..881b2aee7c1 100644 --- a/src/go/wsl-helper/pkg/certificates/certificates_windows.go +++ b/src/go/wsl-helper/pkg/certificates/certificates_windows.go @@ -74,7 +74,13 @@ func GetSystemCertificates(storeName string) (<-chan Entry, error) { } break } - cert, err := x509.ParseCertificate(unsafe.Slice(certCtx.EncodedCert, certCtx.Length)) + // Make a copy of the encoded cert, because the parsed cert may have + // references to the memory (that isn't owned by the GC) and we'll return + // it in a channel, so HeapFree() might get called on it before it's used. + // See #6295 / #6307. + certData := make([]byte, certCtx.Length) + copy(certData, unsafe.Slice(certCtx.EncodedCert, certCtx.Length)) + cert, err := x509.ParseCertificate(certData) if err != nil { // Skip invalid certs logrus.Tracef("Skipping invalid certificate %q in %q: %s", getCertName(certCtx), storeName, err)