Skip to content

Fix ELF native binary extraction and repack for .bun section format#633

Closed
VitalyOstanin wants to merge 3 commits intoPiebald-AI:mainfrom
VitalyOstanin:fix/elf-bun-section
Closed

Fix ELF native binary extraction and repack for .bun section format#633
VitalyOstanin wants to merge 3 commits intoPiebald-AI:mainfrom
VitalyOstanin:fix/elf-bun-section

Conversation

@VitalyOstanin
Copy link
Copy Markdown

@VitalyOstanin VitalyOstanin commented Mar 26, 2026

Summary

Newer Bun versions (used in Claude Code 2.1.84+ on Linux) store embedded data in an ELF .bun section instead of the overlay. LIEF reports hasOverlay: false for these binaries, causing extractClaudeJsFromNativeInstallation to fail with "Failed to extract claude.js from native installation".

Changes

  • Add fallback in getBunData(): when ELF has no overlay, check for .bun section and extract using the existing extractBunDataFromSection() (same code path as PE)
  • Update repackELF() to write back to .bun section when sectionHeaderSize is present (indicating data came from a section, not overlay)
  • Pass sectionHeaderSize through to repackELF() in repackNativeInstallation()

Testing

  • Manual testing on Linux with Claude Code 2.1.84 native binary (.bun section, 129MB)
  • All existing tests pass
  • Verified patched content lands in .bun section (not overlay) and is read by Bun at runtime

Related Issues

Relates to #589 (alternative approach — this fix works within LIEF instead of bypassing it)

Summary by CodeRabbit

  • New Features

    • Added an alternative repack method for native binaries that uses provided section header info to embed app data and verifies output integrity after writing.
  • Bug Fixes

    • Improved native binary handling with a safer fallback when usual overlay data is absent.
    • Added clearer error messages when required embedded data is missing.

Newer Bun versions store embedded data in an ELF .bun section instead
of the overlay. This adds fallback extraction from .bun section when
hasOverlay is false, and writes back to .bun section during repack.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 26, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: be6e411f-7e64-4a43-a76a-ce8716d11615

📥 Commits

Reviewing files that changed from the base of the PR and between 9b58a94 and 0341ab9.

📒 Files selected for processing (1)
  • src/nativeInstallation.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/nativeInstallation.ts

📝 Walkthrough

Walkthrough

Adds .bun section support to ELF handling: getBunData falls back to extracting from a .bun section when no overlay exists; repackELF gains an optional sectionHeaderSize to enable section-based repacking and verification; repackNativeInstallation forwards sectionHeaderSize for ELF repacks.

Changes

Cohort / File(s) Summary
ELF extraction & repacking
src/nativeInstallation.ts
getBunData now checks for a .bun section when no overlay exists and extracts via extractBunDataFromSection(...). repackELF signature adds optional sectionHeaderSize?: number and implements a section-based repack path that wraps newBunBuffer with buildSectionData(...), updates section metadata, writes a temp file, re-parses to verify the .bun section length, and then restores permissions/renames. When sectionHeaderSize is absent, the prior overlay-based repack (setting elfBinary.overlay) is preserved. repackNativeInstallation passes sectionHeaderSize into repackELF for ELF binaries.

Sequence Diagram(s)

sequenceDiagram
    rect rgba(200,200,255,0.5)
    participant CLI as CLI/Invoker
    end
    rect rgba(200,255,200,0.5)
    participant Parser as ELF Parser
    participant Repacker as repackELF
    participant FS as FileSystem
    end

    CLI->>Parser: parse ELF (getBunData)
    alt overlay present
        Parser-->>CLI: return bunData (overlay)
    else .bun section present
        Parser-->>CLI: return bunData and sectionHeaderSize
    else none
        Parser-->>CLI: throw "ELF binary has no overlay data and no .bun section"
    end

    CLI->>Repacker: repackELF(elfBinary, binPath, newBunBuffer, outputPath, sectionHeaderSize?)
    alt sectionHeaderSize provided
        Repacker->>Repacker: buildSectionData(newBunBuffer, sectionHeaderSize)
        Repacker->>FS: write temp output file
        Repacker->>Parser: reparse output and verify .bun section size
        Repacker->>FS: restore permissions & rename temp -> outputPath
    else no sectionHeaderSize
        Repacker->>Repacker: construct overlay (bunData + size)
        Repacker->>FS: atomicWriteBinary(outputPath)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • bl-ue
  • vianch

