Skip to content

fix(libSceNet): reject the flags and names the module rejects - #9727

Merged
adriadam10 merged 1 commit into
boykopovar:mainfrom
KernelPanicNT:fix/net-reject-unsupported-flags
Oct 25, 2026
Merged

adriadam10 merged 1 commit into
boykopovar:mainfrom
KernelPanicNT:fix/net-reject-unsupported-flags

Conversation

@KernelPanicNT

@KernelPanicNT KernelPanicNT commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

What

Four libSceNet calls now fail with EINVAL (0x80410116, errno 22) for the argument values the PS5 libSceNet module rejects. Until now they ignored their flags, and sceNetEpollCreate its name:

Source of the behaviour.

  • prosper's reading of the libSceNet module, which cites an image-relative offset for each check:
    • sceNetEpollCreate "requires a name and zero flags (+0x809f-+0x80b8); anything else is EINVAL" (L448-L449).
    • sceNetGetMacAddress: "The module first refuses a null addr or non-zero flags with EINVAL (+0x542c-+0x5438)" (L531-L541).
    • sceNetResolverCreate: "Non-zero flags are EINVAL (+0xbae0)" (L564-L578).
    • sceNetResolverStartNtoa: "The module refuses a negative timeout or retry and flags & 0xfffefffe with EINVAL (+0xbb11-+0xbb2c)", ahead of its resolver id check (L579-L594).
  • prosper says these NIDs are in the PS5 3.20 libSceNet export set (L436); it does not record which firmware version the disassembled module came from.
  • This follows the merged fix(libSceGameUpdate): return the module's lifecycle and argument errors #7856, which took libSceGameUpdate's errors from a prosper module reading in the same way.

What is kept as it is, and why.

  • The two accepted resolver flag bits: sceNetResolverStartNtoa still ignores bits 0x1 and 0x10000, and the timeout and retry count: every lookup runs once, synchronously, through the host resolver, as on main. What these bits do on a console is not known (shadPS4 names them async and IP address literals disabled), and making them throw would break callers that pass them today. The new debt entry records this.
  • A null resolver name: prosper's sceNetResolverCreate also refuses a null name, but its module citation covers only the flags, so a null name is still accepted.
  • Everything after the new checks (the resolver lookups, epoll and the MAC address) is unchanged.

Changes:

  • Export.cpp: the checks above at the top of the four functions.
  • guest_sce_net, new CheckRejectedArguments: each rejected value fails with EINVAL and sets sceNetErrnoLoc to 22; a rejected sceNetGetMacAddress leaves the address untouched; on a resolver with a pending abort the rejected sceNetResolverStartNtoa calls return EINVAL and the next valid call still returns the abort's EINTR; on a destroyed resolver the rejected values return EINVAL, and flags 0, 0x1, 0x10000 and 0x10001 reach the EBADF id check.
  • docs/dev/debt/libSceNet.md: a new sceNetResolverStartNtoa entry for the two ignored flag bits, the timeout and the retry count.

Unblocks: none. No title is known to pass these values; this corrects the result on those paths.

Tested

Linux (GitHub Codespace, 4 cores, AMD EPYC 7763, native build of this branch b7372d895, rebased on main d969e4bd6):

  • guest_sce_net_tests: 5/5 runs pass.
  • ctest -R "net_epoll_lifetime|guest_sce_net" (guest_sce_net and the eight net_epoll_lifetime_* cases, which create epolls with a name and flags 0): 5/5 runs pass, 9/9 tests each.
  • Negative control: with core/libs/prx/libSceNet/Export.cpp from main, guest_sce_net_tests aborts (exit 134, SIGABRT in CheckRejectedArguments(); its Require aborts without a message): 1/9 Test #1292: guest_sce_net ....................Subprocess aborted***Exception, and the eight net_epoll_lifetime_* cases still pass. 5/5 pass again after restoring it.

Windows: @ycbuzi ran the previous head 5e48663b5 merged onto main 6a6a35fdf5 (Windows 11, MinGW-w64 GCC 15.2.0, Release): guest_sce_net passes, and aborts with Export.cpp from main.

Not tested: macOS, a console, a title run.

Checks:

  • python3 tools/check_conventions.py --base origin/main passes with no findings.
  • tools/progress.py: unchanged, 4835/11180 (43.25%) on base and head; no export is added or removed.
  • git diff --check against main: clean.

