Repository navigation
fix(bsd): size In6Ifreq to the real struct in6_ifreq and read ifru_flags6 - #193
Draft
andrewgazelka wants to merge 1 commit into
Draft
andrewgazelka wants to merge 1 commit into
andrewgazelka wants to merge 1 commit into
Conversation
…ags6 SIOCGIFAFLAG_IN6 encodes sizeof(struct in6_ifreq) = 0x120 bytes, but the local struct was 48 bytes, so the kernel's copyout wrote past it, and the flags were read from an offset the kernel never writes. Use the real union layout, with a compile-time size assert. Assisted-by: Claude:claude-sonnet-5-5
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.
src/os/bsd/ipv6_addr_flags.rsdefinesIn6Ifreqas 48 bytes (name, sockaddr_in6, int). From the FreeBSD, OpenBSD and NetBSDnetinet6/in6_var.h(current main/master/trunk),struct in6_ifreqis name[16] plus a union whose largest members areicmp6_ifstat(34 x u64) andin6_ifstat(20 x u64), so 288 bytes on LP64.SIOCGIFAFLAG_IN6is_IOWR('i', 73, struct in6_ifreq)in all three; the existing constant0xC1206949is that encoding for 288 bytes (checked with a C program built from the header struct bodies: size 288, ioctl 0xc1206949). Since the ioctl framework copies the encoded length in and out, the current 48-byte struct is smaller than what the kernel writes back. Also, the kernel returns the flags inifru_flags6at union offset 0 (struct offset 16), while the code reads anintat offset 44.This changes the struct to the real union layout (padded to 288 bytes, compile-time assert), fills
ifru_addrand readsifru_flags6.Measured:
cargo check --target x86_64-unknown-freebsdand--target x86_64-unknown-netbsdpass. Not checked: OpenBSD (tier 3 target), and I did not run this on any BSD host, so the overflow and the wrong-offset read are from the headers, not observed. Header excerpts and sizes: see commit message; sources were the three in6_var.h files above.AI disclosure: written with Claude (Sonnet); commit carries an
Assisted-by:trailer.