macaroons: ensure all bytes read from db are copied before returning

This commit is a precautionary commit put in place in order to ensure
that the logic of macaroon retrieval doesn’t run into a bug triggered
by returning a reference into bolt’s active memory map. This can arise
if one returns a pointer directly read from the database. We seek to
avoid this by instead ensuring all byte slices are fully copied before
returning.
This commit is contained in:
Olaoluwa Osuntokun 2017-08-23 11:30:09 -07:00
parent ae5afcf555
commit 6e3abdfd14
No known key found for this signature in database
GPG Key ID: 9CC5B105D03521A2

@ -52,11 +52,14 @@ func NewRootKeyStorage(db *bolt.DB) (*RootKeyStorage, error) {
func (r *RootKeyStorage) Get(id string) ([]byte, error) {
var rootKey []byte
err := r.View(func(tx *bolt.Tx) error {
rootKey = tx.Bucket(rootKeyBucketName).Get([]byte(id))
if len(rootKey) == 0 {
dbKey := tx.Bucket(rootKeyBucketName).Get([]byte(id))
if len(dbKey) == 0 {
return fmt.Errorf("root key with id %s doesn't exist",
id)
}
rootKey = make([]byte, len(dbKey))
copy(rootKey[:], dbKey)
return nil
})
if err != nil {
@ -127,21 +130,23 @@ func (s *Storage) Put(location string, item string) error {
// Get implements the Get method for the bakery.Storage interface.
func (s *Storage) Get(location string) (string, error) {
var item string
var item []byte
err := s.View(func(tx *bolt.Tx) error {
itemBytes := tx.Bucket(macaroonBucketName).Get([]byte(location))
if len(itemBytes) == 0 {
return fmt.Errorf("couldn't get item for location %s",
location)
}
item = string(itemBytes)
item = make([]byte, len(itemBytes))
copy(item, itemBytes)
return nil
})
if err != nil {
return "", err
}
return item, nil
return string(item), nil
}
// Del implements the Del method for the bakery.Storage interface.