mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1391268 - 1. Add call to verify CRC; r=glandium
To reliably detect corrupt APK, this patch adds a GeckoLoader.verifyCRC call to enable verification of CRC before extracting libs. MozReview-Commit-ID: 5EpIfwREGIv
This commit is contained in:
parent
b9be133138
commit
589e7e1a01
@ -491,6 +491,7 @@ public final class GeckoLoader {
|
||||
|
||||
// These methods are implemented in mozglue/android/nsGeckoUtils.cpp
|
||||
private static native void putenv(String map);
|
||||
public static native boolean verifyCRCs(String apkName);
|
||||
|
||||
// These methods are implemented in mozglue/android/APKOpen.cpp
|
||||
public static native void nativeRun(String[] args, int crashFd, int ipcFd, int crashAnnotationFd);
|
||||
|
@ -26,6 +26,22 @@ Java_org_mozilla_gecko_mozglue_GeckoLoader_putenv(JNIEnv *jenv, jclass, jstring
|
||||
jenv->ReleaseStringUTFChars(map, str);
|
||||
}
|
||||
|
||||
extern "C" APKOPEN_EXPORT jboolean MOZ_JNICALL
|
||||
Java_org_mozilla_gecko_mozglue_GeckoLoader_verifyCRCs(JNIEnv *jenv, jclass, jstring jApkName) {
|
||||
const char* str;
|
||||
// XXX: java doesn't give us true UTF8, we should figure out something
|
||||
// better to do here
|
||||
str = jenv->GetStringUTFChars(jApkName, nullptr);
|
||||
if (str == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<Zip> zip = Zip::Create(str);
|
||||
const bool valid = zip->VerifyCRCs();
|
||||
jenv->ReleaseStringUTFChars(jApkName, str);
|
||||
return jboolean(valid);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
__attribute__ ((visibility("default")))
|
||||
jobject MOZ_JNICALL
|
||||
|
@ -184,6 +184,67 @@ Zip::GetFirstEntry() const
|
||||
return entries;
|
||||
}
|
||||
|
||||
bool
|
||||
Zip::VerifyCRCs() const
|
||||
{
|
||||
AutoLock lock(&mutex);
|
||||
|
||||
for (const DirectoryEntry *entry = GetFirstEntry();
|
||||
entry; entry = entry->GetNext()) {
|
||||
const LocalFile *file = LocalFile::validate(
|
||||
static_cast<const char *>(mapped) + entry->offset);
|
||||
uint32_t crc = crc32(0, nullptr, 0);
|
||||
|
||||
DEBUG_LOG("%.*s: crc=%08x", int(entry->filenameSize),
|
||||
reinterpret_cast<const char *>(entry) + sizeof(*entry),
|
||||
uint32_t(entry->CRC32));
|
||||
|
||||
if (entry->compression == Stream::Type::STORE) {
|
||||
crc = crc32(crc, static_cast<const uint8_t*>(file->GetData()),
|
||||
entry->compressedSize);
|
||||
DEBUG_LOG(" STORE size=%d crc=%08x", int(entry->compressedSize), crc);
|
||||
|
||||
} else if (entry->compression == Stream::Type::DEFLATE) {
|
||||
zxx_stream zstream;
|
||||
Bytef buffer[1024];
|
||||
zstream.avail_in = entry->compressedSize;
|
||||
zstream.next_in = reinterpret_cast<Bytef *>(
|
||||
const_cast<void *>(file->GetData()));
|
||||
|
||||
if (inflateInit2(&zstream, -MAX_WBITS) != Z_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
zstream.avail_out = sizeof(buffer);
|
||||
zstream.next_out = buffer;
|
||||
|
||||
int ret = inflate(&zstream, Z_SYNC_FLUSH);
|
||||
crc = crc32(crc, buffer, sizeof(buffer) - zstream.avail_out);
|
||||
|
||||
if (ret == Z_STREAM_END) {
|
||||
break;
|
||||
} else if (ret != Z_OK) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inflateEnd(&zstream);
|
||||
DEBUG_LOG(" DEFLATE size=%d crc=%08x", int(zstream.total_out), crc);
|
||||
|
||||
} else {
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected stream type");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry->CRC32 != crc) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ZipCollection ZipCollection::Singleton;
|
||||
|
||||
static pthread_mutex_t sZipCollectionMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
@ -263,6 +263,11 @@ public:
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether all files have correct CRC checksum.
|
||||
*/
|
||||
bool VerifyCRCs() const;
|
||||
|
||||
private:
|
||||
/* File name of the archive */
|
||||
char *name;
|
||||
|
Loading…
Reference in New Issue
Block a user