Steps to Reproduce
During a technical code audit, multiple instances of unmanaged Process and FileOutputStream resources were found. These issues occur via static code paths and do not require runtime steps to reproduce, but they happen when specific logic triggers (e.g., CLI permission checks, platform OS detection, and block exporting).
- Review
app/src/main/java/org/hyperledger/besu/cli/BesuCommand.java around line 1151 in the isGroupMember method. The code spawns Runtime.getRuntime().exec(new String[] {"id", "-Gn", userName}); but fails to close the streams or terminate the process.
- Review
util/src/main/java/org/hyperledger/besu/util/platform/PlatformDetector.java around line 305 in detectGlibc. The processBuilder.start() process is never waited on or destroyed.
- Review
app/src/main/java/org/hyperledger/besu/chainexport/RlpBlockExporter.java around line 70. FileOutputStream outputStream = new FileOutputStream(outputFile, append); is not wrapped in a try-with-resources block, causing a leak if an exception occurs during block processing.
Expected behavior:
- Spawning OS processes via
Runtime.exec or ProcessBuilder should manage the process lifecycle using process.waitFor() and process.destroy(), and explicitly close InputStream and OutputStream.
FileOutputStream instances should always be managed inside a try-with-resources block to ensure file descriptors are correctly released if an exception occurs.
Actual behavior:
- Zombie processes and orphaned file descriptors are leaked due to unmanaged resource handling in
BesuCommand, PlatformDetector, and RlpBlockExporter.
Frequency: 100% of the time those methods execute or fail.
Logs
N/A (Identified via static analysis/code audit).
Versions (Add all that apply)
- Software version:
main branch (latest codebase)
- Java version: All supported versions (code pattern applies to all JDKs).
- OS Name & Version: N/A
- Kernel Version: N/A
- Virtual Machine software & version: N/A
- Docker Version: N/A
- Cloud VM, type, size: N/A
- Consensus Client & Version if using Proof of Stake: N/A
Smart contract information (If you're reporting an issue arising from deploying or calling a smart contract, please supply related information)
N/A
Additional Information (Add any of the following or anything else that may be relevant)
Proposed Fixes:
- In
BesuCommand.java's isGroupMember, wrap the BufferedReader in try-with-resources and wrap the process in a try-finally block to call waitFor() and destroy().
- In
PlatformDetector.java's detectGlibc, add a try-finally block to enforce process.waitFor() and process.destroy().
- In
RlpBlockExporter.java, wrap the FileOutputStream in a try-with-resources block.
Steps to Reproduce
During a technical code audit, multiple instances of unmanaged
ProcessandFileOutputStreamresources were found. These issues occur via static code paths and do not require runtime steps to reproduce, but they happen when specific logic triggers (e.g., CLI permission checks, platform OS detection, and block exporting).app/src/main/java/org/hyperledger/besu/cli/BesuCommand.javaaround line 1151 in theisGroupMembermethod. The code spawnsRuntime.getRuntime().exec(new String[] {"id", "-Gn", userName});but fails to close the streams or terminate the process.util/src/main/java/org/hyperledger/besu/util/platform/PlatformDetector.javaaround line 305 indetectGlibc. TheprocessBuilder.start()process is never waited on or destroyed.app/src/main/java/org/hyperledger/besu/chainexport/RlpBlockExporter.javaaround line 70.FileOutputStream outputStream = new FileOutputStream(outputFile, append);is not wrapped in atry-with-resourcesblock, causing a leak if an exception occurs during block processing.Expected behavior:
Runtime.execorProcessBuildershould manage the process lifecycle usingprocess.waitFor()andprocess.destroy(), and explicitly closeInputStreamandOutputStream.FileOutputStreaminstances should always be managed inside atry-with-resourcesblock to ensure file descriptors are correctly released if an exception occurs.Actual behavior:
BesuCommand,PlatformDetector, andRlpBlockExporter.Frequency: 100% of the time those methods execute or fail.
Logs
N/A (Identified via static analysis/code audit).
Versions (Add all that apply)
mainbranch (latest codebase)Smart contract information (If you're reporting an issue arising from deploying or calling a smart contract, please supply related information)
N/A
Additional Information (Add any of the following or anything else that may be relevant)
Proposed Fixes:
BesuCommand.java'sisGroupMember, wrap theBufferedReaderintry-with-resourcesand wrap theprocessin atry-finallyblock to callwaitFor()anddestroy().PlatformDetector.java'sdetectGlibc, add atry-finallyblock to enforceprocess.waitFor()andprocess.destroy().RlpBlockExporter.java, wrap theFileOutputStreamin atry-with-resourcesblock.