diff --git a/.gitignore b/.gitignore index 570c2b5..ceb3ab9 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/go-go-1.15.7-1-openssl-fips.tar.gz +SOURCES/go-go-1.16.7-1-openssl-fips.tar.gz diff --git a/.golang.metadata b/.golang.metadata index a431e7e..413c971 100644 --- a/.golang.metadata +++ b/.golang.metadata @@ -1 +1 @@ -501d01d764310874ec20f3d7555c70948ef15fb2 SOURCES/go-go-1.15.7-1-openssl-fips.tar.gz +e693273f254789980a55720bd48ac8741d446f21 SOURCES/go-go-1.16.7-1-openssl-fips.tar.gz 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/SOURCES/net-http-graceful-shutdown.patch b/SOURCES/net-http-graceful-shutdown.patch deleted file mode 100644 index 90dd711..0000000 --- a/SOURCES/net-http-graceful-shutdown.patch +++ /dev/null @@ -1,157 +0,0 @@ -diff --git a/src/net/http/export_test.go b/src/net/http/export_test.go -index 657ff9d..67a74ae 100644 ---- a/src/net/http/export_test.go -+++ b/src/net/http/export_test.go -@@ -274,6 +274,17 @@ func (s *Server) ExportAllConnsIdle() bool { - return true - } - -+func (s *Server) ExportAllConnsByState() map[ConnState]int { -+ states := map[ConnState]int{} -+ s.mu.Lock() -+ defer s.mu.Unlock() -+ for c := range s.activeConn { -+ st, _ := c.getState() -+ states[st] += 1 -+ } -+ return states -+} -+ - func (r *Request) WithT(t *testing.T) *Request { - return r.WithContext(context.WithValue(r.Context(), tLogKey{}, t.Logf)) - } -diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go -index 5f56932..806272b 100644 ---- a/src/net/http/serve_test.go -+++ b/src/net/http/serve_test.go -@@ -5519,16 +5519,23 @@ func TestServerSetKeepAlivesEnabledClosesConns(t *testing.T) { - } - } - --func TestServerShutdown_h1(t *testing.T) { testServerShutdown(t, h1Mode) } --func TestServerShutdown_h2(t *testing.T) { testServerShutdown(t, h2Mode) } -+func TestServerShutdown_h1(t *testing.T) { -+ testServerShutdown(t, h1Mode) -+} -+func TestServerShutdown_h2(t *testing.T) { -+ testServerShutdown(t, h2Mode) -+} - - func testServerShutdown(t *testing.T, h2 bool) { - setParallel(t) - defer afterTest(t) - var doShutdown func() // set later -+ var doStateCount func() - var shutdownRes = make(chan error, 1) -+ var statesRes = make(chan map[ConnState]int, 1) - var gotOnShutdown = make(chan struct{}, 1) - handler := HandlerFunc(func(w ResponseWriter, r *Request) { -+ doStateCount() - go doShutdown() - // Shutdown is graceful, so it should not interrupt - // this in-flight response. Add a tiny sleep here to -@@ -5545,6 +5552,9 @@ func testServerShutdown(t *testing.T, h2 bool) { - doShutdown = func() { - shutdownRes <- cst.ts.Config.Shutdown(context.Background()) - } -+ doStateCount = func() { -+ statesRes <- cst.ts.Config.ExportAllConnsByState() -+ } - get(t, cst.c, cst.ts.URL) // calls t.Fail on failure - - if err := <-shutdownRes; err != nil { -@@ -5556,6 +5566,10 @@ func testServerShutdown(t *testing.T, h2 bool) { - t.Errorf("onShutdown callback not called, RegisterOnShutdown broken?") - } - -+ if states := <-statesRes; states[StateActive] != 1 { -+ t.Errorf("connection in wrong state, %v", states) -+ } -+ - res, err := cst.c.Get(cst.ts.URL) - if err == nil { - res.Body.Close() -diff --git a/src/net/http/server.go b/src/net/http/server.go -index d41b5f6..14a6336 100644 ---- a/src/net/http/server.go -+++ b/src/net/http/server.go -@@ -324,7 +324,7 @@ func (c *conn) hijackLocked() (rwc net.Conn, buf *bufio.ReadWriter, err error) { - return nil, nil, fmt.Errorf("unexpected Peek failure reading buffered byte: %v", err) - } - } -- c.setState(rwc, StateHijacked) -+ c.setState(rwc, StateHijacked, runHooks) - return - } - -@@ -1737,7 +1737,12 @@ func validNextProto(proto string) bool { - return true - } - --func (c *conn) setState(nc net.Conn, state ConnState) { -+const ( -+ runHooks = true -+ skipHooks = false -+) -+ -+func (c *conn) setState(nc net.Conn, state ConnState, runHook bool) { - srv := c.server - switch state { - case StateNew: -@@ -1750,6 +1755,9 @@ func (c *conn) setState(nc net.Conn, state ConnState) { - } - packedState := uint64(time.Now().Unix()<<8) | uint64(state) - atomic.StoreUint64(&c.curState.atomic, packedState) -+ if !runHook { -+ return -+ } - if hook := srv.ConnState; hook != nil { - hook(nc, state) - } -@@ -1803,7 +1811,7 @@ func (c *conn) serve(ctx context.Context) { - } - if !c.hijacked() { - c.close() -- c.setState(c.rwc, StateClosed) -+ c.setState(c.rwc, StateClosed, runHooks) - } - }() - -@@ -1831,6 +1839,10 @@ func (c *conn) serve(ctx context.Context) { - if proto := c.tlsState.NegotiatedProtocol; validNextProto(proto) { - if fn := c.server.TLSNextProto[proto]; fn != nil { - h := initALPNRequest{ctx, tlsConn, serverHandler{c.server}} -+ // Mark freshly created HTTP/2 as active and prevent any server state hooks -+ // from being run on these connections. This prevents closeIdleConns from -+ // closing such connections. See issue https://golang.org/issue/39776. -+ c.setState(c.rwc, StateActive, skipHooks) - fn(c.server, tlsConn, h) - } - return -@@ -1851,7 +1863,7 @@ func (c *conn) serve(ctx context.Context) { - w, err := c.readRequest(ctx) - if c.r.remain != c.server.initialReadLimitSize() { - // If we read any bytes off the wire, we're active. -- c.setState(c.rwc, StateActive) -+ c.setState(c.rwc, StateActive, runHooks) - } - if err != nil { - const errorHeaders = "\r\nContent-Type: text/plain; charset=utf-8\r\nConnection: close\r\n\r\n" -@@ -1934,7 +1946,7 @@ func (c *conn) serve(ctx context.Context) { - } - return - } -- c.setState(c.rwc, StateIdle) -+ c.setState(c.rwc, StateIdle, runHooks) - c.curReq.Store((*response)(nil)) - - if !w.conn.server.doKeepAlives() { -@@ -2965,7 +2977,7 @@ func (srv *Server) Serve(l net.Listener) error { - } - tempDelay = 0 - c := srv.newConn(rw) -- c.setState(c.rwc, StateNew) // before Serve can return -+ c.setState(c.rwc, StateNew, runHooks) // before Serve can return - go c.serve(connCtx) - } - } diff --git a/SOURCES/reject-leading-zeros.patch b/SOURCES/reject-leading-zeros.patch new file mode 100644 index 0000000..24fa6c8 --- /dev/null +++ b/SOURCES/reject-leading-zeros.patch @@ -0,0 +1,109 @@ +diff --git a/doc/go1.16.html b/doc/go1.16.html +index 0beb62d..fc6b668 100644 +--- a/doc/go1.16.html ++++ b/doc/go1.16.html +@@ -891,6 +891,14 @@ func TestFoo(t *testing.T) { + is missing; this is common on musl-based systems and makes + Go programs match the behavior of C programs on those systems. +
++
++ The ParseIP
and ParseCIDR
++ functions now reject IPv4 addresses which contain decimal components with leading zeros.
++ These components were always interpreted as decimal, but some operating systems treat them as octal.
++ This mismatch could hypothetically lead to security issues if a Go application was used to validate IP addresses
++ which were then used in their original form with non-Go applications which interpreted components as octal. Generally,
++ it is advisable to always re-encoded values after validation, which avoids this class of parser misalignment issues.
++