Skip to content

fix: route renamed binary formats and classify ExecuTorch read failures#1271

Merged
mldangelo-oai merged 12 commits into
mainfrom
mdangelo/codex/fix-renamed-binary-content-routes
May 26, 2026
Merged

fix: route renamed binary formats and classify ExecuTorch read failures#1271
mldangelo-oai merged 12 commits into
mainfrom
mdangelo/codex/fix-renamed-binary-content-routes

Conversation

@mldangelo-oai
Copy link
Copy Markdown
Contributor

@mldangelo-oai mldangelo-oai commented May 24, 2026

Summary

  • Route signature-valid renamed RKNN, TFLite, and standalone ExecuTorch files to their dedicated scanners.
  • Classify unavailable ExecuTorch header, structure-validation, and archive reads as incomplete analysis with exit code 2 rather than security findings.
  • Document renamed-artifact support and add positive, near-match negative, and direct/aggregate read-outcome regressions.

Stack and Scope

This is stacked on #1269, which owns CNTK and LightGBM renamed routing. R serialized renamed routing has been split into focused PR #1322, stacked on #1312 so its incomplete-analysis semantics and false-positive boundary can be reviewed together.

Context

End-to-end probes showed these three binary formats were already retained by content prefiltering under misleading suffixes such as .jpg, but full dispatch returned unknown, so their dedicated scanner coverage was never applied.

A valid ExecuTorch binary also reported CRITICAL with exit code 1 when its initial header or subsequent bounded structural read was unavailable: the scanner collapsed read failures into Not a valid ExecuTorch archive. The updated scanner propagates I/O failures only during active analysis and reports executorch_read_failed as inconclusive; routing probes remain conservative, and actual malformed signatures, path traversal, Python members, and malicious embedded pickle findings are unchanged.

Validation

  • env -u UV_EXCLUDE_NEWER -u VIRTUAL_ENV uv --no-config run --locked ruff format modelaudit/ packages/modelaudit-picklescan/src packages/modelaudit-picklescan/tests tests/
  • env -u UV_EXCLUDE_NEWER -u VIRTUAL_ENV uv --no-config run --locked ruff check --fix modelaudit/ packages/modelaudit-picklescan/src packages/modelaudit-picklescan/tests tests/
  • env -u UV_EXCLUDE_NEWER -u VIRTUAL_ENV uv --no-config run --locked mypy modelaudit/ packages/modelaudit-picklescan/src packages/modelaudit-picklescan/tests tests/ (Success: no issues found in 451 source files)
  • env -u UV_EXCLUDE_NEWER -u VIRTUAL_ENV PROMPTFOO_DISABLE_TELEMETRY=1 uv --no-config run --locked pytest tests/scanners/test_rknn_scanner.py tests/scanners/test_tflite_scanner.py tests/scanners/test_executorch_scanner.py tests/scanners/test_r_serialized_scanner.py tests/utils/file/test_filetype.py tests/utils/file/test_file_filter.py --maxfail=1 -q (193 passed)
  • env -u UV_EXCLUDE_NEWER -u VIRTUAL_ENV PROMPTFOO_DISABLE_TELEMETRY=1 uv --no-config run --locked pytest -n auto -m "not slow and not integration" --maxfail=1 (4767 passed, 971 skipped)
  • npx prettier --check CHANGELOG.md README.md docs/user/compatibility-matrix.md
  • git diff --check

Recognize strict content signatures during prefiltering and dispatch so misleading suffixes cannot hide supported payloads. Preserve the CNTK .model exclusion for XGBoost overlap and add positive and negative routing regressions.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 24, 2026

Workflow run and artifacts

Performance Benchmarks

Compared 12 shared benchmarks with a regression threshold of 15%.
Status: 1 regressions, 0 improved, 11 stable, 0 new, 0 missing.
Aggregate shared-benchmark median: 531.16ms -> 670.23ms (+26.2%).

Top regressions:

  • tests/benchmarks/test_scan_benchmarks.py::test_scan_warm_cached_repository_rescan +288.1% (46.15ms -> 179.10ms, warm-cache-rescan, release-candidate, size=547.3 KiB, files=32)
