Skip to content

Commit

Permalink
Fixed bug on read empty file.
Browse files Browse the repository at this point in the history
  • Loading branch information
miyabe committed Sep 29, 2022
1 parent 67a7bbe commit 9a55f62
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 53 deletions.
57 changes: 34 additions & 23 deletions EncFSy_lib/EncFSFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,48 +6,52 @@ using namespace std;
static AutoSeededX917RNG<CryptoPP::AES> random;

namespace EncFS {
bool EncFSFile::getFileIV(const LPCWSTR FileName, int64_t *fileIv, bool create) {
EncFSGetFileIVResult EncFSFile::getFileIV(const LPCWSTR FileName, int64_t *fileIv, bool create) {
if (this->fileIvAvailable) {
*fileIv = this->fileIv;
return true;
return EXISTS;
}
if (!encfs.isUniqueIV()) {
this->fileIv = *fileIv = 0L;
this->fileIvAvailable = true;
return true;
return EXISTS;
}
// Read file header.
LARGE_INTEGER distanceToMove;
distanceToMove.QuadPart = 0;
if (!SetFilePointerEx(this->handle, distanceToMove, NULL, FILE_BEGIN)) {
return false;
return READ_ERROR;
}
string fileHeader;
fileHeader.resize(EncFSVolume::HEADER_SIZE);
DWORD ReadLength;
if (!ReadFile(this->handle, &fileHeader[0], (DWORD)fileHeader.size(), (LPDWORD)&ReadLength, NULL)) {
return false;
return READ_ERROR;
}
if (ReadLength != fileHeader.size()) {
if (!create) {
return false;
if (ReadLength == 0) {
return EMPTY;
}
SetLastError(ERROR_READ_FAULT);
return READ_ERROR;
}
// Create file header.
fileHeader.resize(EncFSVolume::HEADER_SIZE);
random.GenerateBlock((byte*)&fileHeader[0], EncFSVolume::HEADER_SIZE);
if (!SetFilePointerEx(this->handle, distanceToMove, NULL, FILE_BEGIN)) {
return false;
return READ_ERROR;
}
DWORD writtenLen;
if (!WriteFile(this->handle, fileHeader.data(), (DWORD)fileHeader.size(), &writtenLen, NULL)) {
return false;
return READ_ERROR;
}
}

string cFileName = this->strConv.to_bytes(wstring(FileName));
this->fileIv = *fileIv = encfs.decodeFileIv(cFileName, fileHeader);
this->fileIvAvailable = true;
return true;
return EXISTS;
}

int32_t EncFSFile::read(const LPCWSTR FileName, char* buff, size_t off, DWORD len) {
Expand All @@ -59,9 +63,13 @@ namespace EncFS {

try {
int64_t fileIv;
if (!this->getFileIV(FileName, &fileIv, false)) {
EncFSGetFileIVResult ivResult = this->getFileIV(FileName, &fileIv, false);
if (ivResult == READ_ERROR) {
return -1;
}
if (ivResult == EMPTY) {
return 0;
}

//printf("read %d %d %d %d\n", fileIv, this->lastBlockNum, off, len);

Expand Down Expand Up @@ -109,7 +117,6 @@ namespace EncFS {
this->blockBuffer.resize(blocksLength);
if (!ReadFile(this->handle, &this->blockBuffer[0], (DWORD)blocksLength, &readLen, NULL)) {
return -1;

}

//printf("read2 %d %d %d %d %d\n", shift, blockNum, lastBlockNum, blocksLength, readLen);
Expand Down Expand Up @@ -147,7 +154,7 @@ namespace EncFS {
lock_guard<decltype(this->mutexLock)> lock(this->mutexLock);
try {
int64_t fileIv;
if (!this->getFileIV(FileName, &fileIv, true)) {
if (this->getFileIV(FileName, &fileIv, true) == READ_ERROR) {
SetLastError(ERROR_FILE_CORRUPT);
return -1;
}
Expand Down Expand Up @@ -263,16 +270,16 @@ namespace EncFS {

// Calculate position.
// File header and block header sizes are zero on reverse mode.
size_t blockSize = encfs.getBlockSize();
size_t shift = off % blockSize;
size_t blockNum = off / blockSize;
size_t lastBlockNum = (off + len - 1) / blockSize;
int32_t blockSize = encfs.getBlockSize();
int32_t shift = off % blockSize;
int64_t blockNum = off / blockSize;
int64_t lastBlockNum = (off + len - 1) / blockSize;

size_t blocksOffset = blockNum * blockSize;
size_t blocksLength = (lastBlockNum + 1) * blockSize - blocksOffset;
int64_t blocksOffset = blockNum * blockSize;
int64_t blocksLength = (lastBlockNum + 1) * blockSize - blocksOffset;

size_t i = 0;
size_t blockDataLen;
int32_t i = 0;
int32_t blockDataLen;

if (blockNum == this->lastBlockNum) {
// Copy from buffer.
Expand Down Expand Up @@ -304,7 +311,7 @@ namespace EncFS {
return i;
}

size_t bufferPos = 0;
int64_t bufferPos = 0;
for (; i < len; i += blockDataLen) {
blockDataLen = (len - i) > blockSize - shift ? blockSize - shift : (len - i);

Expand Down Expand Up @@ -377,7 +384,7 @@ namespace EncFS {
blockNum = fileSize / blockDataSize;
}
int64_t fileIv;
if (!this->getFileIV(FileName, &fileIv, true)) {
if (this->getFileIV(FileName, &fileIv, true) == READ_ERROR) {
return false;
}
if (shift != 0) {
Expand Down Expand Up @@ -458,9 +465,13 @@ namespace EncFS {
bool EncFSFile::changeFileIV(const LPCWSTR FileName, const LPCWSTR NewFileName) {
int64_t fileIv;
//printf("changeFileIV\n");
if (!this->getFileIV(FileName, &fileIv, false)) {
EncFSGetFileIVResult ivResult = this->getFileIV(FileName, &fileIv, false);
if (ivResult == EMPTY) {
return true;
}
if (ivResult == READ_ERROR) {
return false;
}
//printf("changeFileIV A %d\n", fileIv);
string cNewFileName = strConv.to_bytes(wstring(NewFileName));
string encodedFileHeader;
Expand Down
8 changes: 7 additions & 1 deletion EncFSy_lib/EncFSFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ extern EncFS::EncFSVolume encfs;

namespace EncFS
{
enum EncFSGetFileIVResult {
EXISTS,
READ_ERROR,
EMPTY
};

class EncFSFile {
private:
HANDLE handle;
Expand Down Expand Up @@ -56,7 +62,7 @@ namespace EncFS
bool changeFileIV(const LPCWSTR FileName, const LPCWSTR NewFileName);

private:
bool getFileIV(const LPCWSTR FileName, int64_t *fileIv, bool create);
EncFSGetFileIVResult getFileIV(const LPCWSTR FileName, int64_t *fileIv, bool create);
bool _setLength(const LPCWSTR FileName, const size_t fileSize, const size_t length);
};
}
16 changes: 8 additions & 8 deletions EncFSy_lib/EncFSVolume.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -515,28 +515,28 @@ R"(<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
this->codeFilePath(encodedFilePath, plainFilePath, false);
}

size_t EncFSVolume::toDecodedLength(const size_t encodedLength) {
size_t size = encodedLength;
size_t headerSize = this->getHeaderSize();
int64_t EncFSVolume::toDecodedLength(const int64_t encodedLength) {
int64_t size = encodedLength;
int64_t headerSize = this->getHeaderSize();
if (size < (this->uniqueIV ? HEADER_SIZE : 0) + headerSize) {
return 0;
}
if (this->uniqueIV) {
size -= HEADER_SIZE;
}
if (headerSize > 0) {
size_t numBlocks = ((size - 1) / this->blockSize) + 1;
int64_t numBlocks = ((size - 1) / this->blockSize) + 1;
size -= numBlocks * headerSize;
}
return size;
}

size_t EncFSVolume::toEncodedLength(const size_t decodedLength) {
size_t size = decodedLength;
int64_t EncFSVolume::toEncodedLength(const int64_t decodedLength) {
int64_t size = decodedLength;
if (size != 0) {
size_t headerSize = this->getHeaderSize();
int64_t headerSize = this->getHeaderSize();
if (headerSize > 0) {
size_t numBlocks = ((size - 1) / (this->blockSize - headerSize)) + 1;
int64_t numBlocks = ((size - 1) / (this->blockSize - headerSize)) + 1;
size += numBlocks * headerSize;
}
if (this->uniqueIV) {
Expand Down
26 changes: 13 additions & 13 deletions EncFSy_lib/EncFSVolume.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace EncFS
class EncFSVolume {
public:
/** Block header size **/
static const size_t HEADER_SIZE = 8;
static const int32_t HEADER_SIZE = 8;

/** NTFS alt data stream support. **/
bool altStream;
Expand All @@ -37,29 +37,29 @@ namespace EncFS
bool reverse;

/** Key size. 192 or 256B */
int keySize;
int32_t keySize;
/** Block size of data. Fixed to 1024. */
int blockSize;
int32_t blockSize;
/** Generated different IV for each files. */
bool uniqueIV;
/** Generate filename IV from parent file path. */
bool chainedNameIV;
/** Generate content IV from parent file path. */
bool externalIVChaining;
int blockMACBytes;
int blockMACRandBytes;
int32_t blockMACBytes;
int32_t blockMACRandBytes;
bool allowHoles;

int encodedKeySize;
int32_t encodedKeySize;
string encodedKeyData;

int saltLen;
int32_t saltLen;
string saltData;

/** Iteration count of key derivation function. */
int kdfIterations;
int32_t kdfIterations;
/** Expected time for execute key derivation function.@*/
int desiredKDFDuration;
int32_t desiredKDFDuration;

string volumeKey;
string volumeIv;
Expand Down Expand Up @@ -97,10 +97,10 @@ namespace EncFS

void save(string &xml);

inline size_t getHeaderSize() {
inline int32_t getHeaderSize() {
return this->blockMACRandBytes + this->blockMACBytes;
}
inline size_t getBlockSize() {
inline int32_t getBlockSize() {
return this->blockSize;
}
inline bool isChainedNameIV() {
Expand All @@ -125,8 +125,8 @@ namespace EncFS
void decodeFileName(const string &encodedFileName, const string &plainDirPath, string &plainFileName);
void encodeFilePath(const string &plainFilePath, string &encodedFilePath);
void decodeFilePath(const string &plainFilePath, string &encodedFilePath);
size_t toDecodedLength(const size_t encodedLength);
size_t toEncodedLength(const size_t decodedLength);
int64_t toDecodedLength(const int64_t encodedLength);
int64_t toEncodedLength(const int64_t decodedLength);

void encodeFileIv(const string &plainFilePath, const int64_t fileIv, string &encodedFileHeader);
int64_t decodeFileIv(const string &plainFilePath, const string &encodedFileHeader);
Expand Down
7 changes: 4 additions & 3 deletions EncFSy_lib/EncFSy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1370,7 +1370,7 @@ static NTSTATUS DOKAN_CALLBACK EncFSSetAllocationSize(
LARGE_INTEGER encodedFileSize;
if (GetFileSizeEx(encfsFile->getHandle(), &encodedFileSize)) {
size_t decodedFileSize = encfs.toDecodedLength(encodedFileSize.QuadPart);
if (decodedFileSize < AllocSize) {
if ((int64_t)decodedFileSize < AllocSize) {
if (!encfsFile->setLength(FileName, AllocSize)) {
DWORD error = GetLastError();
DbgPrint(L"\tSetFilePointer error: %d, offset = %I64d\n", error,
Expand Down Expand Up @@ -1771,8 +1771,9 @@ static NTSTATUS DOKAN_CALLBACK EncFSMounted(LPCWSTR MountPoint,

if (!g_efo.g_DebugMode) {
wchar_t buff[20];
swprintf(buff, sizeof(buff), L"%s:\\", MountPoint);
ShellExecute(NULL, NULL, buff, NULL, NULL, SW_SHOWNORMAL);
if (swprintf_s(buff, sizeof(buff), L"%s:\\", MountPoint) != -1) {
ShellExecute(NULL, NULL, buff, NULL, NULL, SW_SHOWNORMAL);
}
}

return STATUS_SUCCESS;
Expand Down
36 changes: 32 additions & 4 deletions EncFSy_test/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ int main()
{
DWORD dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
DWORD dwCreationDisposition = OPEN_ALWAYS;
DWORD dwCreationDisposition = CREATE_ALWAYS;
DWORD dwFlagsAndAttribute = FILE_ATTRIBUTE_NORMAL;
HANDLE h = CreateFileW(file, dwDesiredAccess, dwShareMode, NULL,
dwCreationDisposition, dwFlagsAndAttribute, NULL);
Expand Down Expand Up @@ -49,25 +49,53 @@ int main()
printf("CreateFileW ERROR: %d\n", lastError);
return -1;
}

LARGE_INTEGER distanceToMove;
const char* writeData = "ABCDEFG";
const DWORD size = sizeof(writeData);
char buff[size];
DWORD readLen;

distanceToMove.QuadPart = 0;
if (!SetFilePointerEx(h, distanceToMove, NULL, FILE_BEGIN)) {
DWORD lastError = GetLastError();
printf("SetFilePointerEx ERROR: %d\n", lastError);
return -1;
}

if (!ReadFile(h, buff, size, &readLen, NULL)) {
DWORD lastError = GetLastError();
printf("ReadFile ERROR: %d\n", lastError);
return -1;
}
printf("ReadLen: %d\n", readLen);

distanceToMove.QuadPart = 100;
if (!SetFilePointerEx(h, distanceToMove, NULL, FILE_BEGIN)) {
DWORD lastError = GetLastError();
printf("SetFilePointerEx ERROR: %d\n", lastError);
return -1;
}

if (!ReadFile(h, buff, size, &readLen, NULL)) {
DWORD lastError = GetLastError();
printf("ReadFile ERROR: %d\n", lastError);
return -1;
}
printf("ReadLen: %d\n", readLen);

if (!WriteFile(h, writeData, size, &readLen, NULL)) {
DWORD lastError = GetLastError();
printf("WriteFile ERROR: %d\n", lastError);
return -1;
}

LARGE_INTEGER distanceToMove;
distanceToMove.QuadPart = 0;
if (!SetFilePointerEx(h, distanceToMove, NULL, FILE_BEGIN)) {
DWORD lastError = GetLastError();
printf("SetFilePointerEx ERROR: %d\n", lastError);
return -1;
}

char buff[size];
if (!ReadFile(h, buff, size, &readLen, NULL)) {
DWORD lastError = GetLastError();
printf("ReadFile ERROR: %d\n", lastError);
Expand Down
2 changes: 1 addition & 1 deletion installer/installer.nsi
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
!define VERSION "0.17"
!define VERSION "0.18"

!include LogicLib.nsh
!include x64.nsh
Expand Down

0 comments on commit 9a55f62

Please sign in to comment.