Skip to content

Fix crash when external functions are covered#13

Open
SeTcbPrivilege wants to merge 2 commits into
nccgroup:mainfrom
SeTcbPrivilege:fix-external-function-coverage
Open

Fix crash when external functions are covered#13
SeTcbPrivilege wants to merge 2 commits into
nccgroup:mainfrom
SeTcbPrivilege:fix-external-function-coverage

Conversation

@SeTcbPrivilege
Copy link
Copy Markdown

We recently encountered a crash when we were using Cartographer to analyze coverage for embedded firmware:

A NullPointerException is thrown when loading a coverage file, the relevant stack trace is below:

Cannot invoke "cartographer.CoverageFunction.addCoverageBlock(ghidra.program.model.address.Address, java.lang.Integer)" because "ccFunc" is null
java.lang.NullPointerException: Cannot invoke "cartographer.CoverageFunction.addCoverageBlock(ghidra.program.model.address.Address, java.lang.Integer)" because "ccFunc" is null
	at cartographer.CoverageFile.populateBlocks(CoverageFile.java:588)
	at cartographer.CartographerPlugin.loadCoverageFile(CartographerPlugin.java:552)
	at cartographer.CartographerPlugin.processCoverageFile(CartographerPlugin.java:587)
	at cartographer.CartographerPlugin$2.lambda$actionPerformed$0(CartographerPlugin.java:303)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
	at cartographer.CartographerPlugin$2.actionPerformed(CartographerPlugin.java:291)
	at docking.DockingActionProxy.actionPerformed(DockingActionProxy.java:47)
	at docking.MenuBarMenuHandler.lambda$processMenuAction$0(MenuBarMenuHandler.java:60)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

---------------------------------------------------
Build Date: 2024-Apr-10 1518 EDT
Ghidra Version: 11.0.3
Java Home: /usr/lib/jvm/java-21-openjdk-amd64
JVM Version: Ubuntu 21.0.3
OS: Linux 6.8.0-36-generic amd64

I found that the crash is caused when Cartographer tries to add a basic block that is inside a function that is classified as External by Ghidra. In the CartographerPlugin.LoadCoverageFile function, all functions are collected using the iterator currentProgram.getFunctionManager().getFunctions(true), which does not include external functions. When a BB is processed whose address matches the entrypoint of an external function, the call program.getFunctionManager().getFunctionContaining(address) returns this external function. This is not present in the ccFunctionMap, so the map lookup returns null and we get a NPE.

Admittedly, having coverage for external functions is a bit of an edge-case. In our situation, we were analyzing a firmware that is split into a secure and non-secure part which are both provided as separate binaries, but run on the same system. Therefore we have a coverage file that contains coverage over both parts. In this case, one of the functions calling from non-secure into secure mode was defined as an external symbol in the non-secure binary. I am not able to share the binaries since they are under NDA, but I have created a simple example binary and coverage file to reproduce the issue.

sample.zip

The crash can be resolved by checking whether the covered function is external and skipping the BB addition

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant