mirror of
https://github.com/vgough/encfs.git
synced 2025-06-26 15:01:57 +02:00
Verify open/read/write/truncate returned values
This commit is contained in:
parent
b88da06a08
commit
13ae4de830
@ -195,7 +195,9 @@ int BlockFileIO::write(const IORequest &req) {
|
|||||||
if (req.offset > fileSize) {
|
if (req.offset > fileSize) {
|
||||||
// extend file first to fill hole with 0's..
|
// extend file first to fill hole with 0's..
|
||||||
const bool forceWrite = false;
|
const bool forceWrite = false;
|
||||||
padFile(fileSize, req.offset, forceWrite);
|
int res = padFile(fileSize, req.offset, forceWrite);
|
||||||
|
if (res)
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check against edge cases where we can just let the base class handle the
|
// check against edge cases where we can just let the base class handle the
|
||||||
@ -244,7 +246,10 @@ int BlockFileIO::write(const IORequest &req) {
|
|||||||
} else {
|
} else {
|
||||||
// have to merge with existing block data..
|
// have to merge with existing block data..
|
||||||
blockReq.dataLen = _blockSize;
|
blockReq.dataLen = _blockSize;
|
||||||
blockReq.dataLen = cacheReadOneBlock(blockReq);
|
if ((blockReq.dataLen = cacheReadOneBlock(blockReq)) < 0) {
|
||||||
|
res = blockReq.dataLen;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// extend data if necessary..
|
// extend data if necessary..
|
||||||
if (partialOffset + toCopy > blockReq.dataLen)
|
if (partialOffset + toCopy > blockReq.dataLen)
|
||||||
@ -274,10 +279,11 @@ int BlockFileIO::write(const IORequest &req) {
|
|||||||
|
|
||||||
int BlockFileIO::blockSize() const { return _blockSize; }
|
int BlockFileIO::blockSize() const { return _blockSize; }
|
||||||
|
|
||||||
void BlockFileIO::padFile(off_t oldSize, off_t newSize, bool forceWrite) {
|
int BlockFileIO::padFile(off_t oldSize, off_t newSize, bool forceWrite) {
|
||||||
off_t oldLastBlock = oldSize / _blockSize;
|
off_t oldLastBlock = oldSize / _blockSize;
|
||||||
off_t newLastBlock = newSize / _blockSize;
|
off_t newLastBlock = newSize / _blockSize;
|
||||||
int newBlockSize = newSize % _blockSize;
|
int newBlockSize = newSize % _blockSize;
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
IORequest req;
|
IORequest req;
|
||||||
MemBlock mb;
|
MemBlock mb;
|
||||||
@ -296,9 +302,10 @@ void BlockFileIO::padFile(off_t oldSize, off_t newSize, bool forceWrite) {
|
|||||||
|
|
||||||
if (outSize) {
|
if (outSize) {
|
||||||
memset(mb.data, 0, outSize);
|
memset(mb.data, 0, outSize);
|
||||||
cacheReadOneBlock(req);
|
if ((res = cacheReadOneBlock(req)) >= 0) {
|
||||||
req.dataLen = outSize;
|
req.dataLen = outSize;
|
||||||
cacheWriteOneBlock(req);
|
res = cacheWriteOneBlock(req);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
VLOG(1) << "optimization: not padding last block";
|
VLOG(1) << "optimization: not padding last block";
|
||||||
@ -317,33 +324,36 @@ void BlockFileIO::padFile(off_t oldSize, off_t newSize, bool forceWrite) {
|
|||||||
if (req.dataLen != 0) {
|
if (req.dataLen != 0) {
|
||||||
VLOG(1) << "padding block " << oldLastBlock;
|
VLOG(1) << "padding block " << oldLastBlock;
|
||||||
memset(mb.data, 0, _blockSize);
|
memset(mb.data, 0, _blockSize);
|
||||||
cacheReadOneBlock(req);
|
if ((res = cacheReadOneBlock(req)) >= 0) {
|
||||||
req.dataLen = _blockSize; // expand to full block size
|
req.dataLen = _blockSize; // expand to full block size
|
||||||
cacheWriteOneBlock(req);
|
res = cacheWriteOneBlock(req);
|
||||||
|
}
|
||||||
++oldLastBlock;
|
++oldLastBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2, pad zero blocks unless holes are allowed
|
// 2, pad zero blocks unless holes are allowed
|
||||||
if (!_allowHoles) {
|
if (!_allowHoles) {
|
||||||
for (; oldLastBlock != newLastBlock; ++oldLastBlock) {
|
for (; !res && (oldLastBlock != newLastBlock); ++oldLastBlock) {
|
||||||
VLOG(1) << "padding block " << oldLastBlock;
|
VLOG(1) << "padding block " << oldLastBlock;
|
||||||
req.offset = oldLastBlock * _blockSize;
|
req.offset = oldLastBlock * _blockSize;
|
||||||
req.dataLen = _blockSize;
|
req.dataLen = _blockSize;
|
||||||
memset(mb.data, 0, req.dataLen);
|
memset(mb.data, 0, req.dataLen);
|
||||||
cacheWriteOneBlock(req);
|
res = cacheWriteOneBlock(req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. only necessary if write is forced and block is non 0 length
|
// 3. only necessary if write is forced and block is non 0 length
|
||||||
if (forceWrite && newBlockSize) {
|
if (!res && forceWrite && newBlockSize) {
|
||||||
req.offset = newLastBlock * _blockSize;
|
req.offset = newLastBlock * _blockSize;
|
||||||
req.dataLen = newBlockSize;
|
req.dataLen = newBlockSize;
|
||||||
memset(mb.data, 0, req.dataLen);
|
memset(mb.data, 0, req.dataLen);
|
||||||
cacheWriteOneBlock(req);
|
res = cacheWriteOneBlock(req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mb.data) MemoryPool::release(mb);
|
if (mb.data) MemoryPool::release(mb);
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BlockFileIO::truncateBase(off_t size, FileIO *base) {
|
int BlockFileIO::truncateBase(off_t size, FileIO *base) {
|
||||||
@ -357,10 +367,11 @@ int BlockFileIO::truncateBase(off_t size, FileIO *base) {
|
|||||||
// states that it will pad with 0's.
|
// states that it will pad with 0's.
|
||||||
// do the truncate so that the underlying filesystem can allocate
|
// do the truncate so that the underlying filesystem can allocate
|
||||||
// the space, and then we'll fill it in padFile..
|
// the space, and then we'll fill it in padFile..
|
||||||
if (base) base->truncate(size);
|
if (base) res = base->truncate(size);
|
||||||
|
|
||||||
const bool forceWrite = true;
|
const bool forceWrite = true;
|
||||||
padFile(oldSize, size, forceWrite);
|
if (!res)
|
||||||
|
res = padFile(oldSize, size, forceWrite);
|
||||||
} else if (size == oldSize) {
|
} else if (size == oldSize) {
|
||||||
// the easiest case, but least likely....
|
// the easiest case, but least likely....
|
||||||
} else if (partialBlock) {
|
} else if (partialBlock) {
|
||||||
@ -376,19 +387,17 @@ int BlockFileIO::truncateBase(off_t size, FileIO *base) {
|
|||||||
req.data = mb.data;
|
req.data = mb.data;
|
||||||
|
|
||||||
ssize_t rdSz = cacheReadOneBlock(req);
|
ssize_t rdSz = cacheReadOneBlock(req);
|
||||||
|
if (rdSz < 0)
|
||||||
|
res = rdSz;
|
||||||
|
|
||||||
// do the truncate
|
// do the truncate
|
||||||
if (base) res = base->truncate(size);
|
else if (base)
|
||||||
|
res = base->truncate(size);
|
||||||
|
|
||||||
// write back out partial block
|
// write back out partial block
|
||||||
req.dataLen = partialBlock;
|
req.dataLen = partialBlock;
|
||||||
int wrRes = cacheWriteOneBlock(req);
|
if (!res)
|
||||||
|
res = cacheWriteOneBlock(req);
|
||||||
if ((rdSz < 0) || (wrRes)) {
|
|
||||||
// rwarning - unlikely to ever occur..
|
|
||||||
RLOG(WARNING) << "truncate failure: read " << rdSz
|
|
||||||
<< " bytes, partial block of " << partialBlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
MemoryPool::release(mb);
|
MemoryPool::release(mb);
|
||||||
} else {
|
} else {
|
||||||
|
@ -49,7 +49,7 @@ class BlockFileIO : public FileIO {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
int truncateBase(off_t size, FileIO *base);
|
int truncateBase(off_t size, FileIO *base);
|
||||||
void padFile(off_t oldSize, off_t newSize, bool forceWrite);
|
int padFile(off_t oldSize, off_t newSize, bool forceWrite);
|
||||||
|
|
||||||
// same as read(), except that the request.offset field is guarenteed to be
|
// same as read(), except that the request.offset field is guarenteed to be
|
||||||
// block aligned, and the request size will not be larger then 1 block.
|
// block aligned, and the request size will not be larger then 1 block.
|
||||||
|
@ -95,20 +95,20 @@ bool CipherFileIO::setIV(uint64_t iv) {
|
|||||||
} else if (haveHeader) {
|
} else if (haveHeader) {
|
||||||
// we have an old IV, and now a new IV, so we need to update the fileIV
|
// we have an old IV, and now a new IV, so we need to update the fileIV
|
||||||
// on disk.
|
// on disk.
|
||||||
if (fileIV == 0) {
|
// ensure the file is open for read/write..
|
||||||
// ensure the file is open for read/write..
|
int newFlags = lastFlags | O_RDWR;
|
||||||
int newFlags = lastFlags | O_RDWR;
|
int res = base->open(newFlags);
|
||||||
int res = base->open(newFlags);
|
if (res < 0) {
|
||||||
if (res < 0) {
|
if (res == -EISDIR) {
|
||||||
if (res == -EISDIR) {
|
// duh -- there are no file headers for directories!
|
||||||
// duh -- there are no file headers for directories!
|
externalIV = iv;
|
||||||
externalIV = iv;
|
return base->setIV(iv);
|
||||||
return base->setIV(iv);
|
} else {
|
||||||
} else {
|
VLOG(1) << "setIV failed to re-open for write";
|
||||||
VLOG(1) << "writeHeader failed to re-open for write";
|
return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (fileIV == 0) {
|
||||||
if (initHeader() < 0)
|
if (initHeader() < 0)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -184,7 +184,9 @@ int CipherFileIO::initHeader() {
|
|||||||
req.offset = 0;
|
req.offset = 0;
|
||||||
req.data = buf;
|
req.data = buf;
|
||||||
req.dataLen = 8;
|
req.dataLen = 8;
|
||||||
base->read(req);
|
ssize_t readSize = base->read(req);
|
||||||
|
if(readSize < 0)
|
||||||
|
return readSize;
|
||||||
|
|
||||||
if(!cipher->streamDecode(buf, sizeof(buf), externalIV, key))
|
if(!cipher->streamDecode(buf, sizeof(buf), externalIV, key))
|
||||||
return -EBADMSG;
|
return -EBADMSG;
|
||||||
@ -219,7 +221,9 @@ int CipherFileIO::initHeader() {
|
|||||||
req.data = buf;
|
req.data = buf;
|
||||||
req.dataLen = 8;
|
req.dataLen = 8;
|
||||||
|
|
||||||
base->write(req);
|
int res = base->write(req);
|
||||||
|
if (res)
|
||||||
|
return res;
|
||||||
} else {
|
} else {
|
||||||
VLOG(1) << "base not writable, IV not written..";
|
VLOG(1) << "base not writable, IV not written..";
|
||||||
}
|
}
|
||||||
@ -229,15 +233,6 @@ int CipherFileIO::initHeader() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool CipherFileIO::writeHeader() {
|
bool CipherFileIO::writeHeader() {
|
||||||
if (!base->isWritable()) {
|
|
||||||
// open for write..
|
|
||||||
int newFlags = lastFlags | O_RDWR;
|
|
||||||
if (base->open(newFlags) < 0) {
|
|
||||||
VLOG(1) << "writeHeader failed to re-open for write";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fileIV == 0) {
|
if (fileIV == 0) {
|
||||||
RLOG(ERROR) << "Internal error: fileIV == 0 in writeHeader!!!";
|
RLOG(ERROR) << "Internal error: fileIV == 0 in writeHeader!!!";
|
||||||
}
|
}
|
||||||
@ -257,7 +252,8 @@ bool CipherFileIO::writeHeader() {
|
|||||||
req.data = buf;
|
req.data = buf;
|
||||||
req.dataLen = 8;
|
req.dataLen = 8;
|
||||||
|
|
||||||
base->write(req);
|
if (base->write(req))
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -351,7 +347,7 @@ ssize_t CipherFileIO::readOneBlock(const IORequest &req) const {
|
|||||||
<< readSize;
|
<< readSize;
|
||||||
readSize = -EBADMSG;
|
readSize = -EBADMSG;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (readSize == 0) {
|
||||||
VLOG(1) << "readSize zero for offset " << req.offset;
|
VLOG(1) << "readSize zero for offset " << req.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,8 +446,11 @@ int CipherFileIO::truncate(off_t size) {
|
|||||||
if (!base->isWritable()) {
|
if (!base->isWritable()) {
|
||||||
// open for write..
|
// open for write..
|
||||||
int newFlags = lastFlags | O_RDWR;
|
int newFlags = lastFlags | O_RDWR;
|
||||||
if (base->open(newFlags) < 0)
|
int res = base->open(newFlags);
|
||||||
VLOG(1) << "writeHeader failed to re-open for write";
|
if (res < 0) {
|
||||||
|
VLOG(1) << "truncate failed to re-open for write";
|
||||||
|
return res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
int res = initHeader();
|
int res = initHeader();
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
@ -462,7 +461,7 @@ int CipherFileIO::truncate(off_t size) {
|
|||||||
// the wrong size..
|
// the wrong size..
|
||||||
res = BlockFileIO::truncateBase(size, 0);
|
res = BlockFileIO::truncateBase(size, 0);
|
||||||
|
|
||||||
if (res == 0) base->truncate(size + HEADER_SIZE);
|
if (res == 0) res = base->truncate(size + HEADER_SIZE);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -253,7 +253,7 @@ int MACFileIO::truncate(off_t size) {
|
|||||||
|
|
||||||
int res = BlockFileIO::truncateBase(size, 0);
|
int res = BlockFileIO::truncateBase(size, 0);
|
||||||
|
|
||||||
if (res == 0) base->truncate(locWithHeader(size, bs, headerSize));
|
if (res == 0) res = base->truncate(locWithHeader(size, bs, headerSize));
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user