Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 49 additions & 5 deletions appx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1503,6 +1503,7 @@ static int zipAppendSignatureFile(BIO *bio, ZIP_FILE *zip, uint8_t *data, uint64
if (!get_current_position(bio, &offset)) {
fprintf(stderr, "Unable to get offset\n");
OPENSSL_free(header.fileName);
header.fileName = NULL;
OPENSSL_free(dataToWrite);
return 0; /* FAILED */
}
Expand All @@ -1513,6 +1514,7 @@ static int zipAppendSignatureFile(BIO *bio, ZIP_FILE *zip, uint8_t *data, uint64
if (!BIO_write_ex(bio, dataToWrite + written, toWrite, &check)
|| check != toWrite) {
OPENSSL_free(header.fileName);
header.fileName = NULL;
OPENSSL_free(dataToWrite);
return 0; /* FAILED */
}
Expand Down Expand Up @@ -1685,6 +1687,8 @@ static int zipRewriteData(ZIP_FILE *zip, ZIP_CENTRAL_DIRECTORY_ENTRY *entry, BIO
out:
OPENSSL_free(header.fileName);
OPENSSL_free(header.extraField);
header.fileName = NULL;
header.extraField = NULL;
return ret;
}

Expand Down Expand Up @@ -1852,6 +1856,11 @@ static size_t zipReadFileData(ZIP_FILE *zip, uint8_t **pData, ZIP_CENTRAL_DIRECT
}
if (entry->overrideData) {
compressedSize = entry->overrideData->compressedSize;
/* Validate sizes for safe allocation */
if (compressedSize > (uint64_t)(SIZE_MAX - 1)) {
fprintf(stderr, "Corrupted compressedSize : %" PRIu64"\n", compressedSize);
return 0; /* FAILED */
}
uncompressedSize = entry->overrideData->uncompressedSize;
compressedData = OPENSSL_zalloc(compressedSize + 1);
memcpy(compressedData, entry->overrideData->data, compressedSize);
Expand All @@ -1863,6 +1872,8 @@ static size_t zipReadFileData(ZIP_FILE *zip, uint8_t **pData, ZIP_CENTRAL_DIRECT
if (!zipReadLocalHeader(&header, zip, compressedSize)) {
OPENSSL_free(header.fileName);
OPENSSL_free(header.extraField);
header.fileName = NULL;
header.extraField = NULL;
return 0; /* FAILED */
}
if (header.fileNameLen != entry->fileNameLen
Expand All @@ -1873,14 +1884,20 @@ static size_t zipReadFileData(ZIP_FILE *zip, uint8_t **pData, ZIP_CENTRAL_DIRECT
fprintf(stderr, "Local header does not match central directory entry\n");
OPENSSL_free(header.fileName);
OPENSSL_free(header.extraField);
header.fileName = NULL;
header.extraField = NULL;
return 0; /* FAILED */
}
/* we don't really need those */
OPENSSL_free(header.fileName);
OPENSSL_free(header.extraField);
header.fileName = NULL;
header.extraField = NULL;

if (compressedSize > (uint64_t)zip->fileSize - entry->offsetOfLocalHeader) {
fprintf(stderr, "Corrupted compressedSize : 0x%08" PRIX64 "\n", entry->compressedSize);
/* Validate sizes for safe allocation */
if (compressedSize > (uint64_t)(SIZE_MAX - 1)
|| compressedSize > (uint64_t)zip->fileSize - entry->offsetOfLocalHeader) {
fprintf(stderr, "Corrupted compressedSize : %" PRIu64"\n", compressedSize);
return 0; /* FAILED */
}
compressedData = OPENSSL_zalloc(compressedSize + 1);
Expand All @@ -1899,11 +1916,24 @@ static size_t zipReadFileData(ZIP_FILE *zip, uint8_t **pData, ZIP_CENTRAL_DIRECT
*pData = compressedData;
dataSize = compressedSize;
} else if (entry->compression == COMPRESSION_DEFLATE) {
uint8_t *uncompressedData = OPENSSL_zalloc(uncompressedSize + 1);
uint64_t destLen = uncompressedSize;
uint64_t sourceLen = compressedSize;
uint8_t *uncompressedData;
uint64_t destLen, sourceLen;
int ret;

/* Validate sizes for safe allocation */
if (uncompressedSize > (uint64_t)(SIZE_MAX - 1)) {
fprintf(stderr, "Corrupted uncompressedSize : %" PRIu64"\n", uncompressedSize);
return 0; /* FAILED */
}
/* Detect suspicious compression ratio (zip bomb protection) */
if (uncompressedSize > 1024 * 1024 && uncompressedSize / 100 >= compressedSize) {
fprintf(stderr, "Error: suspicious compression ratio\n");
return 0; /* FAILED */
}
uncompressedData = OPENSSL_zalloc(uncompressedSize + 1);
destLen = uncompressedSize;
sourceLen = compressedSize;

ret = zipInflate(uncompressedData, &destLen, compressedData, (uLong *)&sourceLen);
OPENSSL_free(compressedData);

Expand Down Expand Up @@ -1970,6 +2000,8 @@ static int zipReadLocalHeader(ZIP_LOCAL_HEADER *header, ZIP_FILE *zip, uint64_t
header->extraFieldLen = fileGetU16(file);
/* file name (variable size) */
if (header->fileNameLen > 0) {
/* fileNameLen is uint16_t (ZIP spec, 2-byte field),
* so fileNameLen + 1 cannot overflow size_t */
header->fileName = OPENSSL_zalloc(header->fileNameLen + 1);
size = fread(header->fileName, 1, header->fileNameLen, file);
if (size != header->fileNameLen) {
Expand All @@ -1981,6 +2013,8 @@ static int zipReadLocalHeader(ZIP_LOCAL_HEADER *header, ZIP_FILE *zip, uint64_t
}
/* extra field (variable size) */
if (header->extraFieldLen > 0) {
/* extraFieldLen is uint16_t (ZIP spec, 2-byte field),
* so extraFieldLen + 1 cannot overflow size_t */
header->extraField = OPENSSL_zalloc(header->extraFieldLen + 1);
size = fread(header->extraField, 1, header->extraFieldLen, file);
if (size != header->extraFieldLen) {
Expand Down Expand Up @@ -2011,6 +2045,8 @@ static int zipReadLocalHeader(ZIP_LOCAL_HEADER *header, ZIP_FILE *zip, uint64_t
fprintf(stderr, "The input file is not a valid zip file - flags indicate data descriptor, but data descriptor signature does not match\n");
OPENSSL_free(header->fileName);
OPENSSL_free(header->extraField);
header->fileName = NULL;
header->extraField = NULL;
return 0; /* FAILED */
}
header->crc32 = fileGetU32(file);
Expand Down Expand Up @@ -2477,6 +2513,8 @@ static ZIP_CENTRAL_DIRECTORY_ENTRY *zipReadNextCentralDirectoryEntry(FILE *file)
entry->offsetOfLocalHeader = fileGetU32(file);
/* file name (variable size) */
if (entry->fileNameLen > 0) {
/* fileNameLen is uint16_t (ZIP spec, 2-byte field),
* so fileNameLen + 1 cannot overflow size_t */
entry->fileName = OPENSSL_zalloc(entry->fileNameLen + 1);
size = fread(entry->fileName, 1, entry->fileNameLen, file);
if (size != entry->fileNameLen) {
Expand All @@ -2487,6 +2525,8 @@ static ZIP_CENTRAL_DIRECTORY_ENTRY *zipReadNextCentralDirectoryEntry(FILE *file)
}
/* extra field (variable size) */
if (entry->extraFieldLen > 0) {
/* extraFieldLen is uint16_t (ZIP spec, 2-byte field),
* so extraFieldLen + 1 cannot overflow size_t */
entry->extraField = OPENSSL_zalloc(entry->extraFieldLen + 1);
size = fread(entry->extraField, 1, entry->extraFieldLen, file);
if (size != entry->extraFieldLen) {
Expand All @@ -2497,6 +2537,8 @@ static ZIP_CENTRAL_DIRECTORY_ENTRY *zipReadNextCentralDirectoryEntry(FILE *file)
}
/* file comment (variable size) */
if (entry->fileCommentLen > 0) {
/* fileCommentLen is uint16_t (ZIP spec, 2-byte field),
* so fileCommentLen + 1 cannot overflow size_t */
entry->fileComment = OPENSSL_zalloc(entry->fileCommentLen + 1);
size = fread(entry->fileComment, 1, entry->fileCommentLen, file);
if (size != entry->fileCommentLen) {
Expand Down Expand Up @@ -2635,6 +2677,8 @@ static int readZipEOCDR(ZIP_EOCDR *eocdr, FILE *file)
}
#endif
if (eocdr->commentLen > 0) {
/* ZIP_EOCDR commentLen is uint16_t (ZIP spec, 2-byte field),
* so fileCommentLen + 1 cannot overflow size_t */
eocdr->comment = OPENSSL_zalloc(eocdr->commentLen + 1);
size = fread(eocdr->comment, 1, eocdr->commentLen, file);
if (size != eocdr->commentLen) {
Expand Down
Loading