From 29445c976d200f6e734eae56d9665fd4098f0a43 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Thu, 19 Oct 2017 09:23:10 +0200 Subject: contentenc: reserve one additional block in CReqPool ...to account for unaligned reads. I have not seen this happen in the wild because the kernel always seems to issue 4k-aligned requests. But the cost of the additional block in the pool is low and prevents a buffer overrun panic when an unaligned read does happen. --- internal/contentenc/content.go | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'internal/contentenc') diff --git a/internal/contentenc/content.go b/internal/contentenc/content.go index e6f79a6..e2a531c 100644 --- a/internal/contentenc/content.go +++ b/internal/contentenc/content.go @@ -53,13 +53,18 @@ type ContentEnc struct { allZeroNonce []byte // Force decode even if integrity check fails (openSSL only) forceDecode bool - // Ciphertext block pool. Always returns cipherBS-sized byte slices. + + // Ciphertext block "sync.Pool" pool. Always returns cipherBS-sized byte + // slices (usually 4128 bytes). cBlockPool bPool + // Plaintext block pool. Always returns plainBS-sized byte slices + // (usually 4096 bytes). + pBlockPool bPool // Ciphertext request data pool. Always returns byte slices of size - // fuse.MAX_KERNEL_WRITE + overhead. + // fuse.MAX_KERNEL_WRITE + encryption overhead. + // Used by Read() to temporarily store the ciphertext as it is read from + // disk. CReqPool bPool - // Plaintext block pool. Always returns plainBS-sized byte slices. - pBlockPool bPool // Plaintext request data pool. Slice have size fuse.MAX_KERNEL_WRITE. PReqPool bPool } @@ -69,6 +74,9 @@ func New(cc *cryptocore.CryptoCore, plainBS uint64, forceDecode bool) *ContentEn 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. + cReqSize += int(cipherBS) if fuse.MAX_KERNEL_WRITE%plainBS != 0 { log.Panicf("unaligned MAX_KERNEL_WRITE=%d", fuse.MAX_KERNEL_WRITE) } -- cgit v1.2.3