From f6c48db4418b41667c99a92871e0180f7a7a0b35 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Jun 24 2021 04:59:45 +0000 Subject: import golang-1.16.4-3.module+el8.5.0+11462+061f83ad --- diff --git a/SOURCES/fix-crypto-memory-leaks.patch b/SOURCES/fix-crypto-memory-leaks.patch new file mode 100644 index 0000000..daab969 --- /dev/null +++ b/SOURCES/fix-crypto-memory-leaks.patch @@ -0,0 +1,235 @@ +diff --git a/src/crypto/internal/boring/goopenssl.h b/src/crypto/internal/boring/goopenssl.h +index 3585458..ae1607b 100644 +--- a/src/crypto/internal/boring/goopenssl.h ++++ b/src/crypto/internal/boring/goopenssl.h +@@ -667,6 +667,7 @@ typedef EVP_PKEY GO_EVP_PKEY; + DEFINEFUNC(GO_EVP_PKEY *, EVP_PKEY_new, (void), ()) + DEFINEFUNC(void, EVP_PKEY_free, (GO_EVP_PKEY * arg0), (arg0)) + DEFINEFUNC(int, EVP_PKEY_set1_RSA, (GO_EVP_PKEY * arg0, GO_RSA *arg1), (arg0, arg1)) ++DEFINEFUNC(int, EVP_PKEY_set1_EC_KEY, (GO_EVP_PKEY * arg0, GO_EC_KEY *arg1), (arg0, arg1)) + DEFINEFUNC(int, EVP_PKEY_verify, + (EVP_PKEY_CTX *ctx, const unsigned char *sig, unsigned int siglen, const unsigned char *tbs, size_t tbslen), + (ctx, sig, siglen, tbs, tbslen)) +diff --git a/src/crypto/internal/boring/openssl_ecdsa_signature.c b/src/crypto/internal/boring/openssl_ecdsa_signature.c +index 4c14cc9..daa1252 100644 +--- a/src/crypto/internal/boring/openssl_ecdsa_signature.c ++++ b/src/crypto/internal/boring/openssl_ecdsa_signature.c +@@ -9,19 +9,32 @@ + int + _goboringcrypto_ECDSA_sign(EVP_MD* md, const uint8_t *msg, size_t msgLen, uint8_t *sig, unsigned int *slen, GO_EC_KEY *eckey) + { ++ int result; + EVP_PKEY *key = _goboringcrypto_EVP_PKEY_new(); +- if (!_goboringcrypto_EVP_PKEY_assign_EC_KEY(key, eckey)) +- return 0; +- return _goboringcrypto_EVP_sign(md, NULL, msg, msgLen, sig, slen, key); ++ if (!_goboringcrypto_EVP_PKEY_set1_EC_KEY(key, eckey)) { ++ result = 0; ++ goto err; ++ } ++ result = _goboringcrypto_EVP_sign(md, NULL, msg, msgLen, sig, slen, key); ++err: ++ _goboringcrypto_EVP_PKEY_free(key); ++ return result; + } + + int + _goboringcrypto_ECDSA_verify(EVP_MD* md, const uint8_t *msg, size_t msgLen, const uint8_t *sig, unsigned int slen, GO_EC_KEY *eckey) + { + ++ int result; + EVP_PKEY *key = _goboringcrypto_EVP_PKEY_new(); +- if (!_goboringcrypto_EVP_PKEY_assign_EC_KEY(key, eckey)) +- return 0; ++ if (!_goboringcrypto_EVP_PKEY_set1_EC_KEY(key, eckey)) { ++ result = 0; ++ goto err; ++ } + +- return _goboringcrypto_EVP_verify(md, NULL, msg, msgLen, sig, slen, key); ++ result = _goboringcrypto_EVP_verify(md, NULL, msg, msgLen, sig, slen, key); ++ ++err: ++ _goboringcrypto_EVP_PKEY_free(key); ++ return result; + } +diff --git a/src/crypto/internal/boring/openssl_port_rsa.c b/src/crypto/internal/boring/openssl_port_rsa.c +index a8d047d..2e56499 100644 +--- a/src/crypto/internal/boring/openssl_port_rsa.c ++++ b/src/crypto/internal/boring/openssl_port_rsa.c +@@ -25,14 +25,13 @@ int _goboringcrypto_RSA_digest_and_sign_pss_mgf1(GO_RSA *rsa, unsigned int *out_ + EVP_PKEY_CTX *ctx; + unsigned int siglen; + ++ int ret = 0; + EVP_PKEY *key = _goboringcrypto_EVP_PKEY_new(); +- if (!_goboringcrypto_EVP_PKEY_assign_RSA(key, rsa)) +- return 0; ++ if (!_goboringcrypto_EVP_PKEY_set1_RSA(key, rsa)) ++ goto err; + ctx = _goboringcrypto_EVP_PKEY_CTX_new(key, NULL /* no engine */); + if (!ctx) +- return 0; +- +- int ret = 0; ++ goto err; + + EVP_MD_CTX *mdctx = NULL; + if (!(mdctx = _goboringcrypto_EVP_MD_CTX_create())) +@@ -67,6 +66,10 @@ int _goboringcrypto_RSA_digest_and_sign_pss_mgf1(GO_RSA *rsa, unsigned int *out_ + err: + if (mdctx) + _goboringcrypto_EVP_MD_CTX_free(mdctx); ++ if (ctx) ++ _goboringcrypto_EVP_PKEY_CTX_free(ctx); ++ if (key) ++ _goboringcrypto_EVP_PKEY_free(key); + + return ret; + } +@@ -78,18 +81,17 @@ int _goboringcrypto_RSA_sign_pss_mgf1(GO_RSA *rsa, unsigned int *out_len, uint8_ + EVP_PKEY *pkey; + size_t siglen; + ++ int ret = 0; + pkey = _goboringcrypto_EVP_PKEY_new(); + if (!pkey) +- return 0; ++ goto err; + + if (_goboringcrypto_EVP_PKEY_set1_RSA(pkey, rsa) <= 0) +- return 0; +- ++ goto err; ++ + ctx = _goboringcrypto_EVP_PKEY_CTX_new(pkey, NULL /* no engine */); + if (!ctx) +- return 0; +- +- int ret = 0; ++ goto err; + + if (_goboringcrypto_EVP_PKEY_sign_init(ctx) <= 0) + goto err; +@@ -101,7 +103,7 @@ int _goboringcrypto_RSA_sign_pss_mgf1(GO_RSA *rsa, unsigned int *out_len, uint8_ + goto err; + if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgf1_md) <= 0) + goto err; +- ++ + /* Determine buffer length */ + if (_goboringcrypto_EVP_PKEY_sign(ctx, NULL, &siglen, in, in_len) <= 0) + goto err; +@@ -116,7 +118,10 @@ int _goboringcrypto_RSA_sign_pss_mgf1(GO_RSA *rsa, unsigned int *out_len, uint8_ + ret = 1; + + err: +- _goboringcrypto_EVP_PKEY_CTX_free(ctx); ++ if (ctx) ++ _goboringcrypto_EVP_PKEY_CTX_free(ctx); ++ if (pkey) ++ _goboringcrypto_EVP_PKEY_free(pkey); + + return ret; + } +@@ -130,14 +135,14 @@ int _goboringcrypto_RSA_verify_pss_mgf1(RSA *rsa, const uint8_t *msg, unsigned i + + pkey = _goboringcrypto_EVP_PKEY_new(); + if (!pkey) +- return 0; ++ goto err; + + if (_goboringcrypto_EVP_PKEY_set1_RSA(pkey, rsa) <= 0) +- return 0; +- ++ goto err; ++ + ctx = _goboringcrypto_EVP_PKEY_CTX_new(pkey, NULL /* no engine */); + if (!ctx) +- return 0; ++ goto err; + + if (_goboringcrypto_EVP_PKEY_verify_init(ctx) <= 0) + goto err; +@@ -155,25 +160,40 @@ int _goboringcrypto_RSA_verify_pss_mgf1(RSA *rsa, const uint8_t *msg, unsigned i + ret = 1; + + err: +- _goboringcrypto_EVP_PKEY_CTX_free(ctx); ++ if (ctx) ++ _goboringcrypto_EVP_PKEY_CTX_free(ctx); ++ if (pkey) ++ _goboringcrypto_EVP_PKEY_free(pkey); ++ + + return ret; + } + + int _goboringcrypto_EVP_RSA_sign(EVP_MD *md, const uint8_t *msg, unsigned int msgLen, uint8_t *sig, unsigned int *slen, RSA *rsa) + { ++ int result; + EVP_PKEY *key = _goboringcrypto_EVP_PKEY_new(); +- if (!_goboringcrypto_EVP_PKEY_assign_RSA(key, rsa)) +- return 0; +- return _goboringcrypto_EVP_sign(md, NULL, msg, msgLen, sig, slen, key); ++ if (!_goboringcrypto_EVP_PKEY_set1_RSA(key, rsa)) { ++ result = 0; ++ goto err; ++ } ++ result = _goboringcrypto_EVP_sign(md, NULL, msg, msgLen, sig, slen, key); ++err: ++ _goboringcrypto_EVP_PKEY_free(key); ++ return result; + } + + int _goboringcrypto_EVP_RSA_verify(EVP_MD *md, const uint8_t *msg, unsigned int msgLen, const uint8_t *sig, unsigned int slen, GO_RSA *rsa) + { ++ int result; + EVP_PKEY *key = _goboringcrypto_EVP_PKEY_new(); +- if (!_goboringcrypto_EVP_PKEY_assign_RSA(key, rsa)) +- { +- return 0; ++ if (!_goboringcrypto_EVP_PKEY_set1_RSA(key, rsa)) { ++ result = 0; ++ goto err; + } +- return _goboringcrypto_EVP_verify(md, NULL, msg, msgLen, sig, slen, key); ++ result = _goboringcrypto_EVP_verify(md, NULL, msg, msgLen, sig, slen, key); ++err: ++ _goboringcrypto_EVP_PKEY_free(key); ++ return result; ++ + } +diff --git a/src/crypto/internal/boring/rsa.go b/src/crypto/internal/boring/rsa.go +index 2eefc27..698c08e 100644 +--- a/src/crypto/internal/boring/rsa.go ++++ b/src/crypto/internal/boring/rsa.go +@@ -162,12 +162,23 @@ func setupRSA(withKey func(func(*C.GO_RSA) C.int) C.int, + return nil, nil, NewOpenSSLError("EVP_PKEY_set_rsa_oaep_md failed") + } + // ctx takes ownership of label, so malloc a copy for BoringCrypto to free. +- clabel := (*C.uint8_t)(C.malloc(C.size_t(len(label)))) +- if clabel == nil { +- return nil, nil, fail("OPENSSL_malloc") ++ var clabel *C.uint8_t ++ clabel = nil ++ // OpenSSL 1.1.1 does not take ownership of the label if the length is zero. ++ // Depending on the malloc implementation, if clabel is allocated with malloc(0), ++ // metadata for the size-zero allocation is never cleaned up, which is a memory leak. ++ // As such, we must only allocate clabel if the label is of non zero length. ++ if len(label) > 0 { ++ clabel = (*C.uint8_t)(C.malloc(C.size_t(len(label)))) ++ if clabel == nil { ++ return nil, nil, fail("OPENSSL_malloc") ++ } ++ copy((*[1 << 30]byte)(unsafe.Pointer(clabel))[:len(label)], label) + } +- copy((*[1 << 30]byte)(unsafe.Pointer(clabel))[:len(label)], label) +- if C._goboringcrypto_EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, clabel, C.int(len(label))) == 0 { ++ if C._goboringcrypto_EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, clabel, C.int(len(label))) != 1 { ++ if clabel != nil { ++ C.free(unsafe.Pointer(clabel)) ++ } + return nil, nil, NewOpenSSLError("EVP_PKEY_CTX_set0_rsa_oaep_label failed") + } + } diff --git a/SPECS/golang.spec b/SPECS/golang.spec index 4e99e8f..a7fec5c 100644 --- a/SPECS/golang.spec +++ b/SPECS/golang.spec @@ -101,7 +101,7 @@ Name: golang Version: %{go_version} -Release: 1%{?dist} +Release: 3%{?dist} Summary: The Go Programming Language # source tree includes several copies of Mark.Twain-Tom.Sawyer.txt under Public Domain License: BSD and Public Domain @@ -159,6 +159,9 @@ Patch1955032: rhbz1955032.patch # https://go-review.googlesource.com/c/go/+/315289 Patch1956891: rhbz1956891.patch +# Fix FIPS mode memory leaks +Patch1951877: fix-crypto-memory-leaks.patch + # Having documentation separate was broken Obsoletes: %{name}-docs < 1.1-4 @@ -260,6 +263,9 @@ Requires: %{name} = %{version}-%{release} %patch1956891 -p1 +%patch1951877 -p1 + + cp %{SOURCE1} ./src/runtime/ %build @@ -526,6 +532,13 @@ cd .. %endif %changelog +* Thu Jun 17 2021 David Benoit - 1.16.4-3 +- Fix zero-size allocation memory leak. +- Related: rhbz#1951877 + +* Tue Jun 08 2021 David Benoit - 1.16.4-2 +- Resolves: rhbz#1951877 + * Mon May 24 2021 Alejandro Sáez - 1.16.4-1 - Rebase to go-1.16.4-1-openssl-fips