Skip to content

Commit ef984f3

Browse files
authored
fix: Avoid leaking returned bytes outside of Get closure (#3327)
1 parent 8849d75 commit ef984f3

File tree

9 files changed

+49
-61
lines changed

9 files changed

+49
-61
lines changed

cmd/juno/dbcmd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ func dbInfo(cmd *cobra.Command, args []string) error {
100100
return fmt.Errorf("failed to get the state update: %v", err)
101101
}
102102

103-
schemaMeta, err := migration.SchemaMetadata(database)
103+
schemaMeta, err := migration.SchemaMetadata(utils.NewNopZapLogger(), database)
104104
if err != nil {
105105
return fmt.Errorf("failed to get schema metadata: %v", err)
106106
}

core/accessors.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,16 +112,16 @@ func DeleteStateUpdateByBlockNum(w db.KeyValueWriter, blockNum uint64) error {
112112
}
113113

114114
func GetStateUpdateByHash(r db.KeyValueReader, hash *felt.Felt) (*StateUpdate, error) {
115-
var val []byte
115+
var blockNum uint64
116116
err := r.Get(db.BlockHeaderNumbersByHashKey(hash), func(data []byte) error {
117-
val = data
117+
blockNum = binary.BigEndian.Uint64(data)
118118
return nil
119119
})
120120
if err != nil {
121121
return nil, err
122122
}
123123

124-
return GetStateUpdateByBlockNum(r, binary.BigEndian.Uint64(val))
124+
return GetStateUpdateByBlockNum(r, blockNum)
125125
}
126126

127127
// WriteContractStorageHistory writes the old value of a storage location

core/state.go

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -160,24 +160,18 @@ func (s *State) globalTrie(bucket db.Bucket, newTrie trie.NewTrieFunc) (*trie.Tr
160160

161161
// fetch root key
162162
rootKeyDBKey := dbPrefix
163-
var val []byte
163+
rootKey := new(trie.BitArray)
164164
err := s.txn.Get(rootKeyDBKey, func(data []byte) error {
165-
val = data
165+
if len(data) > 0 {
166+
return rootKey.UnmarshalBinary(data)
167+
}
166168
return nil
167169
})
168170
// if some error other than "not found"
169171
if err != nil && !errors.Is(err, db.ErrKeyNotFound) {
170172
return nil, nil, err
171173
}
172174

173-
rootKey := new(trie.BitArray)
174-
if len(val) > 0 {
175-
err = rootKey.UnmarshalBinary(val)
176-
if err != nil {
177-
return nil, nil, err
178-
}
179-
}
180-
181175
gTrie, err := newTrie(s.txn, dbPrefix, globalTrieHeight)
182176
if err != nil {
183177
return nil, nil, err

db/remote/db_test.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,15 @@ func TestRemote(t *testing.T) {
4545
t.Run("Get", func(t *testing.T) {
4646
assert.NoError(t, remoteDB.View(func(txn db.Snapshot) error {
4747
for i := byte(0); i < 3; i++ {
48-
var val []byte
4948
err := txn.Get([]byte{i}, func(data []byte) error {
50-
val = data
49+
if !bytes.Equal(data, []byte{i}) {
50+
return errors.New("wrong value")
51+
}
5152
return nil
5253
})
5354
if err != nil {
5455
return err
5556
}
56-
if !bytes.Equal(val, []byte{i}) {
57-
return errors.New("wrong value")
58-
}
5957

6058
assert.Equal(t, db.ErrKeyNotFound, txn.Get([]byte{0xDE, 0xAD}, func(b []byte) error { return nil }))
6159
}

grpc/handlers.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,18 +76,16 @@ func (h Handler) handleTxCursor(
7676
responsePair.CursorId = cursorID
7777
return server.Send(responsePair)
7878
} else if cur.Op == gen.Op_GET {
79-
var val []byte
8079
err := tx.dbTx.Get(cur.K, func(data []byte) error {
81-
val = data
80+
if data != nil {
81+
responsePair.V = data
82+
responsePair.K = cur.K
83+
}
8284
return nil
8385
})
8486
if err != nil && !errors.Is(err, db.ErrKeyNotFound) {
8587
return err
8688
}
87-
if val != nil {
88-
responsePair.V = val
89-
responsePair.K = cur.K
90-
}
9189
return server.Send(responsePair)
9290
}
9391

migration/bucket_migrator_test.go

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,30 +45,26 @@ func TestBucketMover(t *testing.T) {
4545
require.NoError(t, err)
4646

4747
err = testDB.View(func(txn db.Snapshot) error {
48-
var val []byte
4948
err := txn.Get(sourceBucket.Key(), func(data []byte) error {
50-
val = data
49+
if !bytes.Equal(data, []byte{44}) {
50+
return errors.New("shouldnt have changed")
51+
}
5152
return nil
5253
})
5354
if err != nil {
5455
return err
5556
}
56-
if !bytes.Equal(val, []byte{44}) {
57-
return errors.New("shouldnt have changed")
58-
}
5957

6058
for i := byte(0); i < 3; i++ {
61-
var val []byte
6259
err := txn.Get(destBucket.Key([]byte{i}), func(data []byte) error {
63-
val = data
60+
if !bytes.Equal(data, []byte{i}) {
61+
return errors.New("shouldve moved")
62+
}
6463
return nil
6564
})
6665
if err != nil {
6766
return err
6867
}
69-
if !bytes.Equal(val, []byte{i}) {
70-
return errors.New("shouldve moved")
71-
}
7268

7369
err = txn.Get(sourceBucket.Key([]byte{i}), func([]byte) error { return nil })
7470
require.ErrorIs(t, db.ErrKeyNotFound, err)

migration/migration.go

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"context"
66
"encoding/binary"
7+
"encoding/hex"
78
"encoding/json"
89
"errors"
910
"fmt"
@@ -117,7 +118,7 @@ func migrateIfNeeded(
117118
new ones. It will be able to do this since the schema version it reads from the database will be
118119
non-zero and that is what we use to initialise the i loop variable.
119120
*/
120-
metadata, err := SchemaMetadata(targetDB)
121+
metadata, err := SchemaMetadata(log, targetDB)
121122
if err != nil {
122123
return err
123124
}
@@ -182,36 +183,34 @@ func closeMigrationServer(srv *http.Server, log utils.SimpleLogger) {
182183
}
183184

184185
// SchemaMetadata retrieves metadata about a database schema from the given database.
185-
func SchemaMetadata(targetDB db.KeyValueStore) (schemaMetadata, error) {
186+
func SchemaMetadata(log utils.SimpleLogger, targetDB db.KeyValueStore) (schemaMetadata, error) {
186187
metadata := schemaMetadata{}
187188
txn := targetDB
188189

189-
var sv []byte
190190
err := txn.Get(db.SchemaVersion.Key(), func(data []byte) error {
191-
sv = data
191+
metadata.Version = binary.BigEndian.Uint64(data)
192192
return nil
193193
})
194194
if err != nil && !errors.Is(err, db.ErrKeyNotFound) {
195195
return metadata, err
196196
}
197197

198-
if sv != nil {
199-
metadata.Version = binary.BigEndian.Uint64(sv)
200-
}
201-
202-
var is []byte
203198
err = txn.Get(db.SchemaIntermediateState.Key(), func(data []byte) error {
204-
is = data
199+
err := cbor.Unmarshal(data, &metadata.IntermediateState)
200+
if err != nil {
201+
// TODO: Instead of returning nil, we log the error for now to debug the issue
202+
log.Errorw(
203+
"Failed to unmarshal intermediate state",
204+
"version", metadata.Version,
205+
"state", hex.EncodeToString(data),
206+
"err", err,
207+
)
208+
}
205209
return nil
206210
})
207211
if err != nil && !errors.Is(err, db.ErrKeyNotFound) {
208212
return metadata, err
209213
}
210-
if is != nil {
211-
if err := cbor.Unmarshal(is, &metadata.IntermediateState); err != nil {
212-
return metadata, err
213-
}
214-
}
215214

216215
return metadata, nil
217216
}

migration/migration_pkg_test.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,16 @@ func TestRelocateContractStorageRootKeys(t *testing.T) {
6565
exampleBytes := new(felt.Felt).SetUint64(uint64(i)).Bytes()
6666

6767
// New entry exists.
68-
var val []byte
6968
err := txn.Get(db.ContractStorage.Key(exampleBytes[:]), func(data []byte) error {
70-
val = data
69+
require.Equal(
70+
t,
71+
exampleBytes[:],
72+
data,
73+
"the correct value was not transferred to the new location",
74+
)
7175
return nil
7276
})
7377
require.NoError(t, err)
74-
require.Equal(t, exampleBytes[:], val, "the correct value was not transferred to the new location")
7578

7679
// Old entry does not exist.
7780
oldKey := db.Peer.Key(exampleBytes[:])
@@ -400,7 +403,7 @@ func TestSchemaMetadata(t *testing.T) {
400403
t.Run("conversion", func(t *testing.T) {
401404
t.Run("version not set", func(t *testing.T) {
402405
testDB := memory.New()
403-
metadata, err := SchemaMetadata(testDB)
406+
metadata, err := SchemaMetadata(utils.NewNopZapLogger(), testDB)
404407
require.NoError(t, err)
405408
require.Equal(t, uint64(0), metadata.Version)
406409
require.Nil(t, metadata.IntermediateState)
@@ -414,7 +417,7 @@ func TestSchemaMetadata(t *testing.T) {
414417
return txn.Put(db.SchemaVersion.Key(), version[:])
415418
}))
416419

417-
metadata, err := SchemaMetadata(testDB)
420+
metadata, err := SchemaMetadata(utils.NewNopZapLogger(), testDB)
418421
require.NoError(t, err)
419422
require.Equal(t, uint64(1), metadata.Version)
420423
require.Nil(t, metadata.IntermediateState)
@@ -430,7 +433,7 @@ func TestSchemaMetadata(t *testing.T) {
430433
IntermediateState: nil,
431434
})
432435
}))
433-
metadata, err := SchemaMetadata(testDB)
436+
metadata, err := SchemaMetadata(utils.NewNopZapLogger(), testDB)
434437
require.NoError(t, err)
435438
require.Equal(t, version, metadata.Version)
436439
require.Nil(t, metadata.IntermediateState)
@@ -448,7 +451,7 @@ func TestSchemaMetadata(t *testing.T) {
448451
IntermediateState: intermediateState,
449452
})
450453
}))
451-
metadata, err := SchemaMetadata(testDB)
454+
metadata, err := SchemaMetadata(utils.NewNopZapLogger(), testDB)
452455
require.NoError(t, err)
453456
require.Equal(t, version, metadata.Version)
454457
require.Equal(t, intermediateState, metadata.IntermediateState)
@@ -466,7 +469,7 @@ func TestSchemaMetadata(t *testing.T) {
466469
IntermediateState: intermediateState,
467470
})
468471
}))
469-
metadata, err := SchemaMetadata(testDB)
472+
metadata, err := SchemaMetadata(utils.NewNopZapLogger(), testDB)
470473
require.NoError(t, err)
471474
require.Equal(t, version, metadata.Version)
472475
require.Equal(t, intermediateState, metadata.IntermediateState)

migration/migration_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ func TestMigrateIfNeeded(t *testing.T) {
1919
require.ErrorIs(t, migration.MigrateIfNeeded(ctx, testDB, &utils.Mainnet, utils.NewNopZapLogger(), &migration.HTTPConfig{}), ctx.Err())
2020
})
2121

22-
meta, err := migration.SchemaMetadata(testDB)
22+
meta, err := migration.SchemaMetadata(utils.NewNopZapLogger(), testDB)
2323
require.NoError(t, err)
2424
require.Equal(t, uint64(0), meta.Version)
2525
require.Nil(t, meta.IntermediateState)
@@ -28,14 +28,14 @@ func TestMigrateIfNeeded(t *testing.T) {
2828
require.NoError(t, migration.MigrateIfNeeded(t.Context(), testDB, &utils.Mainnet, utils.NewNopZapLogger(), &migration.HTTPConfig{}))
2929
})
3030

31-
meta, err = migration.SchemaMetadata(testDB)
31+
meta, err = migration.SchemaMetadata(utils.NewNopZapLogger(), testDB)
3232
require.NoError(t, err)
3333
require.NotEqual(t, uint64(0), meta.Version)
3434
require.Nil(t, meta.IntermediateState)
3535

3636
t.Run("subsequent calls to MigrateIfNeeded should not change the DB version", func(t *testing.T) {
3737
require.NoError(t, migration.MigrateIfNeeded(t.Context(), testDB, &utils.Mainnet, utils.NewNopZapLogger(), &migration.HTTPConfig{}))
38-
postVersion, postErr := migration.SchemaMetadata(testDB)
38+
postVersion, postErr := migration.SchemaMetadata(utils.NewNopZapLogger(), testDB)
3939
require.NoError(t, postErr)
4040
require.Equal(t, meta, postVersion)
4141
})

0 commit comments

Comments
 (0)