Index: third_party/bspatch/mbspatch.cc |
diff --git a/third_party/bspatch/mbspatch.cc b/third_party/bspatch/mbspatch.cc |
index d00bc99d1297b4cc9bd032f2831f4267b44c7064..db8392839ac20384c7aa70555187f288a297196a 100644 |
--- a/third_party/bspatch/mbspatch.cc |
+++ b/third_party/bspatch/mbspatch.cc |
@@ -34,6 +34,7 @@ |
#include "mbspatch.h" |
#include <sys/stat.h> |
+#include <sys/types.h> |
#include <stdlib.h> |
#include <stdio.h> |
#include <fcntl.h> |
@@ -72,16 +73,33 @@ MBS_ReadHeader(int fd, MBSPatchHeader *header) |
struct stat hs; |
s = fstat(fd, &hs); |
- if (s) |
+ if (s != 0) |
return READ_ERROR; |
if (memcmp(header->tag, "MBDIFF10", 8) != 0) |
return UNEXPECTED_ERROR; |
- if (sizeof(MBSPatchHeader) + |
- header->cblen + |
- header->difflen + |
- header->extralen != int(hs.st_size)) |
+ if (hs.st_size > INT_MAX) |
+ return UNEXPECTED_ERROR; |
+ |
+ size_t size = static_cast<size_t>(hs.st_size); |
+ if (size < sizeof(MBSPatchHeader)) |
+ return UNEXPECTED_ERROR; |
+ size -= sizeof(MBSPatchHeader); |
+ |
+ if (size < header->cblen) |
+ return UNEXPECTED_ERROR; |
+ size -= header->cblen; |
+ |
+ if (size < header->difflen) |
+ return UNEXPECTED_ERROR; |
+ size -= header->difflen; |
+ |
+ if (size < header->extralen) |
+ return UNEXPECTED_ERROR; |
+ size -= header->extralen; |
+ |
+ if (size != 0) |
return UNEXPECTED_ERROR; |
return OK; |
@@ -91,6 +109,7 @@ int |
MBS_ApplyPatch(const MBSPatchHeader *header, int patchfd, |
unsigned char *fbuffer, int filefd) |
{ |
+ unsigned char *fbufstart = fbuffer; |
unsigned char *fbufend = fbuffer + header->slen; |
unsigned char *buf = (unsigned char*) malloc(header->cblen + |
@@ -111,6 +130,7 @@ MBS_ApplyPatch(const MBSPatchHeader *header, int patchfd, |
} |
r -= c; |
+ wb += c; |
if (c == 0 && r) { |
rv = UNEXPECTED_ERROR; |
@@ -120,6 +140,11 @@ MBS_ApplyPatch(const MBSPatchHeader *header, int patchfd, |
{ |
MBSPatchTriple *ctrlsrc = (MBSPatchTriple*) buf; |
+ if (header->cblen % sizeof(MBSPatchTriple) != 0) { |
+ rv = UNEXPECTED_ERROR; |
+ goto end; |
+ } |
+ |
unsigned char *diffsrc = buf + header->cblen; |
unsigned char *extrasrc = diffsrc + header->difflen; |
@@ -127,7 +152,7 @@ MBS_ApplyPatch(const MBSPatchHeader *header, int patchfd, |
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); |
@@ -144,8 +169,8 @@ MBS_ApplyPatch(const MBSPatchHeader *header, int patchfd, |
/* 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<size_t>(fbufend - fbuffer) || |
+ ctrlsrc->x > static_cast<size_t>(diffend - diffsrc)) { |
rv = UNEXPECTED_ERROR; |
goto end; |
} |
@@ -161,7 +186,7 @@ MBS_ApplyPatch(const MBSPatchHeader *header, int patchfd, |
/* Copy y bytes from the extra block */ |
- if (extrasrc + ctrlsrc->y > extraend) { |
+ if (ctrlsrc->y > static_cast<size_t>(extraend - extrasrc)) { |
rv = UNEXPECTED_ERROR; |
goto end; |
} |
@@ -173,7 +198,8 @@ MBS_ApplyPatch(const MBSPatchHeader *header, int patchfd, |
/* "seek" forwards in oldfile by z bytes */ |
- if (fbuffer + ctrlsrc->z > fbufend) { |
+ if (ctrlsrc->z < fbufstart - fbuffer || |
+ ctrlsrc->z > fbufend - fbuffer) { |
rv = UNEXPECTED_ERROR; |
goto end; |
} |
@@ -182,7 +208,7 @@ MBS_ApplyPatch(const MBSPatchHeader *header, int patchfd, |
/* and on to the next control block */ |
++ctrlsrc; |
- } while (ctrlsrc < ctrlend); |
+ } |
} |
end: |