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...))
}
// unsafeStrToByteArray uses unsafe to convert string into byte array. Returned array
// cannot be altered after this functions is called
// unsafeStrToByteArray uses unsafe to convert string into byte array. Returned bytes
// must not be altered after this function is called as it will cause a segmentation fault.
func unsafeStrToByteArray(s string) []byte {
sh := *(*reflect.SliceHeader)(unsafe.Pointer(&s)) // nolint:govet
sh.Cap = sh.Len
bs := *(*[]byte)(unsafe.Pointer(&sh)) // nolint:govet
return bs
var buf = *(*[]byte)(unsafe.Pointer(&s))
(*reflect.SliceHeader)(unsafe.Pointer(&buf)).Cap = len(s)
return buf
}

View File

@ -2,7 +2,9 @@ package address
import (
"crypto/sha256"
"runtime"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
@ -75,6 +77,23 @@ func (suite *AddressSuite) TestModule() {
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 {
Addr []byte
}