diff options
author | Jakob Unterwurzacher | 2018-07-15 11:39:07 +0200 |
---|---|---|
committer | Jakob Unterwurzacher | 2018-07-15 11:39:19 +0200 |
commit | bcca323cb778d3ab9bf3b16e041ede5e67b18ff8 (patch) | |
tree | 401ec7398ad2fc53e29853b342461560b1ac75ce /internal | |
parent | 38f79a1abc2733b77c90cdf07b0643bd8819b968 (diff) |
contentenc: reserve one extra block in pool plaintext buffers
File holes and -fsck can cause unaligned read accesses, which means
we have to decrypt one extra plaintext block.
xfstests generic/083 manage to crash -fsck like this:
generic/083 2018/07/14 15:25:21 wrong len=266240, want=131072
panic: wrong len=266240, want=131072
goroutine 1 [running]:
log.Panicf(0x67fc00, 0x15, 0xc4204fec90, 0x2, 0x2)
/usr/local/go/src/log/log.go:333 +0xda
github.com/rfjakob/gocryptfs/internal/contentenc.(*bPool).Put(0xc4200d4800, 0xc4202f2000, 0x21000, 0x41000)
/home/jakob/go/src/github.com/rfjakob/gocryptfs/internal/contentenc/bpool.go:27 +0x15d
github.com/rfjakob/gocryptfs/internal/fusefrontend.(*File).doRead(0xc4200b4500, 0xc42019e000, 0x0, 0x20000, 0x28400, 0x20000, 0xc42019e000, 0xc4204ff008, 0x435164, 0xc420000180)
/home/jakob/go/src/github.com/rfjakob/gocryptfs/internal/fusefrontend/file.go:227 +0xba9
github.com/rfjakob/gocryptfs/internal/fusefrontend.(*File).Read(0xc4200b4500, 0xc42019e000, 0x20000, 0x20000, 0x28400, 0x0, 0x0, 0x0)
/home/jakob/go/src/github.com/rfjakob/gocryptfs/internal/fusefrontend/file.go:246 +0x23e
main.(*fsckObj).file(0xc420069320, 0xc42001a630, 0x21)
/home/jakob/go/src/github.com/rfjakob/gocryptfs/fsck.go:126 +0x21f
main.(*fsckObj).dir(0xc420069320, 0xc420014dc0, 0x1d)
/home/jakob/go/src/github.com/rfjakob/gocryptfs/fsck.go:76 +0x387
main.(*fsckObj).dir(0xc420069320, 0xc42021dae0, 0x19)
/home/jakob/go/src/github.com/rfjakob/gocryptfs/fsck.go:74 +0x347
Diffstat (limited to 'internal')
-rw-r--r-- | internal/contentenc/content.go | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/internal/contentenc/content.go b/internal/contentenc/content.go index 76b486d..57ad489 100644 --- a/internal/contentenc/content.go +++ b/internal/contentenc/content.go @@ -71,15 +71,17 @@ type ContentEnc struct { // New returns an initialized ContentEnc instance. func New(cc *cryptocore.CryptoCore, plainBS uint64, forceDecode bool) *ContentEnc { + if fuse.MAX_KERNEL_WRITE%plainBS != 0 { + log.Panicf("unaligned MAX_KERNEL_WRITE=%d", fuse.MAX_KERNEL_WRITE) + } cipherBS := plainBS + uint64(cc.IVLen) + cryptocore.AuthTagLen // Take IV and GHASH overhead into account. cReqSize := int(fuse.MAX_KERNEL_WRITE / plainBS * cipherBS) - // An unaligned read (could happen with O_DIRECT?) may touch one - // additional ciphertext block. Reserve space for it. + // Unaligned reads (happens during fsck, could also happen with O_DIRECT?) + // touch one additional ciphertext and plaintext block. Reserve space for the + // extra block. cReqSize += int(cipherBS) - if fuse.MAX_KERNEL_WRITE%plainBS != 0 { - log.Panicf("unaligned MAX_KERNEL_WRITE=%d", fuse.MAX_KERNEL_WRITE) - } + pReqSize := fuse.MAX_KERNEL_WRITE + int(plainBS) c := &ContentEnc{ cryptoCore: cc, plainBS: plainBS, @@ -90,7 +92,7 @@ func New(cc *cryptocore.CryptoCore, plainBS uint64, forceDecode bool) *ContentEn cBlockPool: newBPool(int(cipherBS)), CReqPool: newBPool(cReqSize), pBlockPool: newBPool(int(plainBS)), - PReqPool: newBPool(fuse.MAX_KERNEL_WRITE), + PReqPool: newBPool(pReqSize), } return c } |