← Back to issue list

Update patchelf

View original Github issue

Metadata

Project
snapcraft
Number
#6509
Type
issue
State
open
Author
mr-cal
Labels
Status: Triaged Type: Enhancement
Created
Updated
Closed
—

Current evaluation

⚠️ This summary may be outdated — the issue content or evaluation prompts have changed since this evaluation was made.

Maintainer proposes updating bundled patchelf from 0.9 to 0.19.2 to fix ELF corruption bugs and improve performance; test plan and results included.

Suggested action: keep open

Reason: This is a well-scoped, actionable upgrade request opened by maintainer mr-cal with a detailed table mapping existing local patches to upstream fixes, a test plan, and test results showing 13-35% performance improvement and successful cross-architecture builds. No labels or maintainer comments yet, but the issue is clearly valid and ready for implementation.

Evaluated by: mr-cal-bot

Impact: 70 Quick Win: 34 Complexity: 40 Confidence: 80 Actionability: 80

Issue body

Snapcraft uses patchelf to update ELFs in classic snaps. Currently, Snapcraft uses a [fork](https://github.com/canonical/patchelf/tree/master) of [NixOS/patchelf](https://github.com/NixOS/patchelf) based on [0.9](https://github.com/NixOS/patchelf/releases/tag/0.9) (2022) whereas [0.19.2](https://github.com/NixOS/patchelf/releases/tag/0.19.2) (2026) is the latest release. It applies a [few commits](https://github.com/canonical/patchelf/commits/0.9%2Bsnapcraft/) on top of 0.9 and 2 patches that only apply to riscv64 ([[1](https://github.com/canonical/snapcraft/blob/004b54d8e/snap/local/patches/patchelf/0001-Always-use-the-ET_DYN-codepath-avoiding-shifting-loa.patch)], [[2](https://github.com/canonical/snapcraft/blob/004b54d8e/snap/local/patches/patchelf/0002-Fix-rewriteSectionsLibrary-to-not-assume-the-base-ad.patch)]). There are new bugs being reported in snapcraft that have been addressed upstream (see the last rows of the table), so Snapcraft should update patchelf. ## Existing patches and upstream fixes | Snapcraft patch | Snapcraft bugs | Upstream bugs | Upstream PRs | | --- | --- | --- | --- | | [canonical/patchelf#2](https://github.com/canonical/patchelf/pull/2): no-rpath-prebuild: force pagesize to 4096 on prebuilt binaries | none | none | [patchelf#81](https://github.com/NixOS/patchelf/pull/81) no-rpath-prebuild: force pagesize to 4096 on prebuilt binaries (v0.10) | | [canonical/patchelf#2](https://github.com/canonical/patchelf/pull/2): Fix issue #66 by ignoring the first section header when sorting, and not overwriting NOBITS entries. | [LP: #1736861](https://bugs.launchpad.net/snapcraft/+bug/1736861) classic snap fails to build with "cannot find section"<br><br>[LP: #1753995](https://bugs.launchpad.net/snapcraft/+bug/1753995) patchelf warning / binary segfaults<br><br>[LP: #1805205](https://bugs.launchpad.net/snapcraft/+bug/1805205) Ensure elf patching works correctly with golang created ELF files<br><br>[snapcraft#2005](https://github.com/canonical/snapcraft/pull/2005) pluginhandler: special case go patchelf failures for classic confinement<br><br>[snapcraft#2519](https://github.com/canonical/snapcraft/pull/2519) packaging: use local patchelf | [patchelf#66](https://github.com/NixOS/patchelf/issues/66) patchelf --set-interpreter fails with `cannot find section ` | [patchelf#149](https://github.com/NixOS/patchelf/pull/149) Fix issue #66: ignore 0th section header when sorting, don't overwrite NOBITS (v0.10) | | [canonical/patchelf#2](https://github.com/canonical/patchelf/pull/2): Avoid inflating file sizes needlessly and allow binaries to be stripped | [snapcraft#2519](https://github.com/canonical/snapcraft/pull/2519) packaging: use local patchelf | [patchelf#10](https://github.com/NixOS/patchelf/issues/10) Section re-ordering confuses `strip` | [patchelf#117](https://github.com/NixOS/patchelf/pull/117) Avoid inflating file sizes needlessly and allow binaries to be stripped (v0.10) | | [canonical/patchelf#2](https://github.com/canonical/patchelf/pull/2): build: set c++ compiler standard to c++11 | [canonical/patchelf#2](https://github.com/canonical/patchelf/pull/2) Local patches for patchelf 0.9 | none | [patchelf@3d28e1e](https://github.com/NixOS/patchelf/commit/3d28e1ed4d9d1d91c313e62b5bc4dd520f6df1a1) Use a std::vector for holding the file contents (v0.10)<br><br>[patchelf#383](https://github.com/NixOS/patchelf/pull/383) / [patchelf#409](https://github.com/NixOS/patchelf/pull/409) Upgrade to C++17 compiler standard (v0.16.0) | | [canonical/patchelf#2](https://github.com/canonical/patchelf/pull/2): fix adjusting startPage | [canonical/patchelf#2](https://github.com/canonical/patchelf/pull/2) Local patches for patchelf 0.9<br>[snapcraft#2519](https://github.com/canonical/snapcraft/pull/2519) packaging: use local patchelf | [patchelf#10](https://github.com/NixOS/patchelf/issues/10) Section re-ordering confuses `strip` | [patchelf#127](https://github.com/NixOS/patchelf/pull/127) fix adjusting startPage (v0.11) | | [canonical/patchelf#3](https://github.com/canonical/patchelf/pull/3): Improve the default section alignment choice | [canonical/patchelf#3](https://github.com/canonical/patchelf/pull/3) Improve the default section alignment choice | [patchelf#79](https://github.com/NixOS/patchelf/issues/79) fail aarch64 -- Need to detect page size from ELF file | [patchelf#216](https://github.com/NixOS/patchelf/pull/216) Improve the default section alignment choice (> 4K page size compat) (v0.12) | | [0001-Always-use-the-ET_DYN-codepath-avoiding-shifting-loa.patch](https://github.com/canonical/snapcraft/blob/d6a8ffe9a513719aca8dfc238ae1319307f28edc/snap/local/patches/patchelf/0001-Always-use-the-ET_DYN-codepath-avoiding-shifting-loa.patch) | [snapcraft#3588](https://github.com/canonical/snapcraft/pull/3588) snap: patch patchelf on riscv64 (CRAFT-566) | [patchelf#404](https://github.com/NixOS/patchelf/issues/404) --add-needed can decrease the address of the first page below `vm.mmap_min_addr`<br><br>[patchelf#622](https://github.com/NixOS/patchelf/issues/622) patchelf should never generate LOAD segments with p_vaddr less than the lowest such address in the original file | [patchelf#637](https://github.com/NixOS/patchelf/pull/637) rewriteSections: rewrite executables like shared objects (#622) (unmerged) | | [0002-Fix-rewriteSectionsLibrary-to-not-assume-the-base-ad.patch](https://github.com/canonical/snapcraft/blob/d6a8ffe9a513719aca8dfc238ae1319307f28edc/snap/local/patches/patchelf/0002-Fix-rewriteSectionsLibrary-to-not-assume-the-base-ad.patch) | [snapcraft#3588](https://github.com/canonical/snapcraft/pull/3588) snap: patch patchelf on riscv64 (CRAFT-566) | [patchelf#404](https://github.com/NixOS/patchelf/issues/404) --add-needed can decrease the address of the first page below `vm.mmap_min_addr`<br><br>[patchelf#622](https://github.com/NixOS/patchelf/issues/622) patchelf should never generate LOAD segments with p_vaddr less than the lowest such address in the original file | none | | none | [snapcraft#6410](https://github.com/canonical/snapcraft/issues/6410) Bundled patchelf drops PT_NOTE coverage for .note.qt.metadata, making every staged Qt 6 plugin unloadable | [patchelf#217](https://github.com/NixOS/patchelf/issues/217) PT_NOTE segment does not point to SHT_NOTE section when the latter is moved<br><br>[patchelf#403](https://github.com/NixOS/patchelf/issues/403) patchelf corrupts PT_NOTE segment | [patchelf#218](https://github.com/NixOS/patchelf/pull/218) Better support relocating NOTE sections/segments (v0.12)<br><br>[patchelf#415](https://github.com/NixOS/patchelf/pull/415) Rework file shifting to avoid sections crossing multiple segments (v0.16.0) | | none | [snapcraft#6350](https://github.com/canonical/snapcraft/pull/6350#discussion_r3596366277) tests: patchelf fails to patch black >= 26.5.0 .so shims | [patchelf#583](https://github.com/NixOS/patchelf/issues/583) segfault following assert fail at patchelf.cc:556 | [patchelf#121](https://github.com/NixOS/patchelf/pull/121) Better error messages when run on statically-linked (or otherwise weird) binaries (v0.10) | | none | none (codebase workaround in [`snapcraft/elf/_patcher.py:80`](https://github.com/canonical/snapcraft/blob/c0546099966880c515b1eb4b59443317889b90a0/snapcraft/elf/_patcher.py#L79-L81)) | [patchelf#94](https://github.com/NixOS/patchelf/issues/94) --force-rpath not working if binary already had RUNPATH | [patchelf#137](https://github.com/NixOS/patchelf/pull/137) Consistently use --force-rpath (fixes #94) (v0.10) | | none | none (codebase workaround in [`snapcraft/elf/_patcher.py:100`](https://github.com/canonical/snapcraft/blob/c0546099966880c515b1eb4b59443317889b90a0/snapcraft/elf/_patcher.py#L99-L105)) | [patchelf#223](https://github.com/NixOS/patchelf/issues/223) --no-default-lib effect is nullified if --set-rpath causes .dynamic section to be rewritten | [patchelf#361](https://github.com/NixOS/patchelf/pull/361) Allow multiple modifications in same call (v0.14.4) | ### Notable improvements Improvements in patchelf that may gain some performance improvements for Snapcraft: - Multiple operations in in a single invocation (https://github.com/NixOS/patchelf/pull/361) - `PT_GNU_PROPERTY` support for Intel CET (https://github.com/NixOS/patchelf/pull/414) - Patching files >2 GB (https://github.com/NixOS/patchelf/pull/361) ### Test plan 1. Build snapcraft itself (a classic snap) on all architectures ([launchpad recipe)](https://launchpad.net/~mr-cal/snapcraft/+snap/snapcraft-test) 2. Build 8 existing classic snaps that are popular, have public sources, and support all arches: curl, jq, tree. ffmpeg, graphicsmagick, nmap, htop. 3. Compare build-time performance. 4. Compare ELF files in the snaps that were patched with 0.9 vs 0.19. 5. Verify all apps run on all archs. ### Test results #### Performance [patchelf#361](https://github.com/NixOS/patchelf/pull/361) let's us combine 2 patchelf calls into 1. The time to run the patchelf module dropped between 13% and 35%. #### Elf file comparison The robots have assured me that relevant sections of the ELF files, including dynamic symbols, relocations, `DT_FLAGS_1: NODEFLIB`, and RPATH strings match byte-for-byte. The new [riscv64 patch](https://github.com/mr-cal-bot/patchelf/commit/328ddee0134953329d99bce9bf56f4c80386a429) (based on the prior [patch](https://github.com/canonical/snapcraft/blob/d6a8ffe9a513719aca8dfc238ae1319307f28edc/snap/local/patches/patchelf/0002-Fix-rewriteSectionsLibrary-to-not-assume-the-base-ad.patch)) for the base virtual address fix is working as intended. #### Real world tests All 8 snaps built and ran succesfully on all architectures. I leveraged launchpad to install and run the snaps inside an `override-build` They also ran on @lengau's riscv64 system.

Evaluation history

Date Model Scores Action Summary
qwen/qwen3.6-35b-a3b
Impact: 70
Quick Win: 34
Complexity: 40
Confidence: 80
Actionability: 80
keep open Maintainer proposes updating bundled patchelf from 0.9 to 0.19.2 to fix ELF corruption bugs and improve performance; test plan and results included.
minimax/minimax-m3.1-flash:free
Impact: 70
Quick Win: 23
Complexity: 65
Confidence: 92
Actionability: 92
needs triage Maintainer proposes replacing the bundled PatchELF 0.9 fork with upstream 0.19.2 to fix known ELF corruption regressions; local-patch review and cross-architecture classic-snap tests remain.

Update history

Date Change
updated
updated
updated
updated
updated
updated
updated
updated
updated
created

Related work

  • Superseded By: snapcraft#1983 (confidence 70%)

    Previous attempt to update patchelf revision that was superseded by packaging-based acquisition in #2006.

Related issues

Issue Project State Summary Similarity
#6511 build(deps): update patchelf to 0.19 snapcraft open Updates bundled patchelf from 0.9 to 0.19 to fix ELF corruption bugs with Qt 6 plugins. Blocked by external PR canonical/patchelf#4. Has 1 unresolved review comment and one failing CI check (OSV-scanner).
80%
#2531 snap: revert to patchelf 0.9 with local patches snapcraft merged Merged PR #2531 as commit 44be372e3, reverting from Patchelf 0.10 to locally patched 0.9 after architecture tests exposed unreliable binaries.
75%
#1983 snap: update revision of patchelf to use snapcraft closed Closed unmerged; the bundled PatchELF revision bump in #1983 was superseded by #2006, which adopted packaging-based acquisition (commit aa2a40322).
71%