ghidra: Denial of Service via Filesystem Inode Exhaustion During Extension Import
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
A maliciously crafted extension archive containing a very large number of files can cause the extension importer to exhaust the available filesystem inodes. Once inode pool is exhausted, subsequent imports and file creation operations fail, preventing ghidra and other system services from creating files and resulting in a denial-of-service condition and loss of system availability.
Details
unzipToInstallationFolder() is responsible for extracting Ghidra extension ZIP archives. Files from the archive are extracted directly to /home/USERNAME/.config/ghidra/ghidra*/Extensions on the host filesystem. If an archive contains very large number of files, the extraction can exhaust all available disk space or inode pool, preventing subsequent imports. Additionally, other applications on the affected system that depend on disk I/O may fail or become unable to perform required write operations.
Stack Trace
ERROR (ExtensionUtils) Error Installing Extension: Unexpected error installing extension java.io.IOException: No space left on device at java.base/java.io.FileOutputStream.writeBytes(Native Method) at java.base/java.io.FileOutputStream.write(FileOutputStream.java:352) at java.base/java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:123) at java.base/java.io.BufferedOutputStream.write(BufferedOutputStream.java:188) at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1457) at org.apache.commons.io.IOUtils.copy(IOUtils.java:1081) at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1429) at org.apache.commons.io.IOUtils.copy(IOUtils.java:1059) at ghidra.util.extensions.ExtensionUtils.writeZipEntryToFile(ExtensionUtils.java:634) at ghidra.util.extensions.ExtensionUtils.unzipToInstallationFolder(ExtensionUtils.java:597) at ghidra.util.extensions.ExtensionUtils.install(ExtensionUtils.java:103) at ghidra.framework.project.extensions.ExtensionInstaller.lambda$install$0(ExtensionInstaller.java:97) at ghidra.util.task.TaskLauncher$2.run(TaskLauncher.java:115) at ghidra.util.task.Task.monitoredRun(Task.java:134) at ghidra.util.task.TaskRunner.lambda$startTaskThread$0(TaskRunner.java:106) 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.run(Thread.java:1516) Suppressed: java.io.IOException: No space left on device at java.base/java.io.FileOutputStream.writeBytes(Native Method) at java.base/java.io.FileOutputStream.write(FileOutputStream.java:352) at java.base/java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:123) at java.base/java.io.BufferedOutputStream.flush(BufferedOutputStream.java:203) at java.base/java.io.FilterOutputStream.close(FilterOutputStream.java:184) at ghidra.util.extensions.ExtensionUtils.writeZipEntryToFile(ExtensionUtils.java:630) ... 9 more ERROR (IndexedV1LocalFileSystem) Failed to flush index file java.io.IOException: error occurred while writing filesystem index: /home/yuvraj/buc.rep/versioned/~index.tmp ///////// INODE COUNT IS EXHAUSTED THEREFORE NO WRITE OPERATION WILL SUCCEEDD at ghidra.framework.store.local.IndexedLocalFileSystem.writeIndex(IndexedLocalFileSystem.java:314) at ghidra.framework.store.local.IndexedLocalFileSystem.flushIndex(IndexedLocalFileSystem.java:269) at ghidra.framework.store.local.IndexedLocalFileSystem.dispose(IndexedLocalFileSystem.java:198)
yuvraj@archlinux ~]$ ls ~/.config/ghidra/ghidra_12.1.2_DEV/Extensions/ file_00000000.txt file_00000004.txt file_00000008.txt file_00000012.txt file_00000016.txt file_00000020.txt file_00000024.txt file_00000028.txt file_00000032.txt file_00000036.txt GhidraFindcrypt file_00000001.txt file_00000005.txt file_00000009.txt file_00000013.txt file_00000017.txt file_00000021.txt file_00000025.txt file_00000029.txt file_00000033.txt file_00000037.txt file_00000002.txt file_00000006.txt file_00000010.txt file_00000014.txt file_00000018.txt file_00000022.txt file_00000026.txt file_00000030.txt file_00000034.txt file_00000038.txt file_00000003.txt file_00000007.txt file_00000011.txt file_00000015.txt file_00000019.txt file_00000023.txt file_00000027.txt file_00000031.txt file_00000035.txt file_00000039.txt ... // Output omitted
Impact
The vulnerability allows an attacker to cause uncontrolled resource consumption by supplying a malicious archive with a very large number of files.
This can result in:
- excessive disk-space consumption;
- excessive CPU and I/O usage during decompression;
- failure of subsequent import operations;
- inability to perform other operations when inode pool is exhausted; and potentially denial of service if sufficient resources are consumed.
Note: Once available inode pool is exhausted, other system-wide applications that depend on disk I/O may fail or become unable to perform write operations.
Text from GitHub Advisory Database
Affected versions 1
- ghidra, ghidra< 12.2GitHub