Skip to content

Commit

Permalink
fix following dead lock problems
Browse files Browse the repository at this point in the history
1. RLock -> RLock
2. RLock -> Lock
  • Loading branch information
wodadehencou committed Apr 20, 2020
1 parent 62d42e3 commit 022edf8
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 29 deletions.
5 changes: 1 addition & 4 deletions buffer.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,10 +314,7 @@ func (b *LockedBuffer) Scramble() {
return
}

b.Lock()
defer b.Unlock()

core.Scramble(b.Bytes())
b.Buffer.Scramble()
}

/*
Expand Down
41 changes: 36 additions & 5 deletions core/buffer.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ func NewBuffer(size int) (*Buffer, error) {
}

// Initialise the canary value and reference regions.
Scramble(b.canary)
if err := Scramble(b.canary); err != nil {
Panic(err)
}
Copy(b.preguard, b.canary)
Copy(b.postguard, b.canary)

Expand Down Expand Up @@ -111,44 +113,73 @@ func (b *Buffer) Inner() []byte {

// Freeze makes the underlying memory of a given buffer immutable. This will do nothing if the Buffer has been destroyed.
func (b *Buffer) Freeze() {
if err := b.freeze(); err != nil {
Panic(err)
}
}

func (b *Buffer) freeze() error {
// Attain lock.
b.Lock()
defer b.Unlock()

// Check if destroyed.
if !b.alive {
return
return nil
}

// Only do anything if currently mutable.
if b.mutable {
// Make the memory immutable.
if err := memcall.Protect(b.inner, memcall.ReadOnly()); err != nil {
Panic(err)
return err
}
b.mutable = false
}

return nil
}

// Melt makes the underlying memory of a given buffer mutable. This will do nothing if the Buffer has been destroyed.
func (b *Buffer) Melt() {
if err := b.melt(); err != nil {
Panic(err)
}
}

func (b *Buffer) melt() error {
// Attain lock.
b.Lock()
defer b.Unlock()

// Check if destroyed.
if !b.alive {
return
return nil
}

// Only do anything if currently immutable.
if !b.mutable {
// Make the memory mutable.
if err := memcall.Protect(b.inner, memcall.ReadWrite()); err != nil {
Panic(err)
return err
}
b.mutable = true
}
return nil
}

// Scramble attempts to overwrite the data with cryptographically-secure random bytes.
func (b *Buffer) Scramble() {
if err := b.scramble(); err != nil {
Panic(err)
}
}

func (b *Buffer) scramble() error {
// Attain lock.
b.Lock()
defer b.Unlock()
return Scramble(b.Data())
}

/*
Expand Down
64 changes: 49 additions & 15 deletions core/coffer.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,24 @@ func (s *Coffer) Initialise() error {
return ErrCofferExpired
}

if err := s.initialise(); err != nil {
Panic(err)
}
return nil
}

func (s *Coffer) initialise() error {
// Attain the mutex.
s.Lock()
defer s.Unlock()

// Overwrite the old value with fresh random bytes.
Scramble(s.left.Data())
Scramble(s.right.Data())
if err := Scramble(s.left.Data()); err != nil {
return err
}
if err := Scramble(s.right.Data()); err != nil {
return err
}

// left = left XOR hash(right)
hr := Hash(s.right.Data())
Expand All @@ -83,18 +94,18 @@ func (s *Coffer) Initialise() error {
View returns a snapshot of the contents of a Coffer inside a Buffer. As usual the Buffer should be destroyed as soon as possible after use by calling the Destroy method.
*/
func (s *Coffer) View() (*Buffer, error) {
// Attain a read-only lock.
s.RLock()
defer s.RUnlock()

// Check if it's destroyed.
if s.destroyed() {
if s.Destroyed() {
return nil, ErrCofferExpired
}

// Create a new Buffer for the data.
b, _ := NewBuffer(32)

// Attain a read-only lock.
s.RLock()
defer s.RUnlock()

// data = hash(right) XOR left
h := Hash(s.right.Data())
for i := range b.Data() {
Expand All @@ -115,12 +126,21 @@ func (s *Coffer) Rekey() error {
return ErrCofferExpired
}

if err := s.rekey(); err != nil {
Panic(err)
}
return nil
}

func (s *Coffer) rekey() error {
// Attain the mutex.
s.Lock()
defer s.Unlock()

// Attain 32 bytes of fresh cryptographic buf32.
Scramble(s.rand.Data())
if err := Scramble(s.rand.Data()); err != nil {
return err
}

// Hash the current right partition for later.
hashRightCurrent := Hash(s.right.Data())
Expand All @@ -144,24 +164,38 @@ func (s *Coffer) Rekey() error {
Destroy wipes and cleans up all memory related to a Coffer object. Once this method has been called, the Coffer can no longer be used and a new one should be created instead.
*/
func (s *Coffer) Destroy() {
if err := s.destroy(); err != nil {
Panic(err)
}
}

func (s *Coffer) destroy() error {
// Attain the mutex.
s.Lock()
defer s.Unlock()

// Destroy the partitions.
s.left.Destroy()
s.right.Destroy()
s.rand.Destroy()
if err := s.left.destroy(); err != nil {
return err
}
buffers.remove(s.rand)

if err := s.right.destroy(); err != nil {
return err
}
buffers.remove(s.rand)

if err := s.rand.destroy(); err != nil {
return err
}
buffers.remove(s.rand)
return nil
}

// Destroyed returns a boolean value indicating if a Coffer has been destroyed.
func (s *Coffer) Destroyed() bool {
s.RLock()
defer s.RUnlock()

return s.destroyed()
}

func (s *Coffer) destroyed() bool {
return (!s.left.Alive()) && (!s.right.Alive())
}
9 changes: 6 additions & 3 deletions core/crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ func Encrypt(plaintext, key []byte) ([]byte, error) {

// Allocate space for and generate a nonce value.
var nonce [24]byte
Scramble(nonce[:])
if err := Scramble(nonce[:]); err != nil {
Panic(err)
}

// Encrypt m and return the result.
return secretbox.Seal(nonce[:], plaintext, &nonce, k), nil
Expand Down Expand Up @@ -84,13 +86,14 @@ func Hash(b []byte) []byte {
}

// Scramble fills a given buffer with cryptographically-secure random bytes.
func Scramble(buf []byte) {
func Scramble(buf []byte) error {
if _, err := rand.Read(buf); err != nil {
Panic(err)
return err
}

// See Wipe
runtime.KeepAlive(buf)
return nil
}

// Wipe takes a buffer and wipes it with zeroes.
Expand Down
3 changes: 2 additions & 1 deletion core/enclave.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ func Seal(b *Buffer) (*Enclave, error) {
return nil, ErrBufferExpired
}

b.Melt() // Make the buffer mutable so that we can wipe it.

// Construct the Enclave from the Buffer's data.
e, err := func() (*Enclave, error) {
b.RLock() // Attain a read lock.
Expand All @@ -77,7 +79,6 @@ func Seal(b *Buffer) (*Enclave, error) {
}

// Destroy the Buffer object.
b.Melt() // Make the buffer mutable so that we can wipe it.
b.Destroy()

// Return the newly created Enclave.
Expand Down
4 changes: 3 additions & 1 deletion memguard.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import (
ScrambleBytes overwrites an arbitrary buffer with cryptographically-secure random bytes.
*/
func ScrambleBytes(buf []byte) {
core.Scramble(buf)
if err := core.Scramble(buf); err != nil {
core.Panic(err)
}
}

/*
Expand Down

0 comments on commit 022edf8

Please sign in to comment.