fusefrontend: catch ReadAt integer overflow
Discovered by xfstests generic/564 . Failure was: generic/564 - output mismatch (see /opt/fuse-xfstests/results//generic/564.out.bad) --- tests/generic/564.out 2021-05-08 21:11:05.307395966 +0200 +++ /opt/fuse-xfstests/results//generic/564.out.bad 2021-05-19 19:01:16.912888879 +0200 @@ -31,7 +31,7 @@ source range beyond 8TiB returns 0 destination range beyond 8TiB returns EFBIG -copy_range: File too large +copy_range: Function not implemented
This commit is contained in:
parent
04858ddd22
commit
b23e21f61f
@ -9,6 +9,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"math"
|
||||
"os"
|
||||
"sync"
|
||||
"syscall"
|
||||
@ -178,6 +179,10 @@ func (f *File) doRead(dst []byte, off uint64, length uint64) ([]byte, syscall.Er
|
||||
// Read the backing ciphertext in one go
|
||||
blocks := f.contentEnc.ExplodePlainRange(off, length)
|
||||
alignedOffset, alignedLength := blocks[0].JointCiphertextRange(blocks)
|
||||
// f.fd.ReadAt takes an int64!
|
||||
if alignedOffset > math.MaxInt64 {
|
||||
return nil, syscall.EFBIG
|
||||
}
|
||||
skip := blocks[0].Skip
|
||||
tlog.Debug.Printf("doRead: off=%d len=%d -> off=%d len=%d skip=%d\n",
|
||||
off, length, alignedOffset, alignedLength, skip)
|
||||
@ -320,9 +325,13 @@ func (f *File) doWrite(data []byte, off int64) (uint32, syscall.Errno) {
|
||||
// Preallocate so we cannot run out of space in the middle of the write.
|
||||
// This prevents partially written (=corrupt) blocks.
|
||||
var err error
|
||||
cOff := int64(blocks[0].BlockCipherOff())
|
||||
cOff := blocks[0].BlockCipherOff()
|
||||
// f.fd.WriteAt & syscallcompat.EnospcPrealloc take int64 offsets!
|
||||
if cOff > math.MaxInt64 {
|
||||
return 0, syscall.EFBIG
|
||||
}
|
||||
if !f.rootNode.args.NoPrealloc {
|
||||
err = syscallcompat.EnospcPrealloc(f.intFd(), cOff, int64(len(ciphertext)))
|
||||
err = syscallcompat.EnospcPrealloc(f.intFd(), int64(cOff), int64(len(ciphertext)))
|
||||
if err != nil {
|
||||
if !syscallcompat.IsENOSPC(err) {
|
||||
tlog.Warn.Printf("ino%d fh%d: doWrite: prealloc failed: %v", f.qIno.Ino, f.intFd(), err)
|
||||
@ -339,7 +348,7 @@ func (f *File) doWrite(data []byte, off int64) (uint32, syscall.Errno) {
|
||||
}
|
||||
}
|
||||
// Write
|
||||
_, err = f.fd.WriteAt(ciphertext, cOff)
|
||||
_, err = f.fd.WriteAt(ciphertext, int64(cOff))
|
||||
// Return memory to CReqPool
|
||||
f.rootNode.contentEnc.CReqPool.Put(ciphertext)
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user