From 77a4bf17ca111096ac79fd6f2064d69cc01146c2 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 22 Feb 2018 09:20:57 +0800 Subject: [PATCH] fix race condition in GetOrOpenStream in incoming streams map --- streams_map_incoming_bidi.go | 4 +++- streams_map_incoming_generic.go | 4 +++- streams_map_incoming_uni.go | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/streams_map_incoming_bidi.go b/streams_map_incoming_bidi.go index 8a35f044..e88d6397 100644 --- a/streams_map_incoming_bidi.go +++ b/streams_map_incoming_bidi.go @@ -69,18 +69,20 @@ func (m *incomingBidiStreamsMap) AcceptStream() (streamI, error) { } func (m *incomingBidiStreamsMap) GetOrOpenStream(id protocol.StreamID) (streamI, error) { + m.mutex.RLock() if id > m.maxStream { + m.mutex.RUnlock() return nil, fmt.Errorf("peer tried to open stream %d (current limit: %d)", id, m.maxStream) } // if the id is smaller than the highest we accepted // * this stream exists in the map, and we can return it, or // * this stream was already closed, then we can return the nil if id <= m.highestStream { - m.mutex.RLock() s := m.streams[id] m.mutex.RUnlock() return s, nil } + m.mutex.RUnlock() m.mutex.Lock() var start protocol.StreamID diff --git a/streams_map_incoming_generic.go b/streams_map_incoming_generic.go index 830b690d..dc79b496 100644 --- a/streams_map_incoming_generic.go +++ b/streams_map_incoming_generic.go @@ -67,18 +67,20 @@ func (m *incomingItemsMap) AcceptStream() (item, error) { } func (m *incomingItemsMap) GetOrOpenStream(id protocol.StreamID) (item, error) { + m.mutex.RLock() if id > m.maxStream { + m.mutex.RUnlock() return nil, fmt.Errorf("peer tried to open stream %d (current limit: %d)", id, m.maxStream) } // if the id is smaller than the highest we accepted // * this stream exists in the map, and we can return it, or // * this stream was already closed, then we can return the nil if id <= m.highestStream { - m.mutex.RLock() s := m.streams[id] m.mutex.RUnlock() return s, nil } + m.mutex.RUnlock() m.mutex.Lock() var start protocol.StreamID diff --git a/streams_map_incoming_uni.go b/streams_map_incoming_uni.go index 9091d635..536b42dd 100644 --- a/streams_map_incoming_uni.go +++ b/streams_map_incoming_uni.go @@ -69,18 +69,20 @@ func (m *incomingUniStreamsMap) AcceptStream() (receiveStreamI, error) { } func (m *incomingUniStreamsMap) GetOrOpenStream(id protocol.StreamID) (receiveStreamI, error) { + m.mutex.RLock() if id > m.maxStream { + m.mutex.RUnlock() return nil, fmt.Errorf("peer tried to open stream %d (current limit: %d)", id, m.maxStream) } // if the id is smaller than the highest we accepted // * this stream exists in the map, and we can return it, or // * this stream was already closed, then we can return the nil if id <= m.highestStream { - m.mutex.RLock() s := m.streams[id] m.mutex.RUnlock() return s, nil } + m.mutex.RUnlock() m.mutex.Lock() var start protocol.StreamID