Workload Benchmark Target Size Files Baseline Current Change Status
warm-cache-rescan tests/benchmarks/test_scan_benchmarks.py::test_scan_warm_cached_repository_rescan release-candidate 547.3 KiB 32 46.15ms 179.10ms +288.1% regression
suspicious-pickle-intake tests/benchmarks/test_scan_benchmarks.py::test_scan_suspicious_pickle_intake suspicious-intake 183.8 KiB 4 72.71ms 76.86ms +5.7% stable
clean-training-checkpoint tests/benchmarks/test_picklescan_benchmarks.py::test_picklescan_clean_training_checkpoint safe_large 278.2 KiB 1 10.47ms 9.94ms -5.1% stable
direct-malicious-upload tests/benchmarks/test_picklescan_benchmarks.py::test_picklescan_direct_malicious_upload malicious_reduce 52 B 1 1.11ms 1.16ms +4.3% stable
chunked-upload-stream tests/benchmarks/test_picklescan_benchmarks.py::test_picklescan_chunked_upload_stream chunked_stream 278.2 KiB 1 13.19ms 12.64ms -4.2% stable
single-checkpoint-preflight tests/benchmarks/test_scan_benchmarks.py::test_scan_single_checkpoint_before_load single_checkpoint.pkl 183.0 KiB 1 28.75ms 28.25ms -1.7% stable
nested-payload-review tests/benchmarks/test_picklescan_benchmarks.py::test_picklescan_nested_payload_review[nested_raw] nested_raw 78 B 1 313.0us 318.0us +1.6% stable
nested-payload-review tests/benchmarks/test_picklescan_benchmarks.py::test_picklescan_nested_payload_review[nested_hex] nested_hex 130 B 1 319.9us 324.6us +1.5% stable
mixed-model-repository tests/benchmarks/test_scan_benchmarks.py::test_scan_release_candidate_repository release-candidate 547.3 KiB 32 206.09ms 208.41ms +1.1% stable
padded-multi-stream-upload tests/benchmarks/test_picklescan_benchmarks.py::test_picklescan_padded_multi_stream_upload multi_stream_padded 4.1 KiB 1 1.17ms 1.18ms +0.8% stable
duplicate-heavy-registry tests/benchmarks/test_scan_benchmarks.py::test_scan_duplicate_registry_snapshot registry-snapshot 915.2 KiB 13 150.58ms 151.72ms +0.8% stable
nested-payload-review tests/benchmarks/test_picklescan_benchmarks.py::test_picklescan_nested_payload_review[nested_base64] nested_base64 98 B 1 318.5us 319.9us +0.4% stable

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b264c0d3af

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread modelaudit/utils/file/detection.py Outdated
Comment thread modelaudit/utils/file/detection.py Outdated
@mldangelo-oai mldangelo-oai changed the title fix: route renamed signature-backed binary formats fix: route renamed binary formats and classify ExecuTorch read failures May 24, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 399d02a710

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread modelaudit/utils/file/detection.py Outdated
Comment thread modelaudit/utils/file/detection.py Outdated
Comment thread modelaudit/utils/file/detection.py Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: faf7e05402

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread modelaudit/utils/file/detection.py Outdated
Comment thread modelaudit/utils/file/detection.py Outdated
Comment thread modelaudit/utils/file/detection.py Outdated
Comment thread modelaudit/utils/file/detection.py Outdated
Comment thread modelaudit/utils/file/detection.py Outdated
Comment thread modelaudit/utils/file/detection.py Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fb2f60210f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread modelaudit/utils/file/detection.py Outdated
Comment thread modelaudit/utils/file/detection.py Outdated
Comment thread modelaudit/utils/file/detection.py Outdated
…lightgbm-routing' into mdangelo/codex/fix-renamed-binary-content-routes
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fb3a658661

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread modelaudit/utils/file/detection.py Outdated
Comment thread modelaudit/utils/file/detection.py Outdated
Comment thread modelaudit/utils/file/detection.py Outdated
Comment thread modelaudit/utils/file/detection.py Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves content-based routing so signature-valid RKNN, TFLite, and standalone ExecuTorch binaries renamed with misleading suffixes (e.g. .jpg) are dispatched to their dedicated scanners, and refines ExecuTorch scan semantics so I/O read failures are reported as inconclusive (exit code 2) instead of security findings.

Changes:

  • Add/adjust file-format detection to route renamed RKNN/Torch7/TFLite/ExecuTorch content while preventing TFLite’s TFL3 identifier from overriding stronger format signals or “owned” extensions.
  • Update ExecuTorchScanner to propagate/handle read failures as executorch_read_failed inconclusive outcomes (INFO check + exit code 2) during active analysis.
  • Expand regression tests and update docs/changelog to reflect renamed-artifact support and ExecuTorch read-failure behavior.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.

