From 6249541f2a6c4cff317a4502d93dd287c5fb0c51 Mon Sep 17 00:00:00 2001 From: Damien Neil Date: Mon, 3 Jun 2024 12:34:02 -0700 Subject: [PATCH] http2: avoid race in server handler SetReadDeadine/SetWriteDeadline Can't safely access responseWriter.rws from on the server's serve loop. Change-Id: I477abe58cf9dd23813a0c5507aed2319696fdfaf Reviewed-on: https://go-review.googlesource.com/c/net/+/589856 Reviewed-by: Brad Fitzpatrick Reviewed-by: Matthew Dempsky Auto-Submit: Damien Neil LUCI-TryBot-Result: Go LUCI --- http2/server.go | 8 ++++---- http2/server_test.go | 13 +++++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/http2/server.go b/http2/server.go index d23640d01..6c349f3ec 100644 --- a/http2/server.go +++ b/http2/server.go @@ -2821,9 +2821,9 @@ func (w *responseWriter) SetReadDeadline(deadline time.Time) error { if deadline.IsZero() { st.readDeadline = nil } else if st.readDeadline == nil { - st.readDeadline = sc.srv.afterFunc(deadline.Sub(w.rws.conn.srv.now()), st.onReadTimeout) + st.readDeadline = sc.srv.afterFunc(deadline.Sub(sc.srv.now()), st.onReadTimeout) } else { - st.readDeadline.Reset(deadline.Sub(w.rws.conn.srv.now())) + st.readDeadline.Reset(deadline.Sub(sc.srv.now())) } }) return nil @@ -2847,9 +2847,9 @@ func (w *responseWriter) SetWriteDeadline(deadline time.Time) error { if deadline.IsZero() { st.writeDeadline = nil } else if st.writeDeadline == nil { - st.writeDeadline = sc.srv.afterFunc(deadline.Sub(w.rws.conn.srv.now()), st.onWriteTimeout) + st.writeDeadline = sc.srv.afterFunc(deadline.Sub(sc.srv.now()), st.onWriteTimeout) } else { - st.writeDeadline.Reset(deadline.Sub(w.rws.conn.srv.now())) + st.writeDeadline.Reset(deadline.Sub(sc.srv.now())) } }) return nil diff --git a/http2/server_test.go b/http2/server_test.go index f877015b9..47c3c619c 100644 --- a/http2/server_test.go +++ b/http2/server_test.go @@ -4661,3 +4661,16 @@ func TestServerRequestCancelOnError(t *testing.T) { }) <-donec } + +func TestServerSetReadWriteDeadlineRace(t *testing.T) { + ts := newTestServer(t, func(w http.ResponseWriter, r *http.Request) { + ctl := http.NewResponseController(w) + ctl.SetReadDeadline(time.Now().Add(3600 * time.Second)) + ctl.SetWriteDeadline(time.Now().Add(3600 * time.Second)) + }) + resp, err := ts.Client().Get(ts.URL) + if err != nil { + t.Fatal(err) + } + resp.Body.Close() +}