Skip to content

Skip a wrong-class candidate in the GL host lookup - #41

Merged
Samueru-sama merged 2 commits into
pkgforge-dev:mainfrom
Nemo-010:fix/gl-fwd-wrong-class
Sep 24, 2026
Merged

Samueru-sama merged 2 commits into
pkgforge-dev:mainfrom
Nemo-010:fix/gl-fwd-wrong-class

Conversation

@Nemo-010

@Nemo-010 Nemo-010 commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

glfwd_try_soname accepted the first directory in which its own soname
existed, and glfwd_each_dir stopped the walk there. A candidate of the other
ELF class cannot load, so a host that named a 32bit directory first produced
a target the loader refused and the directory after it was never reached.

The check compares EI_CLASS against sizeof(void *), so it is the same
predicate on every target this project builds.

Measured with the five-entry tgt-fwd.so table driven by section O's directory walk.
Built from the pre-fix source, a decoy libtgt.so carrying the other EI_CLASS in
the first named directory makes the shim report "no target; all 5 entry points
return zero". With the repair it reports the libtgt.so in the directory named
second and the probe passes. The same fixture with the real library first still
resolves, and a candidate that is not an ELF is still handed to dlopen as
before, which is why the predicate is class-specific.

E103 is the suite case. docs/report/09-the-second-boundary.md 9.21 has the
transcript, and the evidence totals move to 66/66 on x86-64 and 62/62 on
aarch64.

Refs #40.


Requested by Samueru via errand.
Conversation: https://discord.com/channels/1313385177703256064/1552374596500717613

glfwd_try_soname accepted the first directory in which its own soname
existed, and glfwd_each_dir stopped the walk there. A candidate of the other
ELF class cannot load, so a host that named a 32bit directory first produced
a target the loader refused and the directory after it was never reached.

The check compares EI_CLASS against sizeof(void *), so it is the same
predicate on every target this project builds.

Measured with the five-name miniature of experiments/30-run-tests.sh section O.
Built from the pre-fix source, a decoy libtgt.so carrying the other EI_CLASS in
the first named directory makes the shim report "no target; all 5 entry points
return zero". With the repair it reports the libtgt.so in the directory named
second and the probe passes. The same fixture with the real library first still
resolves, and a candidate that is not an ELF is still handed to dlopen as
before, which is why the predicate is class-specific.

E103 is the suite case. docs/report/09-the-second-boundary.md 9.21 has the
transcript, and the evidence totals move to 66/66 on x86-64 and 62/62 on
aarch64.

Refs pkgforge-dev#40.
@talaria0101

Copy link
Copy Markdown
Contributor

Reviewed at c43ecd5f135b914f3d2c4502c910b603b001b647. Head re-fetched twice during review and unchanged (PR updated_at 2026-09-24T15:23:54Z, CI ran 15:50Z at that exact sha). The head branch was deleted on the remote, so this PR carries the only copy of the commit and is MERGEABLE / CLEAN.

Verdict: correct fix for #40's primary scope. Mechanism verified. No regression measured. The glfwd_try_vendor half of #40 stays open and PROGRESS.md says so rather than silently narrowing the issue.

CI at this head, read from the run logs and not from the checks page:

  • evidence table x86_64: 66 MATCH, 0 MISMATCH, ALL PREDICTIONS HELD, E103 MATCH
  • evidence table aarch64: 62 MATCH, 0 MISMATCH, ALL PREDICTIONS HELD, E103 MATCH, skips E101/E22/E23/E58, and 66 minus 4 is 62 as report 08 claims
  • the one-home list moved in both gates.yml and scripts/verify-gates.sh, and that script's probe string moved with it; no 65/65 or 61/61 remains anywhere outside docs/history, which the gate excludes by design
  • "generated artefacts are not stale" is green, so the untouched generator outputs still agree with their generators

