From 81e05de4391c11fad7faf9bc164f92e128a49d25 Mon Sep 17 00:00:00 2001 From: Daniel Brahneborg Date: Thu, 28 Mar 2002 09:47:25 +0000 Subject: Some buffer overrun checks. Removed the --force flag. --- lib/siscomponentrecord.cpp | 3 +++ lib/siscomponentrecord.h | 5 +++++ lib/sisfile.cpp | 6 +++++- lib/sisfilerecord.cpp | 22 +++++++++++++++----- lib/sisfilerecord.h | 15 +++++++++++--- lib/sistypes.h | 1 + sisinstall/sisinstaller.cpp | 49 +++++++++++++++++++++++++++------------------ sisinstall/sisinstaller.h | 13 ------------ sisinstall/sismain.cpp | 9 +-------- 9 files changed, 73 insertions(+), 50 deletions(-) diff --git a/lib/siscomponentrecord.cpp b/lib/siscomponentrecord.cpp index 83781d1..3507bce 100644 --- a/lib/siscomponentrecord.cpp +++ b/lib/siscomponentrecord.cpp @@ -29,6 +29,8 @@ SISComponentNameRecord::~SISComponentNameRecord() { + for (int i = 0; i < m_nameCount; ++i) + delete[] m_names[i]; delete[] m_names; } @@ -62,6 +64,7 @@ SISComponentNameRecord::fillFrom(uint8_t* buf, int base, off_t len, // Then read ptrs. // m_names = new uint8_t*[n]; + m_nameCount = n; for (int i = 0; i < n; ++i) { m_namePtrs[i] = read32(p + size); diff --git a/lib/siscomponentrecord.h b/lib/siscomponentrecord.h index 5fbf945..f2bc734 100644 --- a/lib/siscomponentrecord.h +++ b/lib/siscomponentrecord.h @@ -70,6 +70,11 @@ private: */ uint8_t** m_names; + /** + * The number of names, so we know how much to delete. + */ + int m_nameCount; + }; #endif diff --git a/lib/sisfile.cpp b/lib/sisfile.cpp index 62a2ce1..df60695 100644 --- a/lib/sisfile.cpp +++ b/lib/sisfile.cpp @@ -110,6 +110,7 @@ SISFile::fillFrom(uint8_t* buf, off_t len) n = m_header.m_nfiles; m_fileRecords = new SISFileRecord[n]; ix = m_header.m_filesPtr; + SisRC myrc = SIS_OK; for (int i = 0; i < n; ++i) { if (ix >= len) @@ -118,7 +119,10 @@ SISFile::fillFrom(uint8_t* buf, off_t len) if (rc != SIS_OK) { printf(_("Problem reading file record %d, rc = %d.\n"), i, rc); - return rc; + if (rc == SIS_TRUNCATEDDATA) + myrc = rc; + else + return rc; } } diff --git a/lib/sisfilerecord.cpp b/lib/sisfilerecord.cpp index 95e75ed..a483b80 100644 --- a/lib/sisfilerecord.cpp +++ b/lib/sisfilerecord.cpp @@ -32,7 +32,9 @@ SISFileRecord::fillFrom(uint8_t* buf, int* base, off_t len, SISFile* sisFile) if (*base + 28 + 4 * 2 > len) return SIS_TRUNCATED; + SisRC rc = SIS_OK; m_buf = buf; + m_len = len; uint8_t* p = buf + *base; int size = 0; m_flags = read32(p); @@ -89,16 +91,16 @@ SISFileRecord::fillFrom(uint8_t* buf, int* base, off_t len, SISFile* sisFile) for (int i = 0; i < n; ++i) { m_fileLengths[i] = read32(p + size); - if (m_fileLengths[i] > len) - return SIS_TRUNCATED; +// if (m_fileLengths[i] > len) +// rc = SIS_TRUNCATEDDATA; size += 4; } for (int i = 0; i < n; ++i) { m_filePtrs[i] = read32(p + size); int fileLen = m_fileLengths[i]; - if (m_filePtrs[i] + fileLen > len) - return SIS_TRUNCATED; +// if (m_filePtrs[i] + fileLen > len) +// rc = SIS_TRUNCATEDDATA; size += 4; if (logLevel >= 2) printf(_("File %d (for %s) is %d bytes long (at %d)\n"), @@ -122,7 +124,17 @@ SISFileRecord::fillFrom(uint8_t* buf, int* base, off_t len, SISFile* sisFile) printf(_("Unknown file flags %d\n"), m_flags); } *base += size; - return SIS_OK; + return rc; +} + +uint8_t* +SISFileRecord::getFilePtr(int fileNo) +{ + if (fileNo < 0) + return 0; + if (m_filePtrs[fileNo] >= m_len) + return 0; + return &m_buf[m_filePtrs[fileNo]]; } void diff --git a/lib/sisfilerecord.h b/lib/sisfilerecord.h index d0ccced..96a5f2a 100644 --- a/lib/sisfilerecord.h +++ b/lib/sisfilerecord.h @@ -50,9 +50,15 @@ public: uint8_t* getDestPtr() { - return &m_buf[m_destPtr]; + return m_destPtr < m_len ? &m_buf[m_destPtr] : 0; } + /** + * Return a pointer to the file data for the file for the specified + * language. + */ + uint8_t* getFilePtr(int fileNo); + void setMainDrive(char drive); /** @@ -90,18 +96,21 @@ public: uint32_t m_sourceLength; uint32_t m_sourcePtr; uint32_t m_destLength; - uint32_t m_destPtr; uint32_t* m_fileLengths; - uint32_t* m_filePtrs; private: + uint32_t m_destPtr; + uint32_t* m_filePtrs; + /** * The buffer we belong to. * Used for updating the destination file name. */ uint8_t* m_buf; + int m_len; + }; #endif diff --git a/lib/sistypes.h b/lib/sistypes.h index a5d008f..131c4dc 100644 --- a/lib/sistypes.h +++ b/lib/sistypes.h @@ -31,6 +31,7 @@ enum SisRC { SIS_OK = 0, SIS_TRUNCATED, + SIS_TRUNCATEDDATA, SIS_CORRUPTED, SIS_FAILED, SIS_ABORTED, diff --git a/sisinstall/sisinstaller.cpp b/sisinstall/sisinstaller.cpp index 334d340..9639213 100644 --- a/sisinstall/sisinstaller.cpp +++ b/sisinstall/sisinstaller.cpp @@ -18,8 +18,11 @@ checkAbortHash(void *, u_int32_t) { if (continueRunning) { - printf("#"); - fflush(stdout); + if (logLevel >= 1) + { + printf("#"); + fflush(stdout); + } } return continueRunning; } @@ -75,7 +78,10 @@ SISInstaller::createDirs(char* filename) void SISInstaller::copyFile(SISFileRecord* fileRecord) { - if (m_buf[fileRecord->m_destPtr] == '!') + uint8_t* destptr = fileRecord->getDestPtr(); + if (destptr == 0) + return; + if (destptr[0] == '!') { if (m_drive == 0) selectDrive(); @@ -83,7 +89,7 @@ SISInstaller::copyFile(SISFileRecord* fileRecord) } int len = fileRecord->m_destLength; char dest[256]; - memcpy(dest, m_buf + fileRecord->m_destPtr, len); + memcpy(dest, destptr, len); dest[len] = 0; if (dest[0] == '!') { @@ -91,12 +97,11 @@ SISInstaller::copyFile(SISFileRecord* fileRecord) fileRecord->setMainDrive(m_drive); if (logLevel >= 2) printf("Setting drive at index %d to %c\n", - fileRecord->m_destPtr, m_drive); -// m_buf[fileRecord->m_destPtr] = m_drive; + destptr, m_drive); } printf("Copying %d bytes to %s\n", fileRecord->m_fileLengths[m_fileNo], dest); - copyBuf(m_buf + fileRecord->m_filePtrs[m_fileNo], + copyBuf(fileRecord->getFilePtr(m_fileNo), fileRecord->m_fileLengths[m_fileNo], dest); } @@ -122,13 +127,15 @@ SISInstaller::copyBuf(const uint8_t* buf, int len, char* name) res = m_psion->copyToPsion(srcName, name, NULL, checkAbortHash); if (res == rfsv::E_PSI_GEN_NONE) { - printf(" -> Success.\n"); + if (logLevel >= 1) + printf(" -> Success.\n"); } else { printf(" -> Fail: %s\n", (const char*)res); } unlink(srcName); + //sleep(10); } int @@ -143,7 +150,7 @@ SISInstaller::installFile(SISFileRecord* fileRecord) case 1: printf("Info:\n%.*s\n", fileRecord->m_fileLengths[m_fileNo], - m_buf + fileRecord->m_filePtrs[m_fileNo]); + fileRecord->getFilePtr(m_fileNo)); switch (fileRecord->m_fileDetails) { case 0: @@ -176,11 +183,10 @@ SISInstaller::installFile(SISFileRecord* fileRecord) if (logLevel >= 1) printf("Recursive sis file...\n"); SISFile sisFile; - int fileptr = fileRecord->m_filePtrs[m_fileNo]; - uint8_t* buf2 = m_buf + fileptr; + uint8_t* buf2 = fileRecord->getFilePtr(m_fileNo); off_t len = fileRecord->m_fileLengths[m_fileNo]; - if (m_lastSisFile < fileptr + len) - m_lastSisFile = fileptr + len; +// if (m_lastSisFile < fileptr + len) +// m_lastSisFile = fileptr + len; SisRC rc = sisFile.fillFrom(buf2, len); if (rc != SIS_OK) { @@ -203,13 +209,13 @@ SISInstaller::installFile(SISFileRecord* fileRecord) } case 3: printf("Run %.*s during installation/remove\n", - fileRecord->m_destLength, m_buf + fileRecord->m_destPtr); + fileRecord->m_destLength, fileRecord->getDestPtr()); break; case 4: if (logLevel >= 2) printf("Running the app will create %.*s\n", fileRecord->m_destLength, - m_buf + fileRecord->m_destPtr); + fileRecord->getDestPtr()); break; } return FILE_OK; @@ -232,7 +238,8 @@ SISInstaller::loadInstalled() while (!files.empty()) { PlpDirent file = files[0]; - printf("Loading sis file `%s'\n", file.getName()); + if (logLevel >= 1) + printf("Loading sis file `%s'\n", file.getName()); char sisname[256]; sprintf(sisname, "%s%s", SYSTEMINSTALL, file.getName()); loadPsionSis(sisname); @@ -289,6 +296,7 @@ SISInstaller::loadPsionSis(const char* name) } close(fd); unlink(srcName); + //sleep(10); } void @@ -370,7 +378,8 @@ SISInstaller::run(SISFile* file, uint8_t* buf, off_t len, SISFile* parent) // Check previous version. // - printf( + if (logLevel >= 1) + printf( "Checking if this app (uid %08x) exists with a version less than %d.%d.\n", m_file->m_header.m_uid1, m_file->m_header.m_major, @@ -439,9 +448,9 @@ SISInstaller::run(SISFile* file, uint8_t* buf, off_t len, SISFile* parent) fileRecord->m_filePtrs[m_fileNo], fileRecord->m_fileLengths[m_fileNo]); #endif - if ((firstFile == -1) || - (firstFile >= fileRecord->m_filePtrs[m_fileNo])) - firstFile = fileRecord->m_filePtrs[m_fileNo]; + int fileIx = fileRecord->getFilePtr(m_fileNo) - m_buf; + if ((firstFile == -1) || (firstFile >= fileIx)) + firstFile = fileIx; // We can only do this if we search all files... // fileRecord->m_filePtrs[m_fileNo] + fileRecord->m_fileLengths[m_fileNo] diff --git a/sisinstall/sisinstaller.h b/sisinstall/sisinstaller.h index bb50c6e..28e110f 100644 --- a/sisinstall/sisinstaller.h +++ b/sisinstall/sisinstaller.h @@ -31,15 +31,6 @@ public: */ void selectDrive(); - /** - * Set forced mode, which means that it ignores any earlier versions - * of the same application. - */ - void setForced(bool f) - { - m_forced = f; - } - /** * Set the base pointer to the list of already installed * applications, so we don't have to scan it for every sis @@ -71,10 +62,6 @@ private: int m_lastSisFile; - bool m_forced; - - bool m_ownBuffer; - bool m_ownInstalled; enum { diff --git a/sisinstall/sismain.cpp b/sisinstall/sismain.cpp index 21d6f55..6fbe7f8 100644 --- a/sisinstall/sismain.cpp +++ b/sisinstall/sismain.cpp @@ -27,7 +27,6 @@ static struct option opts[] = { { "version", no_argument, 0, 'V' }, { "loglevel", required_argument, 0, 'l' }, { "dry-run", no_argument, 0, 'n' }, - { "force", no_argument, 0, 'f' }, { NULL, 0, 0, 0 }, }; @@ -42,7 +41,6 @@ void printHelp() " -V, --version Print version and exit.\n" " -l, --loglevel=LEVEL Set the log level, by default 0.\n" " -n, --dry-run Just parse file file.\n" - " -f, --force Ignore any earlier installations.\n" )); } @@ -51,7 +49,6 @@ void main(int argc, char* argv[]) char* filename = 0; char option; bool dryrun = false; - bool forced = false; #ifdef LC_ALL setlocale(LC_ALL, ""); @@ -60,7 +57,7 @@ void main(int argc, char* argv[]) while (1) { - option = getopt_long(argc, argv, "fhnl:", opts, NULL); + option = getopt_long(argc, argv, "hnl:", opts, NULL); if (option == -1) break; switch (option) @@ -69,9 +66,6 @@ void main(int argc, char* argv[]) case '?': printHelp(); exit(0); - case 'f': - forced = true; - break; case 'l': logLevel = atoi(optarg); break; @@ -118,7 +112,6 @@ void main(int argc, char* argv[]) { SISInstaller installer; installer.setPsion(psion); - installer.setForced(forced); installer.run(&sisFile, buf, len); } } -- cgit v1.2.3