Bug 826052: Make HashStore explicitly reject files larger than UINT32_MAX bytes, to avoid precision issues when we pass the file-length as a uint32_t function argument. (Also, skip a redundant file-size lookup.) r=gcp

This commit is contained in:
Daniel Holbert 2013-01-03 00:38:24 -08:00
parent 3a76fec135
commit b8579b5bf1
2 changed files with 25 additions and 17 deletions

View File

@ -185,7 +185,8 @@ HashStore::Reset()
}
nsresult
HashStore::CheckChecksum(nsIFile* aStoreFile)
HashStore::CheckChecksum(nsIFile* aStoreFile,
uint32_t aFileSize)
{
// Check for file corruption by
// comparing the stored checksum to actual checksum of data
@ -194,21 +195,17 @@ HashStore::CheckChecksum(nsIFile* aStoreFile)
char *data;
uint32_t read;
int64_t fileSize;
nsresult rv = aStoreFile->GetFileSize(&fileSize);
NS_ENSURE_SUCCESS(rv, rv);
if (fileSize < 0) {
return NS_ERROR_FAILURE;
}
rv = CalculateChecksum(hash, fileSize, true);
nsresult rv = CalculateChecksum(hash, aFileSize, true);
NS_ENSURE_SUCCESS(rv, rv);
compareHash.GetMutableData(&data, hash.Length());
if (hash.Length() > aFileSize) {
NS_WARNING("SafeBrowing file not long enough to store its hash");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsISeekableStream> seekIn = do_QueryInterface(mInputStream);
rv = seekIn->Seek(nsISeekableStream::NS_SEEK_SET, fileSize-hash.Length());
rv = seekIn->Seek(nsISeekableStream::NS_SEEK_SET, aFileSize - hash.Length());
NS_ENSURE_SUCCESS(rv, rv);
rv = mInputStream->Read(data, hash.Length(), &read);
@ -248,11 +245,17 @@ HashStore::Open()
rv = storeFile->GetFileSize(&fileSize);
NS_ENSURE_SUCCESS(rv, rv);
if (fileSize < 0 || fileSize > UINT32_MAX) {
return NS_ERROR_FAILURE;
}
uint32_t fileSize32 = static_cast<uint32_t>(fileSize);
rv = NS_NewBufferedInputStream(getter_AddRefs(mInputStream), origStream,
fileSize);
fileSize32);
NS_ENSURE_SUCCESS(rv, rv);
rv = CheckChecksum(storeFile);
rv = CheckChecksum(storeFile, fileSize32);
SUCCESS_OR_RESET(rv);
rv = ReadHeader();
@ -301,7 +304,7 @@ HashStore::SanityCheck()
nsresult
HashStore::CalculateChecksum(nsAutoCString& aChecksum,
int64_t aSize,
uint32_t aFileSize,
bool aChecksumPresent)
{
aChecksum.Truncate();
@ -324,7 +327,11 @@ HashStore::CalculateChecksum(nsAutoCString& aChecksum,
rv = hash->UpdateFromStream(mInputStream, UINT32_MAX);
} else {
// Hash everything but last checksum bytes
rv = hash->UpdateFromStream(mInputStream, aSize-CHECKSUM_SIZE);
if (aFileSize < CHECKSUM_SIZE) {
NS_WARNING("SafeBrowsing file isn't long enough to store its checksum");
return NS_ERROR_FAILURE;
}
rv = hash->UpdateFromStream(mInputStream, aFileSize - CHECKSUM_SIZE);
}
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -119,8 +119,9 @@ private:
nsresult ReadHeader();
nsresult SanityCheck();
nsresult CalculateChecksum(nsAutoCString& aChecksum, int64_t aSize, bool aChecksumPresent);
nsresult CheckChecksum(nsIFile* aStoreFile);
nsresult CalculateChecksum(nsAutoCString& aChecksum, uint32_t aFileSize,
bool aChecksumPresent);
nsresult CheckChecksum(nsIFile* aStoreFile, uint32_t aFileSize);
void UpdateHeader();
nsresult ReadChunkNumbers();