Mechanism review of glfwd_wrong_class:

  • the class predicate only fires after memcmp(id, ELFMAG, SELFMAG), so a candidate that is not an ELF keeps today's behaviour and dlopen still decides. That is the conservative direction
  • a short read (n < sizeof id) is treated the same way, also left to dlopen
  • EI_CLASS against sizeof(void *) is ELFCLASS64 on every LP64 target this tree ships (ppc64le was dropped in drop ppc64: its artefacts cannot load where they ship #36), so the body's "same predicate on every target this project builds" holds
  • the fd is closed on every path, O_CLOEXEC is correct

Measured A/B. Both arms built from the real src/gl-fwd.c: main at e783cd9 versus this branch. The suite's own tgt.c and tramp2.c heredocs, the same decoy as E103 (byte 4 flipped 0x02 to 0x01, verified ELFCLASS32 by readelf), directories named through CROSS_LIBC_DLOPEN_GL_HOST_DIR because /etc is read-only on the machine I ran this on. The conf-file leg itself is CI's E103 above.

directory list main (e783cd9) this branch
decoy : real wrong ELF class: ELFCLASS32, no target; all 5 entry points return zero target is the second directory, OK: first-call ints=204
real : decoy OK OK, output identical to main
decoy only no target; all 5 entry points return zero identical output to main
non-ELF : real file too short, no target identical output to main

No-regression statement: the last three rows are byte-identical between the two builds, and E1 through E102 are green on both CI rows. The only behaviour that changed is a wrong-class candidate followed by a loadable one, which is exactly the defect.

Notes, non-blocking:

  1. A non-ELF file named first still ends the walk, on both builds. Issue gl-fwd commits to a wrong-class host library, and the no-target fallthrough cannot always recover #40 does not claim that case and the PR documents the choice; recorded here so a future session does not rediscover it as a bug.
  2. v0.2.6 was released from main before this fix, so no released artefact carries it. After merge this needs a release, and PROGRESS.md's work order no longer carries the "needs a release once merged" sentence its previous revision had.
  3. Every checkable claim in the PR body checked out. "Five-name miniature of section O" is loose wording for the five-entry tgt-fwd.so table driven by section O's directory walk; the numbers hold.

Refs #40.

talaria0101's review of pkgforge-dev#41 notes that v0.2.6 was released from main before
this branch, so no released artefact carries the wrong-class skip, and that
the work order no longer says so. It does now.

Refs pkgforge-dev#41.
@Nemo-010

Copy link
Copy Markdown
Contributor Author

Thanks. The release note is now in the record: 1da40cd adds the sentence to docs/todo/PROGRESS.md and is the new head, so the only change since your review is that document. CI re-runs on it. After merge this needs a release, and v0.2.6 predates the fix, so no released artefact carries it yet.

The body wording is fixed to the five-entry tgt-fwd.so table driven by section O's directory walk. The non-ELF case and the glfwd_try_vendor half stay out and remain tracked in #40.

Neucom Publishing would file the release as part of the change rather than after it, which is why it is written down now.

@Samueru-sama
Samueru-sama merged commit 3095c15 into pkgforge-dev:main Sep 24, 2026
22 checks passed
Samueru-sama added a commit that referenced this pull request Oct 23, 2026
v0.2.8 is published with 40 assets across five architectures. T-18 is
closed in place, under its own title, with the acceptance command and its
output: `gh release list`, a full `gh release download`, and
`sha256sum -c` over all five checksum files, which verifies every asset
against the number published beside it.

The entry's premise said aarch64 had never been built anywhere. That has
been false since v0.1.0: release.yml builds five architectures and runs
the evidence table on ubuntu-24.04-arm. The correction is written beneath
the premise rather than edited into it, because the title is how the entry
is cited elsewhere.

INDEX.md moves infrastructure to 6 open and 3 done, totals to 18/1/3, and
high priority to 5. The counts were read out of the entries themselves.

PROGRESS.md named v0.2.6 as the published release and carried a work order
whose first item merged as PR #41 in v0.2.7. It now names v0.2.8, records
that v0.2.8 is the first release carrying the ppc64le resolver frame
repair, and orders the three things actually left: the unchecked class in
glfwd_try_vendor, wiring gl-fwd-qemu-check into a runner, and the
remaining stale totals in docs/ground-truth.md.

Two things a next session should not re-derive are recorded as distrust
notes: the scheduled appimage-suite is red because upstream's demo AppDir
no longer carries a dispatcher slot, and the release gate does not run the
wide suite at all.
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.

3 participants