From d99a0480f712d4fd1c2012c57a9e1c938d70c9fe Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Wed, 2 Jan 2019 00:07:20 +0100 Subject: [PATCH] nametransform: fix possible incomplete read in ReadLongNameAt Pread() needs retry logic, so instead of implementing it ourselves, use os.File. Reported by @slackner at https://github.com/rfjakob/gocryptfs/commit/c09bf1f2284706232642431c75fa1f3d8500a9d0#r31813394 --- internal/nametransform/longnames.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/internal/nametransform/longnames.go b/internal/nametransform/longnames.go index f0f0490..6fc080b 100644 --- a/internal/nametransform/longnames.go +++ b/internal/nametransform/longnames.go @@ -74,16 +74,21 @@ func IsLongContent(cName string) bool { // Symlink-safe through Openat(). func ReadLongNameAt(dirfd int, cName string) (string, error) { cName += LongNameSuffix - fd, err := syscallcompat.Openat(dirfd, cName, syscall.O_NOFOLLOW, 0) - if err != nil { - return "", err + var f *os.File + { + fd, err := syscallcompat.Openat(dirfd, cName, syscall.O_NOFOLLOW, 0) + if err != nil { + return "", err + } + f = os.NewFile(uintptr(fd), "") + // fd runs out of scope here } - defer syscall.Close(fd) + defer f.Close() // 256 (=255 padded to 16) bytes base64-encoded take 344 bytes: "AAAAAAA...AAA==" lim := 344 // Allocate a bigger buffer so we see whether the file is too big buf := make([]byte, lim+1) - n, err := syscall.Pread(fd, buf, 0) + n, err := f.ReadAt(buf, 0) if err != nil && err != io.EOF { return "", err }