rework unsafe string -> bytes conversion #8674 (#8684)

Changing the unsafe string -> bytes conversion to fix
a security concern.

Closes: #8670

Co-authored-by: Alessio Treglia <alessio@tendermint.com>
This commit is contained in:
Robert Zaremba 2021-02-24 13:47:32 +01:00 committed by GitHub
parent 06ababdf36
commit 7969135abc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 6 deletions

View File

@ -64,11 +64,10 @@ func Module(moduleName string, key []byte) []byte {
return Hash("module", append(mKey, key...)) return Hash("module", append(mKey, key...))
} }
// unsafeStrToByteArray uses unsafe to convert string into byte array. Returned array // unsafeStrToByteArray uses unsafe to convert string into byte array. Returned bytes
// cannot be altered after this functions is called // must not be altered after this function is called as it will cause a segmentation fault.
func unsafeStrToByteArray(s string) []byte { func unsafeStrToByteArray(s string) []byte {
sh := *(*reflect.SliceHeader)(unsafe.Pointer(&s)) // nolint:govet var buf = *(*[]byte)(unsafe.Pointer(&s))
sh.Cap = sh.Len (*reflect.SliceHeader)(unsafe.Pointer(&buf)).Cap = len(s)
bs := *(*[]byte)(unsafe.Pointer(&sh)) // nolint:govet return buf
return bs
} }

View File

@ -2,7 +2,9 @@ package address
import ( import (
"crypto/sha256" "crypto/sha256"
"runtime"
"testing" "testing"
"time"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
@ -75,6 +77,23 @@ func (suite *AddressSuite) TestModule() {
assert.NotEqual(addr2, addr3, "changing key must change address") assert.NotEqual(addr2, addr3, "changing key must change address")
} }
func unsafeConvertABC() []byte {
return unsafeStrToByteArray("abc")
}
func (suite *AddressSuite) TestUnsafeStrToBytes() {
// we convert in other function to trigger GC. We want to check that
// the underlying array in []bytes is accessible after GC will finish swapping.
for i := 0; i < 5; i++ {
b := unsafeConvertABC()
runtime.GC()
<-time.NewTimer(2 * time.Millisecond).C
b2 := append(b, 'd')
suite.Equal("abc", string(b))
suite.Equal("abcd", string(b2))
}
}
type addrMock struct { type addrMock struct {
Addr []byte Addr []byte
} }