From d6c892fe7b0c28d3b994323bdb690257d16b332e Mon Sep 17 00:00:00 2001 From: Damian Gryski Date: Tue, 7 Dec 2021 22:31:07 -0800 Subject: [PATCH] src/runtime: fix nil map dereference Operations on nil maps are accepted and shouldn't panic. The base hashmapGet/hashmapDelete handled nil-maps correctly, but the hashmapBinary versions could segfault accessing the nil map while trying to hash the key. Fixes #2341 --- src/runtime/hashmap.go | 8 ++++++++ testdata/map.go | 4 ++++ testdata/map.txt | 1 + 3 files changed, 13 insertions(+) diff --git a/src/runtime/hashmap.go b/src/runtime/hashmap.go index 07d46b57..5c66e19e 100644 --- a/src/runtime/hashmap.go +++ b/src/runtime/hashmap.go @@ -307,16 +307,24 @@ func hashmapNext(m *hashmap, it *hashmapIterator, key, value unsafe.Pointer) boo // Hashmap with plain binary data keys (not containing strings etc.). func hashmapBinarySet(m *hashmap, key, value unsafe.Pointer) { + // TODO: detect nil map here and throw a better panic message? hash := hashmapHash(key, uintptr(m.keySize)) hashmapSet(m, key, value, hash, memequal) } func hashmapBinaryGet(m *hashmap, key, value unsafe.Pointer, valueSize uintptr) bool { + if m == nil { + memzero(value, uintptr(valueSize)) + return false + } hash := hashmapHash(key, uintptr(m.keySize)) return hashmapGet(m, key, value, valueSize, hash, memequal) } func hashmapBinaryDelete(m *hashmap, key unsafe.Pointer) { + if m == nil { + return + } hash := hashmapHash(key, uintptr(m.keySize)) hashmapDelete(m, key, hash, memequal) } diff --git a/testdata/map.go b/testdata/map.go index 4ca456ea..7d9ee6ae 100644 --- a/testdata/map.go +++ b/testdata/map.go @@ -57,6 +57,10 @@ func main() { println(k) // unreachable } + var nilbinmap map[uint16]int + delete(nilbinmap, 4) + println("nilbinmap:", nilbinmap[5]) + arrKey := ArrayKey([4]byte{4, 3, 2, 1}) println(testMapArrayKey[arrKey]) testMapArrayKey[arrKey] = 5555 diff --git a/testdata/map.txt b/testdata/map.txt index 834dd7ad..366f6467 100644 --- a/testdata/map.txt +++ b/testdata/map.txt @@ -53,6 +53,7 @@ true false 0 nilmap: 0 4 42 +nilbinmap: 0 4321 5555 itfMap[3]: 0