ghidra: Denial of Service via Uncontrolled Resource Consumption When Importing TAR/Zip Archive
What fixes it
- 12.2ghidra, ghidraGitHub
A fixed version on one release line is not the upgrade target for every line. Check your exact version and any vendor backports.
Description
Summary
The application fails to enforce any limit on the number of entries it will process from a user-supplied tar/zip archive. After successfully hashing all entries, the software enters an indexing routine that loops over every entry performing per-entry work with no upper bound, timeout, or throttling. A crafted tar/zip archive containing an excessively large number of entries causes unbounded memory allocation during this loop, exhausting available system memory. The application's UI thread is blocked for the duration of this operation, so the process does not respond to cancel or close requests, and the memory exhaustion degrades or halts other applications running on the same system. Recovery requires the user to forcibly terminate the process (e.g., via Task Manager / kill -9); the OS out-of-memory killer, if configured at all, only intervenes as a last resort after significant system-wide impact, resulting in a denial-of-service condition and loss of system availability.
The below sections outline the TAR case only. The Zip case is similar.
Details
TarFileSystem.java:
void mount(TaskMonitor monitor) throws IOException, CancelledException {
try (TarArchiveInputStream tarInput =
new TarArchiveInputStream(provider.getInputStream(0))) {
TarArchiveEntry tarEntry;
while ((tarEntry = tarInput.getNextEntry()) != null) {
monitor.setMessage(tarEntry.getName());
monitor.checkCancelled();
int fileNum = fileCount++;
String linkName = tarEntry.getLinkName();
TarMetadata tmd = new TarMetadata(tarEntry, fileNum);
GFile newFile = !tarEntry.isSymbolicLink()
? fsIndex.storeFile(tarEntry.getName(), fileCount, tarEntry.isDirectory(),
tarEntry.getSize(), tmd)
: fsIndex.storeSymlink(tarEntry.getName(), fileCount, linkName,
linkName.length(), tmd);
if (!tarEntry.isSymbolicLink() &&
tarEntry.getSize() < FileCache.MAX_INMEM_FILESIZE) {
// because tar files are sequential access, we cache smaller files if they
// will fit in a in-memory ByteProvider
try (ByteProvider bp =
fsService.getDerivedByteProvider(fsFSRL.getContainer(), newFile.getFSRL(),
newFile.getPath(), tarEntry.getSize(), () -> tarInput, monitor)) {
fsIndex.updateFSRL(newFile,
newFile.getFSRL().withMD5(bp.getFSRL().getMD5()));
}
}
}
}
}Stack Trace
2026-09-03 17:06:34 ERROR (TaskBuilderTask) Task Error: Adding Source Files - Uncaught Exception: java.lang.OutOfMemoryError: Java heap space java.lang.OutOfMemoryError: Java heap space at ghidra.formats.gfilesystem.FSUtilities.streamCopy(FSUtilities.java:375) at ghidra.formats.gfilesystem.FileSystemService.getDerivedByteProvider(FileSystemService.java:427) at ghidra.file.formats.tar.TarFileSystem.mount(TarFileSystem.java:84) at ghidra.file.formats.tar.TarFileSystemFactory.create(TarFileSystemFactory.java:63) at ghidra.file.formats.tar.TarFileSystemFactory.create(TarFileSystemFactory.java:37) at ghidra.formats.gfilesystem.factory.FileSystemFactoryMgr.mountUsingFactory(FileSystemFactoryMgr.java:166) at ghidra.formats.gfilesystem.factory.FileSystemFactoryMgr.probe(FileSystemFactoryMgr.java:326) at ghidra.formats.gfilesystem.FileSystemService.probeFileForFilesystem(FileSystemService.java:718) at ghidra.formats.gfilesystem.FileSystemService.probeFileForFilesystem(FileSystemService.java:676) at ghidra.plugins.importer.batch.BatchInfo.processAsFS(BatchInfo.java:303) at ghidra.plugins.importer.batch.BatchInfo.doAddFile(BatchInfo.java:230) at ghidra.plugins.importer.batch.BatchInfo.addFile(BatchInfo.java:198) at ghidra.plugins.importer.batch.BatchInfo.doAddFiles(BatchInfo.java:503) at ghidra.plugins.importer.batch.BatchInfo$AddFilesRunnable.monitoredRun(BatchInfo.java:542) at ghidra.util.task.TaskBuilder$TaskBuilderTask.run(TaskBuilder.java:306) at ghidra.util.task.Task.monitoredRun(Task.java:134) at ghidra.util.task.TaskRunner.lambda$startTaskThread$0(TaskRunner.java:106) at ghidra.util.task.TaskRunner$$Lambda/0x00000000406f3350.run(Unknown Source) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614) at java.base/java.lang.Thread.runWith(Thread.java:1529) at java.base/java.lang.Thread.run(Thread.java:1516)
Impact
- Application-level DoS: Main/UI thread is blocked; the application becomes fully unresponsive to user input, including cancel and window-close actions.
- System-level DoS: Uncontrolled memory allocation exhausts system RAM and Cache, degrading or freezing other running applications.
- Availability of recovery: No graceful recovery path. Requires manual, forced process termination by the user (or an OS-level OOM killer, if present, as a last-resort backstop). Depending upon the configuration, it may cause the machine to reboot itself to correct things.
- Low attacker cost / high impact asymmetry: A relatively small archive file (large entry count does not necessarily mean large file size) can trigger disproportionate resource consumption on the victim system.
Text from GitHub Advisory Database
Affected versions 1
- ghidra, ghidra< 12.2GitHub