Repository navigation
Declare the sysctl(3) prototype, check errors and retry grown values - #22
Merged
Merged
Conversation
added 6 commits
July 6, 2026 23:01
The script boots an official BASIC-CLOUDINIT VM image headless under OVMF, authorizes an ephemeral ssh key through a NoCloud seed ISO, installs pytest from packages and runs the suite over ssh. It uses KVM when available and falls back to TCG emulation. Readiness is detected by the absence of the firstboot sentinel, which avoids racing the reboot at the end of the first boot. The 14.x images apply base-system patches on first boot before sshd becomes reachable, which delays the first connection by a few minutes. Images are cached outside the repository and are never committed.
The workflow only uses github-owned actions, so it works under restrictive organization action allowlists. The FreeBSD job runs the QEMU harness for each supported release.
Lengths are size_t, so passing pointers to c_int let the kernel write 8 bytes into 4-byte objects on 64-bit architectures. The symbol is resolved lazily to keep the module importable on Linux, where the build tooling runs. All call sites go through one wrapper that checks the return code and raises OSError from errno.
The wrapper passes all six arguments, so query_size() no longer leaks garbage into newlen. Unknown sysctl names now raise OSError with ENOENT instead of returning a zero-filled OID, and iterating children stops cleanly at the end of the sysctl tree.
sysctl(3) reports ENOMEM when the value grew between the size query and the read, which sysctl(8) handles the same way.
Unknown names raise ENOENT; unknown OIDs echo numerically from the kernel's name lookup, so the value query carries the check. Bulk value reads skip NODE sysctls without handlers, which report EISDIR, and description lookups skip sysctls that vanish between listing and query.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
All libc sysctl(3) calls went through ctypes without a declared prototype.
The confirmed signature is
int sysctl(const int *, u_int, void *, size_t *, const void *, size_t), but every call site passedoldlenpasPOINTER(c_int), so the kernel wrote 8 bytes through a pointer to a 4-byte object on amd64.query_size()passed only five of the six arguments, leavingnewlento whatever was in the sixth argument register.Return codes were ignored, so a nonexistent sysctl name silently produced a 24-zero OID.
Changes:
freebsd_sysctl.libcdeclares argtypes/restype (resolved lazily, so the module stays importable on Linux where the build tooling runs) and wraps sysctl(3) in a helper that raisesOSErrorfrom errno on failure.c_size_tlengths;query_size()passes the previously missingnewlen.query_value()grows the buffer and retries onENOMEM, like sysctl(8), for values that grow between the size query and the read.childrenstops cleanly at the end of the sysctl tree, where the kernel reportsENOENT.Behavior change: unknown sysctl names and OIDs raise
OSErrorwithENOENTinstead of returning garbage; tests cover both.