fix(net/igmp): restore General Query handling broken by pointer compare#19436
Open
dakejahl wants to merge 1 commit into
Open
fix(net/igmp): restore General Query handling broken by pointer compare#19436dakejahl wants to merge 1 commit into
dakejahl wants to merge 1 commit into
Conversation
The group address in the IGMP header is declared as uint16_t grpaddr[2], so it decays to a pointer. Comparing it against INADDR_ANY compares the address of a struct member against 0, which is always false. The General Query branch is therefore unreachable and GCC discards it entirely. Commit 09bb292 ("net/igmp: fix build warning on GCC 12.2.0") replaced the original if (igmp->grpaddr == 0) with if (net_ipv4addr_cmp(igmp->grpaddr, INADDR_ANY) != 0) but net_ipv4addr_cmp(a, b) expands to (a == b) and INADDR_ANY expands to ((in_addr_t)0), so the emitted comparison is unchanged. The -Waddress diagnostic disappeared only because the comparison now originates inside a macro expanded from a header included via -isystem, and GCC suppresses warnings from system-header macros. The defect was hidden, not fixed. That commit also rewrote the unicast query test from group->grpaddr != 0, which was well-formed, into the same pointer comparison, making it unconditionally true. Convert the header field with net_ip4addr_conv32() once, and compare the resulting in_addr_t. The conversion was already being done in the group-specific branch, so this only hoists it and reuses it. Impact: a General Query (destination 224.0.0.1, group address 0) is the periodic query every IGMP querier sends. It currently falls through to the group-specific branch, where igmp_grpallocfind() allocates a group for 0.0.0.0 and schedules a report for it, while joined groups never have their report timers restarted. The querier then ages out the membership and multicast delivery to the device stops. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
|
xiaoxiang781216
approved these changes
Jul 15, 2026
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.
Summary
igmp_input()never handles IGMP General Queries. The test that distinguishes a General Query from a Group-Specific Query compares the address of a struct member against zero, so it is always false and the General Query branch is unreachable. GCC discards the branch entirely.The group address is declared in
include/nuttx/net/igmp.hasso
igmp->grpaddrdecays toFAR uint16_t *. Comparing it toINADDR_ANYcompares a pointer, not the address the packet carries.This was reported once before, as a compiler warning rather than as a defect. Commit 09bb292 (#7273, "net/igmp: fix build warning on GCC 12.2.0") changed
to
net_ipv4addr_cmp(a, b)expands to(a == b)andINADDR_ANYexpands to((in_addr_t)0), so the emitted comparison is unchanged. The-Waddressdiagnostic disappeared for a different reason: the comparison now originates inside a macro expanded from a header reached via-isystem, and GCC suppresses warnings from system-header macros. Demonstration with the same expression, macro in a header:The defect was hidden rather than fixed, and the report was closed. That commit also rewrote the unicast query test from
group->grpaddr != 0, which was well-formed (group->grpaddris anin_addr_t), into the same pointer comparison, making it unconditionally true.The fix converts the header field once with
net_ip4addr_conv32()and compares the resultingin_addr_t. The conversion was already performed in the group-specific branch, so this only hoists it and reuses it at the other two sites.net_ipv4addr_hdrcmp()is not usable here because it appliesnet_ip4addr_conv32()to both operands, and the second operand is the scalarINADDR_ANY.Impact
Affects all users with
CONFIG_NET_IGMP=y. No API, configuration, or build-system change; no new symbols. Code size grows by the branch that is currently being discarded (+149 bytes of.texton sim, see below).A General Query — destination
224.0.0.1, group address0, per RFC 2236 §2.4 — is the periodic query every IGMP querier emits, typically every 125 s. Today it falls through to the group-specific branch, whereigmp_grpallocfind(dev, &grpaddr)is called withgrpaddr == 0.0.0.0. That allocates a group entry for0.0.0.0and schedules a membership report for it, while the groups the device actually joined never get their report timers restarted. The querier then ages out those memberships and multicast delivery to the device stops.Testing
Host: Linux x86_64, GCC 13.
Board/config:
sim:dynconns, which setsCONFIG_NET_IGMP=y. Also cross-checked the affected expressions witharm-none-eabi-gcc 13.2.1.tools/checkpatch.sh -c -u -m -g master..HEAD(the invocation CI uses):sim:dynconnsbuilds cleanly before and after; the file produces no diagnostics either way, since the warning is suppressed as described above. The behavioural change is visible in the generated code instead.igmp->maxresp = 10;occurs only inside the General Query branch, so it is a reliable marker for whether that branch survives:.textigmp->maxresp = 10present073570a103)Before this change the compiler proves the General Query handler is dead and removes it; after it, the handler is emitted.
The defect was originally found by a
-Werrorbuild of PX4's NuttX fork, which predates 09bb292 and so still carries the originaligmp->grpaddr == 0and still fails to build. That fork is functionally affected in exactly the same way.Signed-off-by: Jacob Dahl dahl.jakejacob@gmail.com