Skip to content

fix(libkernel): accept guest socket addresses whatever their sa_len - #1088

Merged
adriadam10 merged 1 commit into
boykopovar:mainfrom
kjhq:fix/libkernel-sockaddr-len
Oct 8, 2026
Merged

adriadam10 merged 1 commit into
boykopovar:mainfrom
kjhq:fix/libkernel-sockaddr-len

Conversation

@kjhq

@kjhq kjhq commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

What

bind, connect, sendto and the other socket calls rejected an address whose sa_len byte (byte 0) was not exactly 16 for IPv4 or 28 for IPv6. The FreeBSD kernel does not read sa_len on input: getsockaddr overwrites it with the length argument. A title that leaves sa_len 0 got EAFNOSUPPORT (47), which the console does not return for it.

Now the family byte and the length argument alone decide the address kind; addresses returned to the guest still carry the correct sa_len.

  • guest_udp: binding 127.0.0.1 with sa_len 0 succeeds and getsockname reports sa_len 16.

Title

PPSA17221 (Minecraft) needs #716 to load the modules in its app root, so every run below is current main + #716 + the PRs of this set (#1088, #1090–#1096), plus local changes outside it: dialog, NpAuth and TextToSpeech2 stubs that open PRs cover (#560, #925, #301) and a GPU end-of-pipe change that is not submitted. With all of them the title loads a world. The line below is from a run with only this PR left out, Windows 11, WinLibs GCC, normal user session.

Without it the title crashes about 12 s after start:

FATAL: unhandled exception 0xc0000005 on thread 5288 'MINECRAFT MAIN THREAD'
  rip 0x00007ff71ba02c2b app.exe+0x51d2c2b
  read of 0x0000000000000000

With it, the title reaches a loaded world.

Tested

Debian 13 (WSL2), GCC 14.2.0, Release: guest_udp and guest_tcp pass. The new check fails on main without the fix.

Windows 11, WinLibs GCC: PPSA17221 with this PR and the rest of the set loads a world (runs described above). Not tested with Windows ctest.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • AI-assisted: yes

🤖 Generated with Claude Code

The FreeBSD kernel ignores sa_len in a socket address passed in and sets
it from the length argument, so titles may leave it 0. Only the family
and the length argument decide the address kind now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@TheAggie

TheAggie commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Another title this fixes: the DOOM homebrew PPSA99666 v1.1.1 (lowbit/ps5-doom) zeroes its sockaddr_in and sets only the family and port, so its upload server's bind failed on every port:

[debug:0] upload: port 9666 refused (error 47)
...
[debug:0] upload: port 9673 refused (error 47)

With the same change (I had made it independently before finding this PR), the server binds and, together with poll and MSG_NOSIGNAL support, served its page and received a 28.8 MB WAD intact. Windows 11, MinGW GCC 15.2.0 (WinLibs r7), RTX 5070 Ti.

@adriadam10

Copy link
Copy Markdown
Collaborator

Checked: build + full ctest on current main + this PR (416/416), guest_udp fails with the Udp.cpp change reverted, Linux and Windows CI green. Matches FreeBSD getsockaddr, which ignores the input sa_len; returned addresses still carry the right one. Merging.

@adriadam10
adriadam10 merged commit 57b62ce into boykopovar:main Oct 8, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants