Index: third_party/bspatch/mbspatch.cc |
diff --git a/third_party/bspatch/mbspatch.cc b/third_party/bspatch/mbspatch.cc |
index d00bc99d1297b4cc9bd032f2831f4267b44c7064..d74e93b5f91cbb0e63cf6d8f2c1ee94aeeaead83 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,29 @@ 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); |
kcwu
2016/07/27 04:14:36
size -= sizeof(MBSPatchHeader);
rickyz (no longer on Chrome)
2016/07/27 04:24:14
Done.
|
+ if (slen < header->cblen || header->cblen % sizeof(MBSPatchTriple) != 0) |
kcwu
2016/07/27 04:14:36
s/slen/size/
rickyz (no longer on Chrome)
2016/07/27 04:24:14
Done.
|
+ 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 +105,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 +126,7 @@ MBS_ApplyPatch(const MBSPatchHeader *header, int patchfd, |
} |
r -= c; |
+ wb += c |
kcwu
2016/07/27 04:14:36
good catch. but missed semicolon;
rickyz (no longer on Chrome)
2016/07/27 04:24:14
Oops, apologies for all of the build errors, been
|
if (c == 0 && r) { |
rv = UNEXPECTED_ERROR; |
@@ -120,6 +136,11 @@ MBS_ApplyPatch(const MBSPatchHeader *header, int patchfd, |
{ |
MBSPatchTriple *ctrlsrc = (MBSPatchTriple*) buf; |
+ if (header->cblen % sizeof(MBSPatchTriple) != 0) { |
kcwu
2016/07/27 04:14:36
This is redundant? You have checked it in MBS_Read
rickyz (no longer on Chrome)
2016/07/27 04:24:14
I was debating between doing validation earlier vs
|
+ rv = UNEXPECTED_ERROR; |
+ goto end; |
+ } |
+ |
unsigned char *diffsrc = buf + header->cblen; |
unsigned char *extrasrc = diffsrc + header->difflen; |
@@ -127,7 +148,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 +165,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 > fbufend - fbuffer || |
+ ctrlsrc->x > diffend - diffsrc) { |
rv = UNEXPECTED_ERROR; |
goto end; |
} |
@@ -161,7 +182,7 @@ MBS_ApplyPatch(const MBSPatchHeader *header, int patchfd, |
/* Copy y bytes from the extra block */ |
- if (extrasrc + ctrlsrc->y > extraend) { |
+ if (ctrlsrc->y > extraend - extrasrc) { |
rv = UNEXPECTED_ERROR; |
goto end; |
} |
@@ -173,7 +194,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 +204,7 @@ MBS_ApplyPatch(const MBSPatchHeader *header, int patchfd, |
/* and on to the next control block */ |
++ctrlsrc; |
- } while (ctrlsrc < ctrlend); |
+ } |
} |
end: |