summaryrefslogtreecommitdiff
path: root/internal/nametransform/names.go
diff options
context:
space:
mode:
authorJakob Unterwurzacher2017-05-07 20:58:27 +0200
committerJakob Unterwurzacher2017-05-07 20:58:27 +0200
commit26881538e1753e613b4143b28fa339812a9a6d16 (patch)
tree6fbf74a26518b337380789c6bdc90380ed99d569 /internal/nametransform/names.go
parent68387b470c0d6d2896cc6b927a6e3097389d66ab (diff)
nametranform, fusefrontend: better errors on invalid names
nametransform.DecryptName() now always returns syscall.EBADMSG if the name was invalid. fusefrontend.OpenDir error messages have been normalized.
Diffstat (limited to 'internal/nametransform/names.go')
-rw-r--r--internal/nametransform/names.go18
1 files changed, 11 insertions, 7 deletions
diff --git a/internal/nametransform/names.go b/internal/nametransform/names.go
index 71c8cd3..c96f7ce 100644
--- a/internal/nametransform/names.go
+++ b/internal/nametransform/names.go
@@ -2,6 +2,7 @@
package nametransform
import (
+ "bytes"
"crypto/aes"
"encoding/base64"
"syscall"
@@ -34,10 +35,8 @@ func New(e *eme.EMECipher, longNames bool, raw64 bool) *NameTransform {
}
}
-// DecryptName - decrypt base64-encoded encrypted filename "cipherName"
-//
-// This function is exported because it allows for a very efficient readdir
-// implementation (read IV once, decrypt all names using this function).
+// DecryptName decrypts a base64-encoded encrypted filename "cipherName" using the
+// initialization vector "iv".
func (n *NameTransform) DecryptName(cipherName string, iv []byte) (string, error) {
bin, err := n.B64.DecodeString(cipherName)
if err != nil {
@@ -45,16 +44,21 @@ func (n *NameTransform) DecryptName(cipherName string, iv []byte) (string, error
}
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.EINVAL
+ return "", syscall.EBADMSG
}
bin = n.emeCipher.Decrypt(iv, bin)
bin, err = unPad16(bin)
if err != nil {
- tlog.Debug.Printf("pad16 error detail: %v", err)
+ tlog.Debug.Printf("DecryptName: unPad16 error: %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.EINVAL
+ 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.
+ if bytes.Contains(bin, []byte{0}) || bytes.Contains(bin, []byte("/")) {
+ return "", syscall.EBADMSG
}
plain := string(bin)
return plain, err