Poem

🐰 Hop-hop, I patch the ELF tonight,

Found a neat .bun tucked out of sight,
Wrapped with headers, checked each byte true,
Temp file danced — then renamed anew,
Bunny hums: build complete, whoo-hoo! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and specifically describes the main change: fixing ELF native binary extraction and repacking to handle the .bun section format used by newer Bun versions.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/nativeInstallation.ts`:
- Around line 1164-1182: The repackELF flow (in repackELF where buildSectionData
produces newSectionData and bunSection is modified before
atomicWriteBinary(elfBinary, outputPath, binPath)) can corrupt the ELF if new
data exceeds the original section size; add explicit size checks and safe
expansion: before assigning bunSection.content, compare newSectionData.length to
Number(bunSection.size) and log/debug a clear warning if larger; attempt to call
a node-lief ELF section expansion API if available (documented on the node-lief
binding) to grow the section (similar idea to MachO.extendSegment()); if no
expansion API exists, wrap the write/atomicWriteBinary calls in try/catch and
validate sizes before and after elfBinary.write()/atomicWriteBinary to ensure
the section grew (throw/rollback on mismatch), and apply the same pattern to the
PE repack code that sets virtualSize/size (e.g., repackPE) so both formats
validate and handle expansion safely.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 55c30304-757f-418c-89fc-5bea66e67e30

📥 Commits

Reviewing files that changed from the base of the PR and between 86ae3f3 and 40ef472.

📒 Files selected for processing (1)
  • src/nativeInstallation.ts

PR review raised concern about ELF binary corruption when new .bun
section data exceeds original size (no explicit expansion API like
MachO's extendSegment).

Investigation:
- node-lief has no ELF section expansion API (checked programmatically)
- LIEF handles section relocation automatically during write() —
  verified by expanding .bun section by 1KB, writing, re-parsing,
  and confirming the content length matches

Changes:
- Log debug warning when new data exceeds original section size
- Re-parse written binary and verify .bun section size matches
  expected length; throw on mismatch to prevent silent corruption
- PE repack not changed (out of scope per maintainer)
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/nativeInstallation.ts`:
- Around line 1187-1200: The code writes the patched ELF into place via
atomicWriteBinary(elfBinary, outputPath, binPath) before verifying, so a failed
verification can leave a broken outputPath; instead, write the modified binary
to the temporary path (binPath) first, parse/verify that temp file with
LIEF.parse(binPath) and confirm the .bun section size matches newSectionData,
and only after successful verification perform the atomic rename/move to
outputPath (or call the existing atomic rename step). Update repackELF so
verification uses verifyBinary = LIEF.parse(binPath) and verifySection before
performing the final rename; keep references to atomicWriteBinary, outputPath,
binPath, repackELF, verifySection, and newSectionData to locate the change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f18aff40-4088-48fd-8f4d-347b21ac9eec

📥 Commits

Reviewing files that changed from the base of the PR and between 40ef472 and 9b58a94.

📒 Files selected for processing (1)
  • src/nativeInstallation.ts

PR review: verification ran after atomicWriteBinary had already
renamed the file into place, leaving a bad binary on disk if
validation failed. Now: write to temp, verify .bun section in temp,
only then chmod+rename to final path. Temp file is cleaned up on
verification failure.
@signadou
Copy link
Copy Markdown
Member

Closing in favor of #644.  Thank you anyway @VitalyOstanin!

@signadou signadou closed this Mar 29, 2026
@VitalyOstanin VitalyOstanin deleted the fix/elf-bun-section branch March 29, 2026 18:13
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