mobile: don't retain transient []byte in CallMsg.SetData (#14804)

* mobile: don't retain transient []byte in CallMsg.SetData

Go mobile doesn't copy []byte parameters, for performance and to allow
writes to the byte array be reflected in the native byte array.
Unfortunately, that means []byte arguments are only valid during the
call it is being passed into.

CallMsg.SetData retains such a byte array. Copy it instead

Fixes #14675

* mobile: copy all []byte arguments from gomobile

To avoid subtle errors when accidentially retaining an otherwise
transient byte slice coming from gomobile, copy all byte slices before
use.

* mobile: replace copySlice with common.CopyBytes
This commit is contained in:
Elias Naur
2017-07-17 14:25:46 +02:00
committed by Péter Szilágyi
parent cf5d4b5541
commit 23c6fcdbe8
7 changed files with 21 additions and 17 deletions

View File

@ -25,6 +25,7 @@ import (
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
@ -111,7 +112,7 @@ func (ks *KeyStore) DeleteAccount(account *Account, passphrase string) error {
// SignHash calculates a ECDSA signature for the given hash. The produced signature
// is in the [R || S || V] format where V is 0 or 1.
func (ks *KeyStore) SignHash(address *Address, hash []byte) (signature []byte, _ error) {
return ks.keystore.SignHash(accounts.Account{Address: address.address}, hash)
return ks.keystore.SignHash(accounts.Account{Address: address.address}, common.CopyBytes(hash))
}
// SignTx signs the given transaction with the requested account.
@ -130,7 +131,7 @@ func (ks *KeyStore) SignTx(account *Account, tx *Transaction, chainID *BigInt) (
// be decrypted with the given passphrase. The produced signature is in the
// [R || S || V] format where V is 0 or 1.
func (ks *KeyStore) SignHashPassphrase(account *Account, passphrase string, hash []byte) (signature []byte, _ error) {
return ks.keystore.SignHashWithPassphrase(account.account, passphrase, hash)
return ks.keystore.SignHashWithPassphrase(account.account, passphrase, common.CopyBytes(hash))
}
// SignTxPassphrase signs the transaction if the private key matching the
@ -189,7 +190,7 @@ func (ks *KeyStore) ExportKey(account *Account, passphrase, newPassphrase string
// ImportKey stores the given encrypted JSON key into the key directory.
func (ks *KeyStore) ImportKey(keyJSON []byte, passphrase, newPassphrase string) (account *Account, _ error) {
acc, err := ks.keystore.Import(keyJSON, passphrase, newPassphrase)
acc, err := ks.keystore.Import(common.CopyBytes(keyJSON), passphrase, newPassphrase)
if err != nil {
return nil, err
}
@ -198,7 +199,7 @@ func (ks *KeyStore) ImportKey(keyJSON []byte, passphrase, newPassphrase string)
// ImportECDSAKey stores the given encrypted JSON key into the key directory.
func (ks *KeyStore) ImportECDSAKey(key []byte, passphrase string) (account *Account, _ error) {
privkey, err := crypto.ToECDSA(key)
privkey, err := crypto.ToECDSA(common.CopyBytes(key))
if err != nil {
return nil, err
}
@ -212,7 +213,7 @@ func (ks *KeyStore) ImportECDSAKey(key []byte, passphrase string) (account *Acco
// ImportPreSaleKey decrypts the given Ethereum presale wallet and stores
// a key file in the key directory. The key file is encrypted with the same passphrase.
func (ks *KeyStore) ImportPreSaleKey(keyJSON []byte, passphrase string) (ccount *Account, _ error) {
account, err := ks.keystore.ImportPreSaleKey(keyJSON, passphrase)
account, err := ks.keystore.ImportPreSaleKey(common.CopyBytes(keyJSON), passphrase)
if err != nil {
return nil, err
}