Duplicate and overlap check

Searches of open and closed pull requests for sceNetEpollCreate, sceNetResolverCreate, sceNetGetMacAddress, sceNetResolverStartNtoa, "libSceNet EINVAL" and "libSceNet flags" find no other change to these checks. None of the open libSceNet pull requests changes the four functions in its diff; #9636 (deterministic resolver failures) edits other sceNetResolverStartNtoa assertions in GuestSceNet.cpp, and #9493 adds an sceNetEpollCreate call with flags 0 in a test.

python3 tools/pr_overlap.py --branch fix/net-reject-unsupported-flags reports no conflict. It could not compare #5836, #6044, #6879, #7201 and #8398, which conflict with main in the shared files. Checked by hand: none of them changes these four functions or the new test (#5836 is peer socket retries, #6879 adds one line to Export.cpp for the browser build, #7201 is the macOS port, #8398 is NetCtl NpToolkit callbacks), and #6044 moves GuestSceNet.cpp to core/libs/tests/networking/; whichever lands second keeps both changes.

Checklist

  • Based on current main (d969e4bd6); 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 under Silent stubs in their library's technical debt file
  • 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
  • Fixes: none
  • Unblocks: none (argument errors only; no title is known to pass these values)
  • GPUs tested: n/a
  • AI-assisted: yes

@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.

Pull request Conflicting files (lines on main) Same exports Same new files
PR 10881 core/libs/tests/GuestSceNet.cpp L1866

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 5836 core/libs/prx/libSceNet/Export.cpp
core/libs/tests/GuestSceNet.cpp
docs/dev/debt/libSceNet.md
PR 7201 core/libs/prx/libSceNet/Export.cpp
PR 9932 core/libs/prx/libSceNet/Export.cpp
core/libs/tests/GuestSceNet.cpp
docs/dev/debt/libSceNet.md
PR 9948 core/libs/prx/libSceNet/Export.cpp
core/libs/tests/GuestSceNet.cpp
docs/dev/debt/libSceNet.md
PR 10502 core/libs/prx/libSceNet/Export.cpp
core/libs/tests/GuestSceNet.cpp
docs/dev/debt/libSceNet.md

@MarcZX10 MarcZX10 left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The cited module evidence and focused regression coverage are substantive. Separately, the branch is 13 commits behind current main and the test report is against 7e2ba73e4. Please refresh the branch and rerun guest_sce_net and the overlap check on the resulting head before merge. The queue comment is not a reason to hold this PR; it is fine to keep submitting PRs and they will be handled in due course. Product Linux/Windows CI jobs are skipped on the current PR.

I’ve noticed that holding this PR because of #5239 isn’t necessary. It’s fine for PRs to keep coming in; they’ll be handled in due course. Please disregard my earlier request to hold or defer it.

@MarcZX10

MarcZX10 commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

I’ve noticed that asking you to hold this PR was unnecessary. It’s fine to keep submitting PRs; maintainers will handle them in due course.

@ycbuzi

ycbuzi commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

Windows run of 5e48663 merged onto main 6a6a35f (6f7dad6796, clean), the platform the description lists as not run. Windows 11 Home 10.0.26200, MinGW-w64 GCC 15.2.0 (ucrt-posix-seh r7), Release, BUILD_TESTING=ON.

Built libSceNet and guest_sce_net_tests with no errors or warnings. ctest --repeat until-fail:2 on guest_sce_net: passes on both repeats. Negative control: with Export.cpp of libSceNet taken from main, the same test aborts (exit code 0xc0000409). Not run: a title.

@KernelPanicNT
KernelPanicNT force-pushed the fix/net-reject-unsupported-flags branch from 5e48663 to b7372d8 Compare October 22, 2026 18:27
@ntamas94

Copy link
Copy Markdown
Contributor

Console rows for two of the four calls, measured on a PS4 Pro (firmware 10.71, 10.710.001) with a user-mode homebrew PRX loaded by a small watcher app after sceNetInit and sceNetPoolCreate; one line per call as function[label] | arguments | return | sceNetErrnoLoc | output:

