Repository navigation
Refused a UDP reply from an IPv6 address that is no longer valid - #496
Merged
Merged
Conversation
A received IPv6 datagram carries the address it arrived on, and _nxd_udp_socket_send uses that address as the source of a reply without looking one up. Once the address has been deleted, or IPv6 disabled, the entry is no longer attached to an interface. _nx_ipv6_packet_send then fails its NX_ASSERT that the interface is not NULL, with the IP mutex held: the caller sleeps forever and the IP thread waits for the mutex, so the IP instance is dead. With NX_ENABLE_INTERFACE_CAPABILITY the send dereferences the NULL interface first. Measured on two IP instances on the RAM driver: a datagram received on 2001::4, the address deleted, the received packet sent back with nxd_udp_socket_send. In v6_build and v6_only_build the caller is left in TX_SLEEP and the IP thread suspended on the mutex; in v6_full_build the process takes a segmentation fault. The send now returns NX_NO_INTERFACE_ADDRESS when the packet carries an address that is not valid, before anything else uses it. That is the status the function's header already documents for this case, and the one nxd_udp_socket_source_send and the TCP send path return for an address that is not valid. The packet stays with the caller. An address set again and still being checked for duplicates is refused the same way, where until now the datagram was dropped and the send reported success. The product file header is unchanged. netx_udp_ipv6_reply_invalid_address_test replies with a received packet after the address is deleted, after IPv6 is disabled, and after the address is deleted and set again, and checks each refusal, that the refused packet can be sent once the address is valid, and that datagrams cross both ways afterwards. The reply is sent from a helper thread with a bounded wait. Without the change the test fails within a second, or with the segmentation fault; with it, it passes. Assisted-by: Claude Code (Opus 5.5) <noreply@anthropic.com>
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.
Problem
A received IPv6 datagram carries the address it arrived on
(
nx_packet_address.nx_packet_ipv6_address_ptr), and_nxd_udp_socket_senduses that address asthe source of a reply instead of looking one up. Once that address has been deleted
(
nxd_ipv6_address_delete) or IPv6 disabled (nxd_ipv6_disable), the entry is cleared and nolonger attached to an interface. Sending the received packet back then:
NX_ASSERT(if_ptr != NX_NULL)in_nx_ipv6_packet_sendwithnx_ip_protectionheld: thecaller sleeps forever and the IP thread blocks on the mutex, so the IP instance is dead;
NX_ENABLE_INTERFACE_CAPABILITY, dereferences the NULL interface in_nxd_udp_socket_sendfirst.
It is the same mechanism as the TCP control path fixed in #490, reached through the UDP data path.
Measured on
dev(9609e856)Two IP instances on the RAM driver; a datagram received on
2001::4, the address deleted, thereceived packet sent back with
nxd_udp_socket_send:Change
_nxd_udp_socket_sendreturnsNX_NO_INTERFACE_ADDRESSwhen the packet carries an IPv6 addressthat is not valid, before anything uses it. That is the status the function's header already lists
("Socket interface not marked valid"), and the one
nxd_udp_socket_source_sendreturns for anaddress that is not valid. The packet stays with the caller. An address set again and still in
duplicate address detection is refused the same way; until now that datagram was dropped by the
header build and the send reported success.
Test
netx_udp_ipv6_reply_invalid_address_testreplies with a received packet after the address isdeleted, after IPv6 is disabled, and after the address is deleted and set again. It checks each
refusal, that the refused packet goes out once the address is valid again, and that datagrams
cross both ways afterwards. The reply is sent from a helper thread with a bounded wait, so without
the change the test fails rather than hangs.
Swept over all 43 configurations of
test/cmake/netxduo, five runs each: 145 pass (the 29 IPv6configurations), 70 N/A (the 14 IPv4-only ones), 0 fail, 0 build failures.