[GH-ISSUE #3096] Ghidra MIPS: parse and reconcile GNU ABI attributes instead of refusing every GCC-built MIPS ELF #1080

Closed
opened 2026-10-15 18:30:53 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @AurelioB on GitHub (Oct 14, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/3096

Problem

d4bd65c53 (fix(providers)!) makes readMipsElfMetadata refuse any MIPS ELF whose section table contains an SHT_GNU_ATTRIBUTES section:

MIPS ELF declares GNU ABI attributes that REA does not inspect; refusing provider selection until the declared ABI is parsed and reconciled

GCC and GNU ld emit .gnu.attributes in essentially every MIPS object they produce, so this refuses ordinary MIPS firmware before any provider runs. docs/ghidra-mips.md describes the refusal as temporary ("until REA parses and reconciles their declarations").

Impact (one real MIPS32r2 o32 Linux firmware root filesystem)

Kind Files Admitted before d4bd65c53 On main b3c5672ce
ET_EXEC 108 Ghidra lane refused at target resolution
ET_REL (.ko) 30 Ghidra lane refused at target resolution
ET_DYN 87 (shared lane, #2362) refused at target resolution

All 225 carry exactly one GNU attribute, and its value agrees with the ABI flags record wherever one exists (readelf -A):

Tag_GNU_MIPS_ABI_FP ABI flags fp_abi Files
Hard float (double precision) Hard float (double precision) 190
Soft float Soft float 30
Hard float (double precision) no record 5

The 5 without a record declare o32 in e_flags, so the existing "declared ABI without a record" refusal applies to them anyway.

The real-Ghidra executable lane is also affected: npm run verify:ghidra:mips fails on main. Its carved fixture now hits the incomplete-inspection refusal from the same commit; that part is a separate, documented decision.

Proposed fix

Parse the section instead of refusing it outright, keeping everything else fail-closed:

  • Strict parsing of the ELF attributes format: format version A, then vendor subsections and Tag_File sub-subsections, with exact length accounting in the file's byte order. Truncation, overruns, bad ULEB128 values and missing string terminators are errors. The read is bounded, so section size never drives an unbounded allocation.
  • Understood declarations only: the gnu vendor, Tag_File scope, Tag_GNU_MIPS_ABI_FP (4) and Tag_GNU_MIPS_ABI_MSA (8). Other vendors, per-section or per-symbol scopes, unknown tags, duplicate tags and duplicate attribute sections are refused.
  • Reconciliation with the ABI flags record (same Val_GNU_MIPS_ABI_FP_* numbering): the FP tag must equal fp_abi, and the MSA tag must agree with AFL_ASE_MSA in ases. A conflict is refused, like conflicting program and section ABI records.
  • Recordless legacy images, which have no other FP declaration: the GNU FP tag is admitted only when it matches what that lane already models (hard-float double). Any MSA declaration is refused.
  • Profile commitment: the parsed attributes go into the analysis profile (mips_elf.gnu_attributes), so they invalidate profile-bound snapshots.

I have an implementation and will open a PR referencing this issue.

Originally created by @AurelioB on GitHub (Oct 14, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/3096 ## Problem `d4bd65c53` (`fix(providers)!`) makes `readMipsElfMetadata` refuse any MIPS ELF whose section table contains an `SHT_GNU_ATTRIBUTES` section: > MIPS ELF declares GNU ABI attributes that REA does not inspect; refusing provider selection until the declared ABI is parsed and reconciled GCC and GNU ld emit `.gnu.attributes` in essentially every MIPS object they produce, so this refuses ordinary MIPS firmware before any provider runs. `docs/ghidra-mips.md` describes the refusal as temporary ("until REA parses and reconciles their declarations"). ## Impact (one real MIPS32r2 o32 Linux firmware root filesystem) | Kind | Files | Admitted before `d4bd65c53` | On `main` `b3c5672ce` | |---|---|---|---| | `ET_EXEC` | 108 | Ghidra lane | refused at target resolution | | `ET_REL` (`.ko`) | 30 | Ghidra lane | refused at target resolution | | `ET_DYN` | 87 | (shared lane, #2362) | refused at target resolution | All 225 carry exactly one GNU attribute, and its value agrees with the ABI flags record wherever one exists (`readelf -A`): | `Tag_GNU_MIPS_ABI_FP` | ABI flags `fp_abi` | Files | |---|---|---| | Hard float (double precision) | Hard float (double precision) | 190 | | Soft float | Soft float | 30 | | Hard float (double precision) | no record | 5 | The 5 without a record declare o32 in `e_flags`, so the existing "declared ABI without a record" refusal applies to them anyway. The real-Ghidra executable lane is also affected: `npm run verify:ghidra:mips` fails on `main`. Its carved fixture now hits the incomplete-inspection refusal from the same commit; that part is a separate, documented decision. ## Proposed fix Parse the section instead of refusing it outright, keeping everything else fail-closed: - **Strict parsing** of the ELF attributes format: format version `A`, then vendor subsections and `Tag_File` sub-subsections, with exact length accounting in the file's byte order. Truncation, overruns, bad ULEB128 values and missing string terminators are errors. The read is bounded, so section size never drives an unbounded allocation. - **Understood declarations only:** the `gnu` vendor, `Tag_File` scope, `Tag_GNU_MIPS_ABI_FP` (4) and `Tag_GNU_MIPS_ABI_MSA` (8). Other vendors, per-section or per-symbol scopes, unknown tags, duplicate tags and duplicate attribute sections are refused. - **Reconciliation with the ABI flags record** (same `Val_GNU_MIPS_ABI_FP_*` numbering): the FP tag must equal `fp_abi`, and the MSA tag must agree with `AFL_ASE_MSA` in `ases`. A conflict is refused, like conflicting program and section ABI records. - **Recordless legacy images,** which have no other FP declaration: the GNU FP tag is admitted only when it matches what that lane already models (hard-float double). Any MSA declaration is refused. - **Profile commitment:** the parsed attributes go into the analysis profile (`mips_elf.gnu_attributes`), so they invalidate profile-bound snapshots. I have an implementation and will open a PR referencing this issue.
bsakaguchi 2026-10-15 18:30:53 +00:00
  • closed this issue
  • added the
    bug
    label
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#1080
No description provided.