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.
This commit is contained in:
parent
2783eadc8f
commit
29445c976d
@ -53,13 +53,18 @@ type ContentEnc struct {
|
|||||||
allZeroNonce []byte
|
allZeroNonce []byte
|
||||||
// Force decode even if integrity check fails (openSSL only)
|
// Force decode even if integrity check fails (openSSL only)
|
||||||
forceDecode bool
|
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
|
cBlockPool bPool
|
||||||
// Ciphertext request data pool. Always returns byte slices of size
|
// Plaintext block pool. Always returns plainBS-sized byte slices
|
||||||
// fuse.MAX_KERNEL_WRITE + overhead.
|
// (usually 4096 bytes).
|
||||||
CReqPool bPool
|
|
||||||
// Plaintext block pool. Always returns plainBS-sized byte slices.
|
|
||||||
pBlockPool bPool
|
pBlockPool bPool
|
||||||
|
// Ciphertext request data pool. Always returns byte slices of size
|
||||||
|
// fuse.MAX_KERNEL_WRITE + encryption overhead.
|
||||||
|
// Used by Read() to temporarily store the ciphertext as it is read from
|
||||||
|
// disk.
|
||||||
|
CReqPool bPool
|
||||||
// Plaintext request data pool. Slice have size fuse.MAX_KERNEL_WRITE.
|
// Plaintext request data pool. Slice have size fuse.MAX_KERNEL_WRITE.
|
||||||
PReqPool bPool
|
PReqPool bPool
|
||||||
}
|
}
|
||||||
@ -69,6 +74,9 @@ func New(cc *cryptocore.CryptoCore, plainBS uint64, forceDecode bool) *ContentEn
|
|||||||
cipherBS := plainBS + uint64(cc.IVLen) + cryptocore.AuthTagLen
|
cipherBS := plainBS + uint64(cc.IVLen) + cryptocore.AuthTagLen
|
||||||
// Take IV and GHASH overhead into account.
|
// Take IV and GHASH overhead into account.
|
||||||
cReqSize := int(fuse.MAX_KERNEL_WRITE / plainBS * cipherBS)
|
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 {
|
if fuse.MAX_KERNEL_WRITE%plainBS != 0 {
|
||||||
log.Panicf("unaligned MAX_KERNEL_WRITE=%d", fuse.MAX_KERNEL_WRITE)
|
log.Panicf("unaligned MAX_KERNEL_WRITE=%d", fuse.MAX_KERNEL_WRITE)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user