VYPR
High severityNVD Advisory· Published Jun 27, 2024· Updated Oct 15, 2025

Denial of Service via Invalid Argument in h2oai/h2o-3

CVE-2024-5979

Description

In h2oai/h2o-3 version 3.46.0, the run_tool command in the rapids component allows the main function of any class under the water.tools namespace to be called. One such class, MojoConvertTool, crashes the server when invoked with an invalid argument, causing a denial of service.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

CVE-2024-5979 allows denial of service via the MojoConvertTool class in H2O-3 3.46.0, crashing the server with an invalid argument.

Vulnerability

Description CVE-2024-5979 affects H2O-3 version 3.46.0, specifically the run_tool command in the rapids component. This command permits calling the main function of any class under the water.tools namespace. One such class, MojoConvertTool, when invoked with an invalid argument, crashes the server, causing a denial of service [2]. The root cause is that the tool's main method could call System.exit or otherwise terminate the JVM without proper error handling [3].

Exploitation

An attacker must be able to execute the run_tool command, which is accessible within the H2O-3 environment. No authentication is required beyond access to the Rapids API or command line interface. By crafting a request with an invalid argument (e.g., a malformed file path), the attacker triggers the crash, leading to a denial of service. The vulnerability requires no special privileges and can be exploited remotely if the H2O-3 service is exposed [1][2].

Impact

Successful exploitation results in a denial of service, as the server process terminates. This disrupts any ongoing machine learning operations, model serving, or data processing tasks, potentially impacting availability for all users of the affected H2O-3 instance.

Mitigation

The issue is fixed in commit d0899f8e0f7a584b60405a65b1d7b439aaaa55a5, which removes System.exit calls from water.tools classes and adds internal error handling [3]. Users are strongly advised to update H2O-3 to a version containing this patch. No workarounds have been provided by the vendor other than applying the update. The vulnerability has not been listed in CISA's Known Exploited Vulnerabilities (KEV) catalog as of the publication date [2].

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
h2oPyPI
<= 3.46.0

Affected products

2
  • ghsa-coords
    Range: <= 3.46.0
  • h2oai/h2oai/h2o-3v5
    Range: unspecified

Patches

1
d0899f8e0f7a

[GH-16351] Do not call System.exit from water.tools [nocheck] (#16366)

https://github.com/h2oai/h2o-3krasinskiOct 23, 2024via ghsa
4 files changed · +33 19
  • h2o-algos/src/main/java/water/tools/MojoConvertTool.java+14 11 modified
    @@ -33,25 +33,28 @@ void convert() throws IOException {
             Files.write(pojoPath, pojo.getBytes(StandardCharsets.UTF_8));
         }
     
    -    private static void usage() {
    -        System.err.println("java -cp h2o.jar " + MojoConvertTool.class.getName() + " source_mojo.zip target_pojo.java");
    -    }
    -
         public static void main(String[] args) throws IOException {
    -        if (args.length < 2) {
    -            usage();
    +        try {
    +            mainInternal(args);
    +        }
    +        catch (IllegalArgumentException e) {
    +            System.err.println(e.getMessage());
                 System.exit(1);
             }
    +    }
    +
    +    public static void mainInternal(String[] args) throws IOException {
    +        if (args.length < 2 || args[0] == null || args[1] == null) {
    +            throw new IllegalArgumentException("java -cp h2o.jar " + MojoConvertTool.class.getName() + " source_mojo.zip target_pojo.java");
    +        }
     
             File mojoFile = new File(args[0]);
    -        if (!mojoFile.isFile()) {
    -            System.err.println("Specified MOJO file (" + mojoFile.getAbsolutePath() + ") doesn't exist!");
    -            System.exit(2);
    +        if (!mojoFile.exists() || !mojoFile.isFile()) {
    +            throw new IllegalArgumentException("Specified MOJO file (" + mojoFile.getAbsolutePath() + ") doesn't exist!");
             }
             File pojoFile = new File(args[1]);
             if (pojoFile.isDirectory() || (pojoFile.getParentFile() != null && !pojoFile.getParentFile().isDirectory())) {
    -            System.err.println("Invalid target POJO file (" + pojoFile.getAbsolutePath() + ")! Please specify a file in an existing directory.");
    -            System.exit(3);
    +            throw new IllegalArgumentException("Invalid target POJO file (" + pojoFile.getAbsolutePath() + ")! Please specify a file in an existing directory.");
             }
     
             System.out.println();
    
  • h2o-core/src/main/java/water/rapids/ast/prims/internal/AstRunTool.java+4 2 modified
    @@ -33,10 +33,12 @@ public ValStr apply(Env env, Env.StackHelp stk, AstRoot[] asts) {
             try {
                 // only allow to run approved tools (from our package), not just anything on classpath
                 Class<?> clazz = Class.forName(TOOLS_PACKAGE + toolClassName);
    -            Method mainMethod = clazz.getDeclaredMethod("main", String[].class);
    +            Method mainMethod = clazz.getDeclaredMethod("mainInternal", String[].class);
                 mainMethod.invoke(null, new Object[]{args});
             } catch (Exception e) {
    -            throw new RuntimeException(e);
    +            RuntimeException shorterException = new RuntimeException(e.getCause().getMessage());
    +            shorterException.setStackTrace(new StackTraceElement[0]);
    +            throw shorterException;
             }
             return new ValStr("OK");
         }
    
  • h2o-core/src/main/java/water/tools/EncryptionTool.java+3 0 modified
    @@ -47,6 +47,9 @@ public void encrypt(File input, File output) throws IOException, GeneralSecurity
         }
     
         public static void main(String[] args) throws GeneralSecurityException, IOException {
    +        mainInternal(args);
    +    }
    +    public static void mainInternal(String[] args) throws GeneralSecurityException, IOException {
             EncryptionTool et = new EncryptionTool();
             et._keystore_file = new File(args[0]);
             et._keystore_type = args[1];
    
  • h2o-extensions/xgboost/src/main/java/water/tools/XGBoostLibExtractTool.java+12 6 modified
    @@ -10,19 +10,25 @@
     public class XGBoostLibExtractTool {
     
         public static void main(String[] args) throws IOException {
    +        try {
    +            mainInternal(args);
    +        } catch (IllegalArgumentException e) {
    +            System.err.println((e.getMessage()));
    +            System.exit(1);
    +        }
    +    }
    +
    +    public static void mainInternal(String[] args) throws IOException {
             if (args.length != 1) {
    -            System.err.println("XGBoostLibExtractTool: Specify target directory where to extract XGBoost native libraries.");
    -            System.exit(-1);
    +            throw new IllegalArgumentException("XGBoostLibExtractTool: Specify target directory where to extract XGBoost native libraries.");
             }
             File dir = new File(args[0]);
             if (!dir.exists()) {
    -            System.err.println("XGBoostLibExtractTool: Directory '" + dir.getAbsolutePath() + "' doesn't exist.");
    -            System.exit(-1);
    +            throw new IllegalArgumentException("XGBoostLibExtractTool: Directory '" + dir.getAbsolutePath() + "' doesn't exist.");
             }
             NativeLibraryLoaderChain loader = XGBoostExtension.getLoader();
             if (loader == null) {
    -            System.err.println("XGBoostLibExtractTool: Failed to locate native libraries.");
    -            System.exit(-1);
    +            throw new IllegalArgumentException("XGBoostLibExtractTool: Failed to locate native libraries.");
             }
             for (NativeLibrary lib : loader.getNativeLibs()) {
                 if (!lib.isBundled())
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.