From 78edb14d76c2721e3c62f00fb7964a40a22ff8d3 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Tue, 11 Apr 2017 19:55:17 -0500 Subject: [PATCH] Fix some issues in in FileStore::alloc that caused buffer overflows --- src/ox/fs/filestore.hpp | 46 +++++++++++++++-------------------------- src/ox/fs/oxfstool.cpp | 21 +++++++++++-------- 2 files changed, 29 insertions(+), 38 deletions(-) diff --git a/src/ox/fs/filestore.hpp b/src/ox/fs/filestore.hpp index 928e8b0a5..68bb747f4 100644 --- a/src/ox/fs/filestore.hpp +++ b/src/ox/fs/filestore.hpp @@ -276,15 +276,9 @@ class FileStore { */ bool insert(Inode *root, Inode *insertValue); - /** - * Gets the FsSize_t associated with the next Inode to be allocated. - * @retrun the FsSize_t associated with the next Inode to be allocated - */ - typename Header::FsSize_t iterator(); - typename Header::FsSize_t firstInode(); - Inode *lastInode(); + typename Header::FsSize_t lastInode(); /** * Updates the address of the inode in the tree. @@ -326,7 +320,7 @@ void FileStore
::Inode::setDataLen(typename Header::FsSize_t dataLen) { template typename Header::FsSize_t FileStore
::Inode::getDataLen() { - return std::bigEndianAdapt(this->m_dataLen); + return std::bigEndianAdapt(m_dataLen); } template @@ -336,7 +330,7 @@ void FileStore
::Inode::setPrev(typename Header::FsSize_t prev) { template typename Header::FsSize_t FileStore
::Inode::getPrev() { - return std::bigEndianAdapt(this->m_prev); + return std::bigEndianAdapt(m_prev); } template @@ -346,7 +340,7 @@ void FileStore
::Inode::setNext(typename Header::FsSize_t next) { template typename Header::FsSize_t FileStore
::Inode::getNext() { - return std::bigEndianAdapt(this->m_next); + return std::bigEndianAdapt(m_next); } template @@ -356,7 +350,7 @@ void FileStore
::Inode::setId(InodeId_t id) { template typename Header::InodeId_t FileStore
::Inode::getId() { - return std::bigEndianAdapt(this->m_id); + return std::bigEndianAdapt(m_id); } template @@ -366,7 +360,7 @@ void FileStore
::Inode::setFileType(uint8_t fileType) { template uint8_t FileStore
::Inode::getFileType() { - return std::bigEndianAdapt(this->m_fileType); + return std::bigEndianAdapt(m_fileType); } template @@ -376,7 +370,7 @@ void FileStore
::Inode::setLeft(typename Header::FsSize_t left) { template typename Header::FsSize_t FileStore
::Inode::getLeft() { - return std::bigEndianAdapt(this->m_left); + return std::bigEndianAdapt(m_left); } template @@ -386,12 +380,12 @@ void FileStore
::Inode::setRight(typename Header::FsSize_t right) { template typename Header::FsSize_t FileStore
::Inode::getRight() { - return std::bigEndianAdapt(this->m_right); + return std::bigEndianAdapt(m_right); } template void FileStore
::Inode::setData(void *data, typename Header::FsSize_t size) { - ox_memcpy(this->getData(), data, size); + ox_memcpy(getData(), data, size); setDataLen(size); } @@ -630,17 +624,16 @@ typename FileStore
::Inode *FileStore
::getInodeParent(Inode *root template typename Header::FsSize_t FileStore
::nextInodeAddr() { - typename Header::FsSize_t next = ptr(lastInode()) + lastInode()->size(); - return next; + return lastInode() + ptr(lastInode())->size(); } template void *FileStore
::alloc(typename Header::FsSize_t size) { - typename Header::FsSize_t next = nextInodeAddr(); - if ((next + size) > (uint64_t) end()) { + auto next = nextInodeAddr(); + if ((next + size) > ptr(end())) { compact(); next = nextInodeAddr(); - if ((next + size) > (uint64_t) end()) { + if ((next + size) > ptr(end())) { return nullptr; } } @@ -649,7 +642,7 @@ void *FileStore
::alloc(typename Header::FsSize_t size) { const auto inode = ptr(retval); ox_memset(inode, 0, size); inode->setPrev(ptr(firstInode())->getPrev()); - inode->setNext(retval + size); + inode->setNext(firstInode()); m_header.setMemUsed(m_header.getMemUsed() + size); ptr(firstInode())->setPrev(retval); return inode; @@ -697,11 +690,6 @@ bool FileStore
::insert(Inode *root, Inode *insertValue) { return retval; } -template -typename Header::FsSize_t FileStore
::iterator() { - return ptr(lastInode()) + lastInode()->size(); -} - template typename Header::FsSize_t FileStore
::ptr(void *ptr) { #ifdef _MSC_VER @@ -719,8 +707,8 @@ typename Header::FsSize_t FileStore
::firstInode() { } template -typename FileStore
::Inode *FileStore
::lastInode() { - return ptr(ptr(firstInode())->getPrev()); +typename Header::FsSize_t FileStore
::lastInode() { + return ptr(firstInode())->getPrev(); } template @@ -744,7 +732,7 @@ uint8_t *FileStore
::format(uint8_t *buffer, typename Header::FsSize_t si fs->m_header.setMemUsed(sizeof(FileStore
) + sizeof(Inode)); fs->m_header.setRootInode(sizeof(FileStore
)); ((Inode*) (fs + 1))->setPrev(sizeof(FileStore
)); - fs->lastInode()->setNext(sizeof(FileStore
)); + ((Inode*) (fs + 1))->setNext(sizeof(FileStore
)); return (uint8_t*) buffer; } diff --git a/src/ox/fs/oxfstool.cpp b/src/ox/fs/oxfstool.cpp index d49af7a07..273958e17 100644 --- a/src/ox/fs/oxfstool.cpp +++ b/src/ox/fs/oxfstool.cpp @@ -55,8 +55,9 @@ size_t bytes(const char *str) { auto size = ::ox_strlen(str); const auto lastChar = str[size-1]; auto multiplier = 1; - auto copy = new char[size]; - ox_memcpy(copy, str, size); + char copy[size + 1]; + ox_memcpy(copy, str, size + 1); + // parse size unit if (lastChar < '0' || lastChar > '9') { copy[size-1] = 0; switch (lastChar) { @@ -76,9 +77,7 @@ size_t bytes(const char *str) { multiplier = -1; } } - const auto retval = ((size_t) ox_atoi(copy)) * multiplier; - delete []copy; - return retval; + return ox_atoi(copy) * multiplier; } int format(int argc, char **args) { @@ -86,13 +85,10 @@ int format(int argc, char **args) { auto err = 0; if (argc >= 5) { auto type = ox_atoi(args[2]); - cout << args[3] << endl; auto size = bytes(args[3]); auto path = args[4]; auto buff = (uint8_t*) malloc(size); - cout << "Size: " << size << " bytes\n"; - cout << "Type: " << type << endl; if (size < sizeof(FileStore64)) { err = 1; @@ -198,10 +194,11 @@ int write(int argc, char **args, bool expand) { if (itemsRead) { auto srcBuff = loadFileBuff(srcPath, &srcSize); if (srcBuff) { + auto expanded = false; auto fs = createFileSystem(fsBuff); if (fs) { if (expand && fs->available() <= srcSize) { - auto needed = fs->spaceNeeded(inode, srcSize); + auto needed = fs->size() + fs->spaceNeeded(inode, srcSize); auto cloneBuff = new uint8_t[needed]; ox_memcpy(cloneBuff, fsBuff, fsSize); @@ -214,6 +211,12 @@ int write(int argc, char **args, bool expand) { fs->resize(fsSize); } err |= fs->write(inode, srcBuff, srcSize); + + // compact the file system if it was expanded + if (expanded) { + fs->resize(); + } + if (err) { fprintf(stderr, "Could not write to file system.\n"); }