Skip to content

Preserve SysV semaphore errno across host dispatch - #912

Closed
brandonpayton wants to merge 1 commit into
mainfrom
fix/semctl-errno
Closed

Preserve SysV semaphore errno across host dispatch#912
brandonpayton wants to merge 1 commit into
mainfrom
fix/semctl-errno

Conversation

@brandonpayton

@brandonpayton brandonpayton commented Jul 13, 2026

Copy link
Copy Markdown
Member

Why

System V IPC is the POSIX-style interprocess-communication API used here for semaphore sets. errno is the numeric error code returned to a guest program when a system call fails.

kernel_handle_channel normalizes syscall failures to CH_RETURN = -1 and stores the actual errno in CH_ERRNO. The four intercepted semctl paths ignored CH_ERRNO and derived errno from -CH_RETURN, so every failure became EPERM. This surfaced in util-linux ipcrm: querying a removed semaphore should return EINVAL, but Kandelo reported EPERM.

This is a compatible implementation correction: the host now consumes the existing channel errno field as designed. It changes no channel layout, syscall interface, or process expectation, so no ABI bump is required. scripts/check-abi-version.sh confirms the snapshot and generated bindings remain in sync.

What changed

  • preserve the kernel existing CH_ERRNO contract across all four host-intercepted semctl marshalling branches: IPC_STAT, GETALL, SETALL, and scalar commands
  • keep IPC_STAT and GETALL copy-back conditional on successful kernel returns
  • extend the real SysV IPC guest fixture to require EINVAL after IPC_RMID through IPC_STAT, GETALL, SETALL, and GETVAL

Validation

  • ./scripts/dev-shell.sh bash build.sh
  • focused Node execution: cd host && npx vitest run test/sysv-ipc.test.ts (1 passed)
  • real Chromium execution of the same examples/sysv_ipc_test.wasm fixture through scripts/browser-test-runner.ts (1/1 passed; isolated local port because 5199 was occupied by another worktree)
  • ./scripts/dev-shell.sh bash scripts/ci-run-test-suite.sh cargo-kernel (963 passed)
  • ./scripts/dev-shell.sh bash scripts/run-libc-tests.sh functional ipc_sem (1 passed)
  • ./scripts/dev-shell.sh bash scripts/run-sortix-tests.sh basic sys_sem/semctl (1 passed)
  • ./scripts/dev-shell.sh bash scripts/check-abi-version.sh (passed; no ABI delta)
  • the first complete host run stopped only because the fresh worktree lacked declared programs/wasm64/hello64.wasm; after building the wasm64 musl sysroot and programs through the normal repository scripts, the full rerun passed: Vitest 785 passed, 2 expected failures, 108 skipped; Bun 3 passed

The kernel normalizes channel failures to CH_RETURN=-1 and stores the actual error in CH_ERRNO. Forward that errno through every intercepted semctl command shape instead of deriving EPERM from the normalized return value.

Extend the SysV IPC guest regression to verify EINVAL after IPC_RMID for IPC_STAT, GETALL, SETALL, and scalar GETVAL.
@brandonpayton

Copy link
Copy Markdown
Member Author

Independent exact-head review: ACCEPT for Brandon review at 89b826e98d0f346d1b20def7797fe7c44a5479c3 / tree 4742a71ea9b2443a4927b9e106952f15dad689c3.

The review traced the observed EPERM to the host interception boundary: the kernel already emitted normalized CH_RETURN=-1 with the correct CH_ERRNO=EINVAL, while all four handleSemctl command shapes discarded that field and derived errno from the normalized return. The final change reads the existing channel errno in IPC_STAT, GETALL, SETALL, and scalar branches, retains output copy-back only on success, and does not alter marshalling, channel layout, syscall numbers, or user-binary expectations. No ABI bump is warranted.

The strengthened guest fixture exercises every branch after IPC_RMID and requires EINVAL; the same binary passes through Node and real Chromium. Kernel 963/963, libc ipc_sem, Sortix sys_sem/semctl, ABI check, full Vitest (785 passed, 2 expected failures, 108 skipped), and Bun 3/3 passed after the fresh worktree's normal wasm64 fixture build. Only the three intended files are committed; inherited submodule/build dirt remains unstaged. No material finding remains.

@brandonpayton

Copy link
Copy Markdown
Member Author

Absorbed by rebase-merged #967. Main is now 6efb411 with the sealed tree b133bfa018f7e2bc84c4845edf2f945b2f844954, and ABI 41 activation completed successfully in run 29550069085. The absorption audit confirmed this PR\x27s behavior and tests are present in that merged tree, so this source PR is closed and its branch is deleted.

@brandonpayton
brandonpayton deleted the fix/semctl-errno branch July 17, 2026 02:38
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.

1 participant