aboutsummaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorJakob Unterwurzacher2017-10-19 09:23:10 +0200
committerJakob Unterwurzacher2017-10-19 09:23:10 +0200
commit29445c976d200f6e734eae56d9665fd4098f0a43 (patch)
tree10ccf7ff0c46e1eaa5f649974c0a9c23e406440f /internal
parent2783eadc8f69ae5803a75dbfccd7ea1862cdfe51 (diff)
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.
Diffstat (limited to 'internal')
-rw-r--r--internal/contentenc/content.go16
1 files changed, 12 insertions, 4 deletions
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)
}