summaryrefslogtreecommitdiff
path: root/internal/nametransform/names.go
diff options
context:
space:
mode:
authorJakob Unterwurzacher2017-05-23 20:46:24 +0200
committerJakob Unterwurzacher2017-05-23 21:26:38 +0200
commite827763f2e6226d9f5778d56c28270264950c0f5 (patch)
tree2f5f4adeed482dd473cc4714b97a8903806fdbb3 /internal/nametransform/names.go
parent508fd9e1d64131958c86175cb8d848f730e629cf (diff)
nametransform: harden name decryption against invalid input
This fixes a few issues I have found reviewing the code: 1) Limit the amount of data ReadLongName() will read. Previously, you could send gocryptfs into out-of-memory by symlinking gocryptfs.diriv to /dev/zero. 2) Handle the empty input case in unPad16() by returning an error. Previously, it would panic with an out-of-bounds array read. It is unclear to me if this could actually be triggered. 3) Reject empty names after base64-decoding in DecryptName(). An empty name crashes emeCipher.Decrypt(). It is unclear to me if B64.DecodeString() can actually return a non-error empty result, but let's guard against it anyway.
Diffstat (limited to 'internal/nametransform/names.go')
-rw-r--r--internal/nametransform/names.go8
1 files changed, 6 insertions, 2 deletions
diff --git a/internal/nametransform/names.go b/internal/nametransform/names.go
index c96f7ce..3447583 100644
--- a/internal/nametransform/names.go
+++ b/internal/nametransform/names.go
@@ -42,6 +42,10 @@ func (n *NameTransform) DecryptName(cipherName string, iv []byte) (string, error
if err != nil {
return "", err
}
+ if len(bin) == 0 {
+ tlog.Warn.Printf("DecryptName: empty input")
+ return "", syscall.EBADMSG
+ }
if len(bin)%aes.BlockSize != 0 {
tlog.Debug.Printf("DecryptName %q: decoded length %d is not a multiple of 16", cipherName, len(bin))
return "", syscall.EBADMSG
@@ -49,14 +53,14 @@ func (n *NameTransform) DecryptName(cipherName string, iv []byte) (string, error
bin = n.emeCipher.Decrypt(iv, bin)
bin, err = unPad16(bin)
if err != nil {
- tlog.Debug.Printf("DecryptName: unPad16 error: %v", err)
+ tlog.Debug.Printf("DecryptName: unPad16 error detail: %v", err)
// unPad16 returns detailed errors including the position of the
// incorrect bytes. Kill the padding oracle by lumping everything into
// a generic error.
return "", syscall.EBADMSG
}
// A name can never contain a null byte or "/". Make sure we never return those
- // to the user, even when we read a corrupted (or fuzzed) filesystem.
+ // to the kernel, even when we read a corrupted (or fuzzed) filesystem.
if bytes.Contains(bin, []byte{0}) || bytes.Contains(bin, []byte("/")) {
return "", syscall.EBADMSG
}