From 19cb6d046aac92f44722c17ba9a371b08ca0be6a Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sun, 17 Feb 2019 17:05:05 +0100 Subject: nametransform: reject names longer than 255 chars Looks like we allowed creating longer names by accident. Fix that, and add a test that verifies it. --- internal/fusefrontend/openbackingdir.go | 12 ++++++++++-- internal/nametransform/diriv.go | 15 +++++++++------ internal/nametransform/names.go | 5 +++++ 3 files changed, 24 insertions(+), 8 deletions(-) (limited to 'internal') diff --git a/internal/fusefrontend/openbackingdir.go b/internal/fusefrontend/openbackingdir.go index 1cca81b..e9e10db 100644 --- a/internal/fusefrontend/openbackingdir.go +++ b/internal/fusefrontend/openbackingdir.go @@ -38,7 +38,11 @@ func (fs *FS) openBackingDir(relPath string) (dirfd int, cName string, err error return dirfd, ".", nil } name := filepath.Base(relPath) - cName = fs.nameTransform.EncryptAndHashName(name, iv) + cName, err = fs.nameTransform.EncryptAndHashName(name, iv) + if err != nil { + syscall.Close(dirfd) + return -1, "", err + } return dirfd, cName, nil } // Open cipherdir (following symlinks) @@ -58,7 +62,11 @@ func (fs *FS) openBackingDir(relPath string) (dirfd int, cName string, err error syscall.Close(dirfd) return -1, "", err } - cName = fs.nameTransform.EncryptAndHashName(name, iv) + cName, err = fs.nameTransform.EncryptAndHashName(name, iv) + if err != nil { + syscall.Close(dirfd) + return -1, "", err + } // Last part? We are done. if i == len(parts)-1 { fs.dirCache.Store(dirRelPath, dirfd, iv) diff --git a/internal/nametransform/diriv.go b/internal/nametransform/diriv.go index 09e9dd5..da33aee 100644 --- a/internal/nametransform/diriv.go +++ b/internal/nametransform/diriv.go @@ -8,8 +8,6 @@ import ( "path/filepath" "syscall" - "golang.org/x/sys/unix" - "github.com/rfjakob/gocryptfs/internal/cryptocore" "github.com/rfjakob/gocryptfs/internal/syscallcompat" "github.com/rfjakob/gocryptfs/internal/tlog" @@ -97,12 +95,17 @@ func WriteDirIVAt(dirfd int) error { // encryptAndHashName encrypts "name" and hashes it to a longname if it is // too long. -func (be *NameTransform) EncryptAndHashName(name string, iv []byte) string { +// Returns ENAMETOOLONG if "name" is longer than 255 bytes. +func (be *NameTransform) EncryptAndHashName(name string, iv []byte) (string, error) { + // Prevent the user from creating files longer than 255 chars. + if len(name) > NameMax { + return "", syscall.ENAMETOOLONG + } cName := be.EncryptName(name, iv) - if be.longNames && len(cName) > unix.NAME_MAX { - return be.HashLongName(cName) + if be.longNames && len(cName) > NameMax { + return be.HashLongName(cName), nil } - return cName + return cName, nil } // Dir is like filepath.Dir but returns "" instead of ".". diff --git a/internal/nametransform/names.go b/internal/nametransform/names.go index 638a9eb..20fbede 100644 --- a/internal/nametransform/names.go +++ b/internal/nametransform/names.go @@ -12,6 +12,11 @@ import ( "github.com/rfjakob/gocryptfs/internal/tlog" ) +const ( + // Like ext4, we allow at most 255 bytes for a file name. + NameMax = 255 +) + // NameTransform is used to transform filenames. type NameTransform struct { emeCipher *eme.EMECipher -- cgit v1.2.3