Show a summary per file
File Description
modelaudit/utils/file/detection.py Extends content detection/routing for renamed binaries; adds TFLite override-blocking list; adds ExecuTorch I/O-propagation option.
modelaudit/scanners/executorch_scanner.py Treats header/structure/archive read failures as inconclusive with explicit outcome reason and INFO check.
modelaudit/scanners/rknn_scanner.py Allows RKNN handling by signature regardless of extension to support renamed artifacts.
tests/scanners/test_tflite_scanner.py Adds directory-scan routing + negative/precedence regressions for TFLite renamed payloads and stronger-route precedence.
tests/scanners/test_rknn_scanner.py Adds renamed RKNN routing test and near-match negative regression.
tests/scanners/test_executorch_scanner.py Adds regressions for inconclusive read failures and renamed standalone ExecuTorch routing behavior.
README.md Documents renamed-artifact support for RKNN/TFLite/ExecuTorch in the supported formats table.
docs/user/compatibility-matrix.md Updates compatibility matrix to include renamed-artifact support notes and ExecuTorch row.
CHANGELOG.md Records the routing fixes and ExecuTorch inconclusive read-failure classification under Unreleased.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Base automatically changed from mdangelo/codex/fix-renamed-cntk-lightgbm-routing to main May 25, 2026 20:04
@mldangelo-oai
Copy link
Copy Markdown
Contributor Author

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e645f054bf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread modelaudit/scanners/executorch_scanner.py Outdated
Comment thread modelaudit/scanners/tflite_scanner.py Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f2300d01b2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +853 to +854
if _looks_like_tflite_header(magic8):
return "tflite"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Validate TFLite .bin supplements before failing

For .bin files this helper feeds the supplemental scanner merge after the raw PyTorch binary scan, but _looks_like_tflite_header() only checks that bytes 4-7 equal TFL3. Since .bin weights are arbitrary binary, a benign raw tensor with those four bytes now runs TFLiteScanner; in the common base install without the optional tflite dependency (or when the bytes are not a real FlatBuffer), that supplemental result is merged as an inconclusive/unsuccessful scan even though the primary .bin scan was clean. Require real FlatBuffer structure validation before returning tflite, or avoid letting this weak supplemental match fail the primary .bin result.

Useful? React with 👍 / 👎.

Comment on lines +2119 to +2124
if (
_allows_renamed_binary_content_route(file_path)
and _is_executorch_binary_signature(magic8)
and _is_valid_executorch_binary(file_path)
):
return "executorch"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve Paddle routing before ExecuTorch promotion

For Paddle-owned .pdmodel/.pdiparams files, this content route can now select ExecuTorchScanner before the Paddle extension route if the first bytes look like a minimal valid ETxx FlatBuffer. ExecuTorchScanner returns success for standalone binary programs without running Paddle's embedded-code/string-pattern checks, so a Paddle file with suspicious content after such a prefix is no longer analyzed by PaddleScanner; add Paddle suffixes to the renamed-binary blocklist or keep Paddle extension routing ahead of this promotion.

Useful? React with 👍 / 👎.

Comment on lines +2127 to +2128
if ext not in _TFLITE_CONTENT_ROUTE_BLOCKED_EXTENSIONS and _looks_like_tflite_header(magic8):
return "tflite"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve config and Paddle suffix routes before TFLite

This TFLite route is now global for any suffix not in the blocklist, but the blocklist omits scanner-owned config/Paddle extensions such as .json, .yaml, .toml, .pdmodel, and .pdiparams. A valid JSON/YAML manifest or Paddle model can have bytes 4-7 equal TFL3, causing core.scan_file() to dispatch to TFLiteScanner instead of ManifestScanner/PaddleScanner; manifest URL/template checks and Paddle code-pattern checks are then skipped (or replaced by an optional-dependency/parse inconclusive result). Block these owned suffixes or move the TFLite identifier check behind their routes.

Useful? React with 👍 / 👎.

Comment on lines +2125 to +2126
if _allows_renamed_binary_content_route(file_path) and magic4 == b"RKNN":
return "rknn"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve config and Paddle routes before RKNN

This raw RKNN prefix promotion also runs before extension-based routing, but only .bin, .meta, and .pb are blocked. A Paddle .pdmodel/.pdiparams binary or a manifest/config file such as a valid YAML file beginning with an RKNN key will be dispatched to RknnScanner instead of PaddleScanner or ManifestScanner, so their embedded-code, URL, template, and policy checks are skipped. Add the scanner-owned config/Paddle suffixes to the RKNN renamed-route blocklist or move this check after those extension routes.

Useful? React with 👍 / 👎.

@mldangelo-oai mldangelo-oai merged commit c86dd85 into main May 26, 2026
29 checks passed
@mldangelo-oai mldangelo-oai deleted the mdangelo/codex/fix-renamed-binary-content-routes branch May 26, 2026 22:25
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.

2 participants