mirror of
https://github.com/lightninglabs/lightning-terminal.git
synced 2026-08-13 12:33:36 +02:00
accounts: copy bbolt values before closing read transaction
bucket.Get returns a byte slice that points directly into bbolt's mmap'd file. This slice is only valid for the lifetime of the transaction. In Account() and LastIndexes(), the slices were escaping the View callback and being read after the transaction closed. Under concurrent write transactions the file gets remapped, invalidating the pointer and causing a segmentation fault. Copy the byte slices inside the transaction so deserialization operates on stable, heap-allocated memory.
This commit is contained in:
parent
50376dd429
commit
21933e8c8e
1 changed files with 20 additions and 6 deletions
|
|
@ -457,11 +457,17 @@ func (s *BoltStore) Account(_ context.Context, id AccountID) (
|
|||
return ErrAccountBucketNotFound
|
||||
}
|
||||
|
||||
accountBinary = bucket.Get(id[:])
|
||||
if len(accountBinary) == 0 {
|
||||
v := bucket.Get(id[:])
|
||||
if len(v) == 0 {
|
||||
return ErrAccNotFound
|
||||
}
|
||||
|
||||
// Copy the value since bbolt's Get returns a slice into
|
||||
// the mmap'd file that is only valid for the lifetime of
|
||||
// the transaction.
|
||||
accountBinary = make([]byte, len(v))
|
||||
copy(accountBinary, v)
|
||||
|
||||
return nil
|
||||
}, func() {
|
||||
accountBinary = nil
|
||||
|
|
@ -560,16 +566,24 @@ func (s *BoltStore) LastIndexes(_ context.Context) (uint64, uint64, error) {
|
|||
return ErrAccountBucketNotFound
|
||||
}
|
||||
|
||||
addValue = bucket.Get(lastAddIndexKey)
|
||||
if len(addValue) == 0 {
|
||||
av := bucket.Get(lastAddIndexKey)
|
||||
if len(av) == 0 {
|
||||
return ErrNoInvoiceIndexKnown
|
||||
}
|
||||
|
||||
settleValue = bucket.Get(lastSettleIndexKey)
|
||||
if len(settleValue) == 0 {
|
||||
sv := bucket.Get(lastSettleIndexKey)
|
||||
if len(sv) == 0 {
|
||||
return ErrNoInvoiceIndexKnown
|
||||
}
|
||||
|
||||
// Copy values since bbolt's Get returns slices into the
|
||||
// mmap'd file, only valid within the transaction.
|
||||
addValue = make([]byte, len(av))
|
||||
copy(addValue, av)
|
||||
|
||||
settleValue = make([]byte, len(sv))
|
||||
copy(settleValue, sv)
|
||||
|
||||
return nil
|
||||
}, func() {
|
||||
addValue, settleValue = nil, nil
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue