Skip to content

🛡️ Sentinel: Harden entry parsing and splitting against integer overflows#3053

Open
ChanTsune wants to merge 1 commit into
mainfrom
sentinel-harden-arithmetic-3992568315708466104
Open

🛡️ Sentinel: Harden entry parsing and splitting against integer overflows#3053
ChanTsune wants to merge 1 commit into
mainfrom
sentinel-harden-arithmetic-3992568315708466104

Conversation

@ChanTsune
Copy link
Copy Markdown
Owner

@ChanTsune ChanTsune commented May 12, 2026

🛡️ Sentinel: [HIGH] Harden entry parsing and splitting against integer overflows

  • 🚨 Severity: HIGH
  • 💡 Vulnerability: Potential panics from integer overflows during archive entry parsing and multi-part archive splitting.
  • 🎯 Impact: Maliciously crafted archives with massive chunk counts or sizes could trigger panics, leading to Denial of Service (DoS), especially on 32-bit platforms.
  • 🔧 Fix:
    • Replaced wrapping += and .sum() with saturating_add for cumulative size calculations in libpna and the CLI.
    • Replaced unsafe additions with checked_add and safe boundary checks in EntryPart::try_split.
    • Added overflow protection for archive part numbers using checked_add(1).
  • Verification: Ran full test suite (cargo test) and linters (clippy, fmt). Verified code changes visually via read_file. Verified that logic handles boundary conditions safely without wrapping.

PR created automatically by Jules for task 3992568315708466104 started by @ChanTsune

Summary by CodeRabbit

  • Bug Fixes

    • Enhanced archive entry parsing and multi-part splitting to prevent integer overflow and underflow issues that could cause panics during file processing.
  • Documentation

    • Added guidance on arithmetic hardening practices for entry parsing and splitting operations.

Review Change Stack

- Use `saturating_add` for size and length calculations in `lib/src/entry.rs` and `cli/src/command/core.rs` to prevent panics on 32-bit platforms or malformed archives.
- Use `checked_add` for archive part number increments to safely handle extreme splitting scenarios.
- Improve chunk boundary checks during entry splitting using safe arithmetic and stable `Option` methods.
- Document security learning in `.jules/sentinel.md`.

Co-authored-by: ChanTsune <41658782+ChanTsune@users.noreply.github.com>
@google-labs-jules
Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 12, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cc84a6c3-5176-4f17-9080-42a01301a25b

📥 Commits

Reviewing files that changed from the base of the PR and between 33867da and 859f276.

📒 Files selected for processing (3)
  • .jules/sentinel.md
  • cli/src/command/core.rs
  • lib/src/entry.rs

📝 Walkthrough

Walkthrough

This PR hardens arithmetic operations across archive entry parsing, splitting, and writing against integer overflow. Sentinel documentation establishes the hardening approach, then cumulative size calculations in entry parsing, splitting logic, and split archive writing are updated from unchecked addition to saturating and checked variants.

Changes

Arithmetic Hardening in Archive Entry Parsing and Splitting

Layer / File(s) Summary
Hardening approach documentation
.jules/sentinel.md
Sentinel entry documents the overflow-hardening strategy using saturating_add for cumulative size/length calculations and checked_add for sequence/structural counters in archive entry parsing and splitting.
Entry parsing arithmetic hardening
lib/src/entry.rs
NormalEntry::try_from initializes compressed_size as usize and accumulates FDAT chunk data length using saturating_add instead of unchecked += to prevent overflow during parsing.
Entry part splitting and sizing hardening
lib/src/entry.rs
EntryPart::bytes_len uses an iterator fold with saturating_add for total computation; EntryPart::try_split uses checked_add for max-size comparisons (including MIN_CHUNK_BYTES_SIZE checks) and saturating_add for cumulative total_size increments.
Split archive writer capacity tracking hardening
cli/src/command/core.rs
write_split_archive_writer tracks written_entry_size and part_num using saturating_sub and saturating_add for remaining capacity computation, and checked_add for part counter increment with explicit InvalidData error on overflow.

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

Suggested labels

lib, cli

Poem

🐰 Counting up with care so keen,
No overflow panics in between,
Saturating sums and checks so tight,
Archive parsing done just right!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title directly addresses the main objective: hardening entry parsing and splitting against integer overflows, which is the primary focus of all changes across three files.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sentinel-harden-arithmetic-3992568315708466104

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added cli This issue is about cli application lib This issue is about lib crate labels May 12, 2026
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request implements arithmetic hardening to prevent integer overflows during archive entry parsing and splitting by replacing standard arithmetic with saturating and checked operations. These changes affect the CLI core and library entry logic, and a sentinel record has been added to document the vulnerability prevention. Feedback indicates that the is_none_or method should be replaced with map_or to maintain compatibility with Rust versions prior to 1.82.0.

Comment thread lib/src/entry.rs
Comment on lines +1164 to +1166
if total_size
.checked_add(chunk.bytes_len())
.is_none_or(|sum| max_bytes_len < sum)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The is_none_or method was stabilized in Rust 1.82.0. To maintain compatibility with older Rust versions (MSRV), consider using map_or(true, ...) which provides the same logic and is compatible with versions prior to 1.82.0.

Suggested change
if total_size
.checked_add(chunk.bytes_len())
.is_none_or(|sum| max_bytes_len < sum)
if total_size
.checked_add(chunk.bytes_len())
.map_or(true, |sum| max_bytes_len < sum)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli This issue is about cli application lib This issue is about lib crate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant