Skip to content

Commit

Permalink
rework unsafe string -> bytes conversion #8674 (#8684)
Browse files Browse the repository at this point in the history
Changing the unsafe string -> bytes conversion to fix
a security concern.

Closes: #8670

Co-authored-by: Alessio Treglia <alessio@tendermint.com>
  • Loading branch information
robert-zaremba and Alessio Treglia authored Feb 24, 2021
1 parent 06ababd commit 7969135
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 6 deletions.
11 changes: 5 additions & 6 deletions types/address/hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
19 changes: 19 additions & 0 deletions types/address/hash_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package address

import (
"crypto/sha256"
"runtime"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
Expand Down Expand Up @@ -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
}
Expand Down

0 comments on commit 7969135

Please sign in to comment.