sceNetEpollCreate | "survey", 0 | 0x00000010 | 0 |
sceNetEpollCreate[null-name] | NULL, 0 | 0x80410116 | 22 |
sceNetEpollCreate[flags-bad] | "survey", 0x7777 | 0x80410116 | 22 |
sceNetResolverCreate | "survey", (int32_t)$pool, 0 | 0x00000010 | 0 |
sceNetResolverCreate[bad-pool] | "survey", 0x7fff, 0 | 0x80410109 | 9 |
sceNetResolverCreate[null-name] | NULL, (int32_t)$pool, 0 | 0x00000011 | 0 |

On PS4 sceNetEpollCreate rejects a null name and non-zero flags with EINVAL and errno 22, as this PR does, and sceNetResolverCreate accepts a null name, which matches keeping it accepted here. Non-zero flags on sceNetResolverCreate, sceNetGetMacAddress and sceNetResolverStartNtoa were not measured.

@Dom3005

Dom3005 commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

Windows rerun on the current head b7372d8 (rebased since @ycbuzi's run of 5e48663), merged onto main f57ceaa together with #9932, which also changes libSceNet/Export.cpp (merges cleanly). Windows 11 Home 10.0.26200, WinLibs GCC 15.2.0 r7, Release, BUILD_TESTING=ON.

The diff since the earlier run is the rebase only. No findings.

AI-assisted: yes

@BunnyFl

BunnyFl commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

I checked the four calls against the PS5 firmware 13.42 libSceNet module, running each one in an emulator with the module marked initialized (head b7372d8). Every rejection the PR adds matches: 0x80410116 with sceNetErrnoLoc 22.

  • sceNetEpollCreate: a null name or non-zero flags (tried 1, 0x10000, -1) is refused. A name with flags 0 goes on to the epoll creation.
  • sceNetGetMacAddress: a null address or non-zero flags is refused, and the address is left untouched.
  • sceNetResolverCreate: non-zero flags are refused. A null name with flags 0 passes the module's own checks: its length is taken as 0, and the call goes on to resolver creation. The name is then passed to the socket the resolver opens, which I couldn't follow from the module. So keeping a null name accepted is consistent with 13.42 as far as the module goes.
  • sceNetResolverStartNtoa: a negative timeout, a negative retry, or any flag bit outside 0x10001 is refused before the resolver is looked up. That covers 2, 0x20000, 0x10003, 0x80000000 and -1. Flags 0, 1, 0x10000 and 0x10001 reach the resolver check (EBADF for an unknown id).

One more sceNetResolverStartNtoa rejection that the PR doesn't model. A timeout of 0 is replaced by 1000000. After that, a timeout from 1 to 999999 is also refused with EINVAL, still before the resolver is looked up. Timeouts 1 and 999999 were refused; 1000000, 5000000 and 0x7fffffff reached the resolver check. On this PR such a timeout is accepted.

A null hostname or address comes after the resolver check on 13.42: with an unknown id, either one gives EBADF. main checks those two before the id. This PR doesn't change that, so I'm only noting it.

AI-assisted: yes (Claude Code).

sceNetEpollCreate fails with EINVAL for a null name or non-zero flags,
sceNetResolverCreate and sceNetGetMacAddress for non-zero flags, and
sceNetResolverStartNtoa, before any other check, for a negative timeout
or retry count or a flag bit outside 0x10001, as prosper reads the
libSceNet module. The two accepted resolver flag bits are still ignored,
which the debt file now records.
@adriadam10
adriadam10 force-pushed the fix/net-reject-unsupported-flags branch from b7372d8 to 6e8ec6d Compare October 25, 2026 18:56
@adriadam10
adriadam10 dismissed MarcZX10’s stale review October 25, 2026 18:57

Dismissing a stale review: the requested changes were addressed after it (new head) and the merge queue blocks on it. Please request changes again if anything is still open.

@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 25, 2026
@adriadam10
adriadam10 merged commit b76f08c into boykopovar:main Oct 25, 2026
10 checks passed
@adriadam10

Copy link
Copy Markdown
Collaborator

Checked the four rejections against prosper's module reading and the console/Windows measurements in the thread (@ntamas94, @BunnyFl, @ycbuzi, @Dom3005); the new CheckRejectedArguments aborts without the Export.cpp change. Rebased onto current main (test declarations now come from Net.hpp, debt entry kept next to the new neighbours); the libs tests pass after the rebase; merged.

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.

7 participants