# HG changeset patch # User June Wilde # Date 1543343430 0 # Node ID 6798cc7aaed0765f259470eb5f7cac16d4310545 # Parent e54386a858606c13bd4c7c93426c8bacdab0d7b2 Bug 1468552 - Update bspatch.cpp to match Chromium version; r=rstrong Adds bounds checking around file reads and header values Differential Revision: https://phabricator.services.mozilla.com/D12356 diff --git a/toolkit/mozapps/update/updater/bspatch.cpp b/toolkit/mozapps/update/updater/bspatch.cpp --- a/toolkit/mozapps/update/updater/bspatch.cpp +++ b/toolkit/mozapps/update/updater/bspatch.cpp @@ -66,35 +66,53 @@ MBS_ReadHeader(FILE* file, MBSPatchHeade header->scrc32 = ntohl(header->scrc32); header->dlen = ntohl(header->dlen); header->cblen = ntohl(header->cblen); header->difflen = ntohl(header->difflen); header->extralen = ntohl(header->extralen); struct stat hs; s = fstat(fileno(file), &hs); - if (s) + if (s != 0) return READ_ERROR; if (memcmp(header->tag, "MBDIFF10", 8) != 0) return UNEXPECTED_BSPATCH_ERROR; - if (sizeof(MBSPatchHeader) + - header->cblen + - header->difflen + - header->extralen != uint32_t(hs.st_size)) + if (hs.st_size > INT_MAX) + return UNEXPECTED_BSPATCH_ERROR; + + size_t size = static_cast(hs.st_size); + if (size < sizeof(MBSPatchHeader)) + return UNEXPECTED_BSPATCH_ERROR; + size -= sizeof(MBSPatchHeader); + + if (size < header->cblen) + return UNEXPECTED_BSPATCH_ERROR; + size -= header->cblen; + + if (size < header->difflen) + return UNEXPECTED_BSPATCH_ERROR; + size -= header->difflen; + + if (size < header->extralen) + return UNEXPECTED_BSPATCH_ERROR; + size -= header->extralen; + + if (size != 0) return UNEXPECTED_BSPATCH_ERROR; return OK; } int MBS_ApplyPatch(const MBSPatchHeader *header, FILE* patchFile, unsigned char *fbuffer, FILE* file) { + unsigned char *fbufstart = fbuffer; unsigned char *fbufend = fbuffer + header->slen; unsigned char *buf = (unsigned char*) malloc(header->cblen + header->difflen + header->extralen); if (!buf) return BSPATCH_MEM_ERROR; @@ -107,81 +125,92 @@ MBS_ApplyPatch(const MBSPatchHeader *hea size_t c = fread(wb, 1, count, patchFile); if (c != count) { rv = READ_ERROR; goto end; } r -= c; wb += c; + + if (c == 0 && r) { + rv = UNEXPECTED_BSPATCH_ERROR; + goto end; + } } { MBSPatchTriple *ctrlsrc = (MBSPatchTriple*) buf; + if (header->cblen % sizeof(MBSPatchTriple) != 0) { + rv = UNEXPECTED_BSPATCH_ERROR; + goto end; + } + unsigned char *diffsrc = buf + header->cblen; unsigned char *extrasrc = diffsrc + header->difflen; MBSPatchTriple *ctrlend = (MBSPatchTriple*) diffsrc; unsigned char *diffend = extrasrc; unsigned char *extraend = extrasrc + header->extralen; - do { + while (ctrlsrc < ctrlend) { ctrlsrc->x = ntohl(ctrlsrc->x); ctrlsrc->y = ntohl(ctrlsrc->y); ctrlsrc->z = ntohl(ctrlsrc->z); #ifdef DEBUG_bsmedberg printf("Applying block:\n" " x: %u\n" " y: %u\n" " z: %i\n", ctrlsrc->x, ctrlsrc->y, ctrlsrc->z); #endif /* Add x bytes from oldfile to x bytes from the diff block */ - if (fbuffer + ctrlsrc->x > fbufend || - diffsrc + ctrlsrc->x > diffend) { + if (ctrlsrc->x > static_cast(fbufend - fbuffer) || + ctrlsrc->x > static_cast(diffend - diffsrc)) { rv = UNEXPECTED_BSPATCH_ERROR; goto end; } for (uint32_t i = 0; i < ctrlsrc->x; ++i) { diffsrc[i] += fbuffer[i]; } if ((uint32_t) fwrite(diffsrc, 1, ctrlsrc->x, file) != ctrlsrc->x) { rv = WRITE_ERROR_PATCH_FILE; goto end; } fbuffer += ctrlsrc->x; diffsrc += ctrlsrc->x; /* Copy y bytes from the extra block */ - if (extrasrc + ctrlsrc->y > extraend) { + if (ctrlsrc->y > static_cast(extraend - extrasrc)) { rv = UNEXPECTED_BSPATCH_ERROR; goto end; } if ((uint32_t) fwrite(extrasrc, 1, ctrlsrc->y, file) != ctrlsrc->y) { rv = WRITE_ERROR_PATCH_FILE; goto end; } extrasrc += ctrlsrc->y; /* "seek" forwards in oldfile by z bytes */ - if (fbuffer + ctrlsrc->z > fbufend) { + if (ctrlsrc->z < fbufstart - fbuffer || + ctrlsrc->z > fbufend - fbuffer) { rv = UNEXPECTED_BSPATCH_ERROR; goto end; } fbuffer += ctrlsrc->z; /* and on to the next control block */ ++ctrlsrc; - } while (ctrlsrc < ctrlend); + } } end: free(buf); return rv; }