diff --git a/CHANGELOG.md b/CHANGELOG.md index 9819fd0..5a1d139 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * Deprecated the initializers that take a file path instead of an `NSURL` (Issue #90, PR #95) * Fixed a crasher for unreadable files in `+pathIsAZip:` (Issue #99) * Deprecated all overloads of `-writeData:...` and `-writeIntoBuffer:...` that take any file properties other than the path, replacing them each with a single call that takes an instance of the new `ZipFileProperties`. This allows for all the default values to be defined in one place, so you can specify only where you want to deviate from the defaults (Issue #89, PR #97) +* Fixed buffer overrun vulnerability when deleting a file in an archive where not every file has a file comment (Issue #106) ## 1.9 diff --git a/Source/UZKArchive.m b/Source/UZKArchive.m index 8f822e7..dd1a4ae 100644 --- a/Source/UZKArchive.m +++ b/Source/UZKArchive.m @@ -1460,9 +1460,9 @@ - (BOOL)deleteFile:(NSString *)filePath error:(NSError * __autoreleasing*)error detail:detail]; } - UZKLogDebug("Allocating commentary"); - char *commentary = (char*)malloc(unzipInfo.size_file_comment); - if ((commentary == NULL) && (unzipInfo.size_file_comment != 0)) { + UZKLogDebug("Allocating file comment buffer"); + char *fileCommentBuffer = unzipInfo.size_file_comment > 0 ? (char*)malloc(unzipInfo.size_file_comment) : NULL; + if ((fileCommentBuffer == NULL) && (unzipInfo.size_file_comment != 0)) { NSString *detail = [NSString localizedStringWithFormat:NSLocalizedStringFromTableInBundle(@"Error allocating commentary info of %@ while deleting %@", @"UnzipKit", _resources, @"Detailed error string"), currentFileName, filePath]; UZKLogError("UZKErrorCodeDeleteFile: %{public}@", detail); @@ -1476,14 +1476,14 @@ - (BOOL)deleteFile:(NSString *)filePath error:(NSError * __autoreleasing*)error } UZKLogDebug("Getting file info"); - err = unzGetCurrentFileInfo64(source_zip, &unzipInfo, filename_inzip, FILE_IN_ZIP_MAX_NAME_LENGTH, extra_field, unzipInfo.size_file_extra, commentary, unzipInfo.size_file_comment); + err = unzGetCurrentFileInfo64(source_zip, &unzipInfo, filename_inzip, FILE_IN_ZIP_MAX_NAME_LENGTH, extra_field, unzipInfo.size_file_extra, fileCommentBuffer, unzipInfo.size_file_comment); if (err != UNZ_OK) { NSString *detail = [NSString localizedStringWithFormat:NSLocalizedStringFromTableInBundle(@"Error reading extra_field and commentary info of %@ while deleting %@ (%d)", @"UnzipKit", _resources, @"Detailed error string"), currentFileName, filePath, err]; UZKLogError("UZKErrorCodeDeleteFile: %{public}@", detail); UZKLogDebug("Closing source_zip, dest_zip, freeing global_comment, extra_field, commentary"); free(extra_field); - free(commentary); + free(fileCommentBuffer); return [self assignError:error code:UZKErrorCodeDeleteFile detail:detail]; } @@ -1503,7 +1503,7 @@ - (BOOL)deleteFile:(NSString *)filePath error:(NSError * __autoreleasing*)error unzClose(source_zip); free(global_comment); free(extra_field); - free(commentary); + free(fileCommentBuffer); return [self assignError:error code:UZKErrorCodeDeleteFile detail:detail]; } @@ -1519,7 +1519,7 @@ - (BOOL)deleteFile:(NSString *)filePath error:(NSError * __autoreleasing*)error unzClose(source_zip); free(global_comment); free(extra_field); - free(commentary); + free(fileCommentBuffer); return [self assignError:error code:UZKErrorCodeDeleteFile detail:detail]; } @@ -1535,7 +1535,7 @@ - (BOOL)deleteFile:(NSString *)filePath error:(NSError * __autoreleasing*)error unzClose(source_zip); free(global_comment); free(extra_field); - free(commentary); + free(fileCommentBuffer); return [self assignError:error code:UZKErrorCodeDeleteFile detail:detail]; } @@ -1550,7 +1550,7 @@ - (BOOL)deleteFile:(NSString *)filePath error:(NSError * __autoreleasing*)error unzClose(source_zip); free(global_comment); free(extra_field); - free(commentary); + free(fileCommentBuffer); free(local_extra); return [self assignError:error code:UZKErrorCodeDeleteFile detail:detail]; @@ -1568,7 +1568,7 @@ - (BOOL)deleteFile:(NSString *)filePath error:(NSError * __autoreleasing*)error unzClose(source_zip); free(global_comment); free(extra_field); - free(commentary); + free(fileCommentBuffer); free(local_extra); return [self assignError:error code:UZKErrorCodeDeleteFile detail:detail]; @@ -1586,7 +1586,7 @@ - (BOOL)deleteFile:(NSString *)filePath error:(NSError * __autoreleasing*)error unzClose(source_zip); free(global_comment); free(extra_field); - free(commentary); + free(fileCommentBuffer); free(local_extra); free(buf); return [self assignError:error code:UZKErrorCodeDeleteFile @@ -1604,7 +1604,7 @@ - (BOOL)deleteFile:(NSString *)filePath error:(NSError * __autoreleasing*)error UZKLogDebug("Opening file in destination archive"); err = zipOpenNewFileInZip2(dest_zip, filename_inzip, &zipInfo, - local_extra, size_local_extra, extra_field, (uInt)unzipInfo.size_file_extra, commentary, + local_extra, size_local_extra, extra_field, (uInt)unzipInfo.size_file_extra, fileCommentBuffer, method, level, 1); if (err != UNZ_OK) { NSString *detail = [NSString localizedStringWithFormat:NSLocalizedStringFromTableInBundle(@"Error opening %@ in destination zip while deleting %@ (%d)", @"UnzipKit", _resources, @"Detailed error string"), @@ -1615,7 +1615,7 @@ - (BOOL)deleteFile:(NSString *)filePath error:(NSError * __autoreleasing*)error unzClose(source_zip); free(global_comment); free(extra_field); - free(commentary); + free(fileCommentBuffer); free(local_extra); free(buf); return [self assignError:error code:UZKErrorCodeDeleteFile @@ -1634,7 +1634,7 @@ - (BOOL)deleteFile:(NSString *)filePath error:(NSError * __autoreleasing*)error unzClose(source_zip); free(global_comment); free(extra_field); - free(commentary); + free(fileCommentBuffer); free(local_extra); free(buf); return [self assignError:error code:UZKErrorCodeDeleteFile @@ -1653,7 +1653,7 @@ - (BOOL)deleteFile:(NSString *)filePath error:(NSError * __autoreleasing*)error unzClose(source_zip); free(global_comment); free(extra_field); - free(commentary); + free(fileCommentBuffer); free(local_extra); free(buf); return [self assignError:error code:UZKErrorCodeDeleteFile @@ -1672,7 +1672,7 @@ - (BOOL)deleteFile:(NSString *)filePath error:(NSError * __autoreleasing*)error unzClose(source_zip); free(global_comment); free(extra_field); - free(commentary); + free(fileCommentBuffer); free(local_extra); free(buf); return [self assignError:error code:UZKErrorCodeDeleteFile @@ -1681,7 +1681,7 @@ - (BOOL)deleteFile:(NSString *)filePath error:(NSError * __autoreleasing*)error UZKLogDebug("Freeing extra_field, commentary, local_extra, buf"); free(extra_field); - free(commentary); + free(fileCommentBuffer); free(local_extra); free(buf);