Skip to content

Model package: security, correctness, and session creation simplification#28602

Merged
jambayk merged 3 commits into
chi/model_package_2from
jambayk/mp
May 20, 2026
Merged

Model package: security, correctness, and session creation simplification#28602
jambayk merged 3 commits into
chi/model_package_2from
jambayk/mp

Conversation

@jambayk
Copy link
Copy Markdown
Contributor

@jambayk jambayk commented May 20, 2026

Summary

This PR addresses security vulnerabilities, correctness bugs, and simplifies the session creation flow for the model package feature.

Security & correctness fixes

  • Path traversal validation: Added ValidatePathSegment and ValidatePathConfinement to prevent directory traversal attacks via malicious package descriptors. Uses lexically_normal() (not weakly_canonical()) to support symlinked packages.
  • Use-after-free fix: ModelPackageComponentContext now owns all state (EP infos, provider list, devices) copied from ModelPackageOptions, eliminating lifetime coupling.
  • Provider options propagation: Variant provider options are now properly merged into session options and reach EP creation.
  • String lifetime: Fixed dangling pointer risk in C-string array construction.
  • Variant ordering: Variants are now evaluated in descriptor order for deterministic selection.
  • Device validation: Added bounds checking for device index in EP info resolution.
  • CPU fallback: Added fallback loop in variant selector to try CPU variant when the requested EP has no match.

Session creation simplification

  • Removed stored OrtSessionOptions from both ModelPackageOptions and ModelPackageComponentContext. The session options passed to create package options are now only used to extract EP intent (factories, devices, policy) for variant selection.
  • Clean-slate session creation: CreateSession default path starts from a fresh OrtSessionOptions populated only with the selected variant's session options and provider options.
  • Simplified GetVariantSelectionEpInfo: Uses the first EP in the provider list directly instead of skipping CPU. Empty provider list defaults to implicit CPU.
  • Unified RebuildProviderListForSession: Both explicit-factory and policy paths now use CreateIExecutionProviderFactoryForEpDevices with captured ep_devices, eliminating the two-path rebuild logic.
  • Removed HasOptions()/SessionOptions() from the component context API.

Files changed

  • model_package_descriptor_parser.cc: Path validation functions
  • model_package_context.h/.cc: Owned state, simplified rebuild
  • model_package_options.h/.cc: Removed stored session options, simplified EP resolution
  • model_package_api.cc: Clean-slate session creation
  • model_package_variant_selector.cc: CPU fallback loop
  • utils.cc: Simplified EP info extraction

Testing

  • Verified with CPU-only and CUDA model packages (single and multi-variant)
  • E2E notebook tests pass for both ORT and GenAI integration

jambayk and others added 3 commits May 20, 2026 19:04
- Path traversal: validate path segments and confinement using lexical
  normalization (allows symlinks, blocks '..' traversal)
- UAF fix: ModelPackageComponentContext owns copies of all state instead
  of holding a raw pointer to ModelPackageOptions
- Provider options: pass effective (merged) session options to
  RebuildProviderListForSession so variant provider options reach EP
  creation
- String lifetime: use context-owned caches for C string arrays
- Variant order: preserve JSON key order during parsing
- Device validation: reject malformed device fields, fix constraint
  matching logic
- CPU fallback: try remaining EPs when primary variant does not match

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove stored OrtSessionOptions from ModelPackageOptions and
  ModelPackageComponentContext. Session creation now starts from a clean
  OrtSessionOptions populated only with variant metadata (session options
  and provider options).
- Simplify GetVariantSelectionEpInfo to use the first EP in the list
  directly instead of skipping CPU. Remove synthetic CPU hack.
- Unify RebuildProviderListForSession to use captured ep_devices from the
  selected VariantSelectionEpInfo, working for both explicit-factory and
  policy paths.
- Remove HasOptions()/SessionOptions() from component context.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When session options have no explicit providers and no policy, default
ep_infos to CPUExecutionProvider so variant selection works for the
empty-session-options path.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jambayk jambayk merged commit a4a5e2b into chi/model_package_2 May 20, 2026
4 of 5 checks passed
@jambayk jambayk deleted the jambayk/mp branch May 20, 2026 21:00
jambayk added a commit that referenced this pull request May 20, 2026
…tion (#28602)

## Summary

This PR addresses security vulnerabilities, correctness bugs, and
simplifies the session creation flow for the model package feature.

### Security & correctness fixes
- **Path traversal validation**: Added `ValidatePathSegment` and
`ValidatePathConfinement` to prevent directory traversal attacks via
malicious package descriptors. Uses `lexically_normal()` (not
`weakly_canonical()`) to support symlinked packages.
- **Use-after-free fix**: `ModelPackageComponentContext` now owns all
state (EP infos, provider list, devices) copied from
`ModelPackageOptions`, eliminating lifetime coupling.
- **Provider options propagation**: Variant provider options are now
properly merged into session options and reach EP creation.
- **String lifetime**: Fixed dangling pointer risk in C-string array
construction.
- **Variant ordering**: Variants are now evaluated in descriptor order
for deterministic selection.
- **Device validation**: Added bounds checking for device index in EP
info resolution.
- **CPU fallback**: Added fallback loop in variant selector to try CPU
variant when the requested EP has no match.

### Session creation simplification
- **Removed stored `OrtSessionOptions`** from both `ModelPackageOptions`
and `ModelPackageComponentContext`. The session options passed to create
package options are now only used to extract EP intent (factories,
devices, policy) for variant selection.
- **Clean-slate session creation**: `CreateSession` default path starts
from a fresh `OrtSessionOptions` populated only with the selected
variant's session options and provider options.
- **Simplified `GetVariantSelectionEpInfo`**: Uses the first EP in the
provider list directly instead of skipping CPU. Empty provider list
defaults to implicit CPU.
- **Unified `RebuildProviderListForSession`**: Both explicit-factory and
policy paths now use `CreateIExecutionProviderFactoryForEpDevices` with
captured `ep_devices`, eliminating the two-path rebuild logic.
- **Removed `HasOptions()`/`SessionOptions()`** from the component
context API.

### Files changed
- `model_package_descriptor_parser.cc`: Path validation functions
- `model_package_context.h/.cc`: Owned state, simplified rebuild
- `model_package_options.h/.cc`: Removed stored session options,
simplified EP resolution
- `model_package_api.cc`: Clean-slate session creation
- `model_package_variant_selector.cc`: CPU fallback loop
- `utils.cc`: Simplified EP info extraction

### Testing
- Verified with CPU-only and CUDA model packages (single and
multi-variant)
- E2E notebook tests pass for both ORT and GenAI integration

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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