• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

system/corennnnn


Commit MetaInfo

修訂a47780b99894478ec68fc246c4c8725c54ac89f6 (tree)
時間2016-09-21 17:26:10
作者Narayan Kamath <narayan@goog...>
Commiterandroid-build-merger

Log Message

libzipfile: add additional validity checks. am: a1ec23634a
am: c307830f5d

Change-Id: I5d856cec4528541ff5416456cbe1338c78a09699

Change Summary

差異

--- a/libzipfile/centraldir.c
+++ b/libzipfile/centraldir.c
@@ -60,16 +60,20 @@ read_central_dir_values(Zipfile* file, const unsigned char* buf, int len)
6060 return 0;
6161 }
6262
63+static const int kCompressionStored = 0x0;
64+static const int kCompressionDeflate = 0x8;
65+
6366 static int
6467 read_central_directory_entry(Zipfile* file, Zipentry* entry,
6568 const unsigned char** buf, ssize_t* len)
6669 {
6770 const unsigned char* p;
71+ size_t remaining;
72+ const unsigned char* bufLimit;
6873
6974 unsigned short versionMadeBy;
7075 unsigned short versionToExtract;
7176 unsigned short gpBitFlag;
72- unsigned short compressionMethod;
7377 unsigned short lastModFileTime;
7478 unsigned short lastModFileDate;
7579 unsigned long crc32;
@@ -84,8 +88,9 @@ read_central_directory_entry(Zipfile* file, Zipentry* entry,
8488 unsigned int dataOffset;
8589 unsigned short lfhExtraFieldSize;
8690
87-
8891 p = *buf;
92+ remaining = *len;
93+ bufLimit = file->buf + file->bufsize;
8994
9095 if (*len < ENTRY_LEN) {
9196 fprintf(stderr, "cde entry not large enough\n");
@@ -115,41 +120,88 @@ read_central_directory_entry(Zipfile* file, Zipentry* entry,
115120 localHeaderRelOffset = read_le_int(&p[0x2a]);
116121
117122 p += ENTRY_LEN;
123+ remaining -= ENTRY_LEN;
118124
119125 // filename
120126 if (entry->fileNameLength != 0) {
127+ if (entry->fileNameLength > remaining) {
128+ fprintf(stderr, "cde entry not large enough for file name.\n");
129+ return 1;
130+ }
131+
121132 entry->fileName = p;
122133 } else {
123- entry->fileName = NULL;
134+ fprintf(stderr, "cde entry does not contain a file name.\n");
135+ return 1;
124136 }
125137 p += entry->fileNameLength;
138+ remaining -= entry->fileNameLength;
126139
127- // extra field
140+ // extra field, if any
128141 if (extraFieldLength != 0) {
142+ if (extraFieldLength > remaining) {
143+ fprintf(stderr, "cde entry not large enough for extra field.\n");
144+ return 1;
145+ }
146+
129147 extraField = p;
130148 } else {
131149 extraField = NULL;
132150 }
133151 p += extraFieldLength;
152+ remaining -= extraFieldLength;
134153
135154 // comment, if any
136155 if (fileCommentLength != 0) {
156+ if (fileCommentLength > remaining) {
157+ fprintf(stderr, "cde entry not large enough for file comment.\n");
158+ return 1;
159+ }
160+
137161 fileComment = p;
138162 } else {
139163 fileComment = NULL;
140164 }
141165 p += fileCommentLength;
166+ remaining -= fileCommentLength;
142167
143168 *buf = p;
169+ *len = remaining;
144170
145171 // the size of the extraField in the central dir is how much data there is,
146172 // but the one in the local file header also contains some padding.
147173 p = file->buf + localHeaderRelOffset;
174+ if (p >= bufLimit) {
175+ fprintf(stderr, "Invalid local header offset for entry.\n");
176+ return 1;
177+ }
178+
148179 extraFieldLength = read_le_short(&p[0x1c]);
149180
150181 dataOffset = localHeaderRelOffset + LFH_SIZE
151182 + entry->fileNameLength + extraFieldLength;
152183 entry->data = file->buf + dataOffset;
184+
185+ // Sanity check: make sure that the start of the entry data is within
186+ // our allocated buffer.
187+ if ((entry->data < file->buf) || (entry->data >= bufLimit)) {
188+ fprintf(stderr, "Invalid data offset for entry.\n");
189+ return 1;
190+ }
191+
192+ // Sanity check: make sure that the end of the entry data is within
193+ // our allocated buffer. We need to look at the uncompressedSize for
194+ // stored entries and the compressed size for deflated entries.
195+ if ((entry->compressionMethod == kCompressionStored) &&
196+ (entry->uncompressedSize > (unsigned int) (bufLimit - entry->data))) {
197+ fprintf(stderr, "Invalid uncompressed size for stored entry.\n");
198+ return 1;
199+ }
200+ if ((entry->compressionMethod == kCompressionDeflate) &&
201+ (entry->compressedSize > (unsigned int) (bufLimit - entry->data))) {
202+ fprintf(stderr, "Invalid uncompressed size for deflated entry.\n");
203+ return 1;
204+ }
153205 #if 0
154206 printf("file->buf=%p entry->data=%p dataOffset=%x localHeaderRelOffset=%d "
155207 "entry->fileNameLength=%d extraFieldLength=%d\n",
--- a/libzipfile/test_zipfile.c
+++ b/libzipfile/test_zipfile.c
@@ -75,7 +75,6 @@ main(int argc, char** argv)
7575 unsize = get_zipentry_size(entry);
7676 size = unsize * 1.001;
7777 scratch = malloc(size);
78- printf("scratch=%p\n", scratch);
7978 err = decompress_zipentry(entry, scratch, size);
8079 if (err != 0) {
8180 fprintf(stderr, "error decompressing file\n");