diff -Nru golang-google-grpc-1.6.0/debian/changelog golang-google-grpc-1.6.0/debian/changelog --- golang-google-grpc-1.6.0/debian/changelog 2017-12-05 22:19:44.000000000 +0000 +++ golang-google-grpc-1.6.0/debian/changelog 2019-03-13 15:32:22.000000000 +0000 @@ -1,3 +1,13 @@ +golang-google-grpc (1.6.0-3ubuntu1) bionic; urgency=medium + + * Backport upstream fixes for intermittent panic due to a race condition + when sending RPC status (LP: #1819936) + - transport/handler_server.go: wrap status sending function in a mutex + - transport/handler_server_test.go: add test cases for the races + - Thanks to Gyuho Lee for the patches. + + -- Tiit Pikma Wed, 13 Mar 2019 15:32:22 +0000 + golang-google-grpc (1.6.0-3) unstable; urgency=medium [ Shengjing Zhu ] diff -Nru golang-google-grpc-1.6.0/debian/control golang-google-grpc-1.6.0/debian/control --- golang-google-grpc-1.6.0/debian/control 2017-12-05 22:19:44.000000000 +0000 +++ golang-google-grpc-1.6.0/debian/control 2019-03-13 15:32:22.000000000 +0000 @@ -1,7 +1,8 @@ Source: golang-google-grpc Section: devel Priority: optional -Maintainer: Debian Go Packaging Team +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: Debian Go Packaging Team Uploaders: Dmitry Smirnov , Martín Ferrari , Tim Potter , diff -Nru golang-google-grpc-1.6.0/debian/patches/0003-Fix-race-sending-RPC-status.patch golang-google-grpc-1.6.0/debian/patches/0003-Fix-race-sending-RPC-status.patch --- golang-google-grpc-1.6.0/debian/patches/0003-Fix-race-sending-RPC-status.patch 1970-01-01 00:00:00.000000000 +0000 +++ golang-google-grpc-1.6.0/debian/patches/0003-Fix-race-sending-RPC-status.patch 2019-03-13 15:32:22.000000000 +0000 @@ -0,0 +1,153 @@ +From 22c3f92f5faea8db492fb0f5ae4daf0d2752b19e Mon Sep 17 00:00:00 2001 +From: Gyu-Ho Lee +Date: Wed, 4 Oct 2017 14:44:57 -0700 +Subject: [PATCH] transport: fix racey send to writes channel in WriteStatus + (#1546) + +Concurrent 'SendMsg' calls to stream lead to +multiple 'WriteStatus' calls, while closing +'writes' channel is not synchronized. + +This patch marks 'streamDone' first before 'ht.do', +so that following 'WriteStatus' does not trigger panic +on 'writes' channel. + +Signed-off-by: Gyu-Ho Lee +--- + transport/handler_server.go | 5 +---- + transport/handler_server_test.go | 25 +++++++++++++++++++++++++ + 2 files changed, 26 insertions(+), 4 deletions(-) + +From c6b46087ab923e9f453ec433f99174cdd45b9b89 Mon Sep 17 00:00:00 2001 +From: Gyuho Lee +Date: Thu, 30 Nov 2017 13:58:31 -0800 +Subject: [PATCH] transport: fix race sending RPC status that could lead to a + panic (#1687) + +WriteStatus can be called concurrently: one by SendMsg, +the other by RecvMsg. Then, closing writes channel +becomes racey without proper locking. + +Make transport closing synchronous in such case. +--- + transport/handler_server.go | 23 +++++++++++------------ + transport/handler_server_test.go | 27 +++++++++++++++++++++++---- + 2 files changed, 34 insertions(+), 16 deletions(-) + +diff --git a/transport/handler_server.go b/transport/handler_server.go +index 0489fada52..7e0fdb3593 100644 +--- a/transport/handler_server.go ++++ b/transport/handler_server.go +@@ -123,10 +123,9 @@ type serverHandlerTransport struct { + // when WriteStatus is called. + writes chan func() + +- mu sync.Mutex +- // streamDone indicates whether WriteStatus has been called and writes channel +- // has been closed. +- streamDone bool ++ // block concurrent WriteStatus calls ++ // e.g. grpc/(*serverStream).SendMsg/RecvMsg ++ writeStatusMu sync.Mutex + } + + func (ht *serverHandlerTransport) Close() error { +@@ -173,17 +172,13 @@ func (ht *serverHandlerTransport) do(fn + case <-ht.closedCh: + return ErrConnClosing + } +- + } + } + + func (ht *serverHandlerTransport) WriteStatus(s *Stream, st *status.Status) error { +- ht.mu.Lock() +- if ht.streamDone { +- ht.mu.Unlock() +- return nil +- } +- ht.mu.Unlock() ++ ht.writeStatusMu.Lock() ++ defer ht.writeStatusMu.Unlock() ++ + err := ht.do(func() { + ht.writeCommonHeaders(s) + +@@ -222,10 +217,11 @@ func (ht *serverHandlerTransport) WriteS + } + } + }) +- close(ht.writes) +- ht.mu.Lock() +- ht.streamDone = true +- ht.mu.Unlock() ++ ++ if err == nil { // transport has not been closed ++ ht.Close() ++ close(ht.writes) ++ } + return err + } + +diff --git a/transport/handler_server_test.go b/transport/handler_server_test.go +index 262e6016bd..8505e1a7fd 100644 +--- a/transport/handler_server_test.go ++++ b/transport/handler_server_test.go +@@ -26,6 +26,7 @@ import ( + "net/http/httptest" + "net/url" + "reflect" ++ "sync" + "testing" + "time" + +@@ -390,6 +391,49 @@ func TestHandlerTransport_HandleStreams_ + } + } + ++// TestHandlerTransport_HandleStreams_MultiWriteStatus ensures that ++// concurrent "WriteStatus"s do not panic writing to closed "writes" channel. ++func TestHandlerTransport_HandleStreams_MultiWriteStatus(t *testing.T) { ++ testHandlerTransportHandleStreams(t, func(st *handleStreamTest, s *Stream) { ++ if want := "/service/foo.bar"; s.method != want { ++ t.Errorf("stream method = %q; want %q", s.method, want) ++ } ++ st.bodyw.Close() // no body ++ ++ var wg sync.WaitGroup ++ wg.Add(5) ++ for i := 0; i < 5; i++ { ++ go func() { ++ defer wg.Done() ++ st.ht.WriteStatus(s, status.New(codes.OK, "")) ++ }() ++ } ++ wg.Wait() ++ }) ++} ++ ++// TestHandlerTransport_HandleStreams_WriteStatusWrite ensures that "Write" ++// following "WriteStatus" does not panic writing to closed "writes" channel. ++func TestHandlerTransport_HandleStreams_WriteStatusWrite(t *testing.T) { ++ testHandlerTransportHandleStreams(t, func(st *handleStreamTest, s *Stream) { ++ if want := "/service/foo.bar"; s.method != want { ++ t.Errorf("stream method = %q; want %q", s.method, want) ++ } ++ st.bodyw.Close() // no body ++ ++ st.ht.WriteStatus(s, status.New(codes.OK, "")) ++ st.ht.Write(s, []byte("hdr"), []byte("data"), &Options{}) ++ }) ++} ++ ++func testHandlerTransportHandleStreams(t *testing.T, handleStream func(st *handleStreamTest, s *Stream)) { ++ st := newHandleStreamTest(t) ++ st.ht.HandleStreams( ++ func(s *Stream) { go handleStream(st, s) }, ++ func(ctx context.Context, method string) context.Context { return ctx }, ++ ) ++} ++ + func TestHandlerTransport_HandleStreams_ErrDetails(t *testing.T) { + errDetails := []proto.Message{ + &epb.RetryInfo{ diff -Nru golang-google-grpc-1.6.0/debian/patches/series golang-google-grpc-1.6.0/debian/patches/series --- golang-google-grpc-1.6.0/debian/patches/series 2017-12-05 22:19:44.000000000 +0000 +++ golang-google-grpc-1.6.0/debian/patches/series 2019-03-13 15:32:22.000000000 +0000 @@ -1,2 +1,3 @@ 0001-Disable-network-tests.patch 0002-Add-NewContext-and-FromContext-back-to-metadata-pack.patch +0003-Fix-race-sending-RPC-status.patch