macos 15.6.1 - BSD sendto() fails for IPv4-mapped IPv6 addresses

There appears to be some unexplained change in behaviour in the recent version of macos 15.6.1 which is causing the BSD socket sendto() syscall to no longer send the data when the source socket is bound to a IPv4-mapped IPv6 address.

I have attached a trivial native code which reproduces the issue. What this reproducer does is explained as a comment on that code's main() function:

// Creates a AF_INET6 datagram socket, marks it as dual socket (i.e. IPV6_V6ONLY = 0),
// then binds the socket to a IPv4-mapped IPv6 address (chosen on the host where this test runs).
//
// The test then uses sendto() to send some bytes. For the sake of this test, it uses the same IPv4-mapped
// IPv6 address as the destination address to sendto(). The test then waits for (a maximum of) 15 seconds to
// receive that sent message by calling recvfrom().
//
// The test passes on macos (x64 and aarch64) hosts of versions 12.x, 13.x, 14.x and 15.x upto 15.5.
// Only on macos 15.6.1 and the recent macos 26, the test fails. Specifically, the first message that is
// sent using sendto() is never sent (and thus the recvfrom()) times out. sendto() however returns 0,
// incorrectly indicating a successful send. Interesting, if you repeat sendto() a second message from the
// same bound socket to the exact same destination address, the send message is indeed correctly sent and
// received immediately by the recvfrom(). It's only the first message which goes missing (the test uses
// unique content in each message to be sure which exact message was received and it has been observed that
// only the second message is received and the first one lost).
//
// Logs collected using "sudo log collect --last 2m" (after the test program returns) shows the following log
// message, which seem relevant:
// ...
// default kernel  cfil_hash_entry_log:6088 <CFIL: Error: sosend_reinject() failed>:
//          [86868 a.out] <UDP(17) out so 59faaa5dbbcef55d 127846646561221313 127846646561221313 age 0>
//          lport 65051 fport 65051 laddr 192.168.1.2 faddr 192.168.1.2 hash 201AAC1
// default kernel  cfil_service_inject_queue:4472 CFIL: sosend() failed 22
// ...
//

As noted, this test passes without issues on various macosx version (12 through 15.5), both x64 and aarch64 but always fails against 15.6.1. I have been told that it also fails on the recently released macos 26 but I don't have access to such host to verify it myself.

The release notes don't usually contain this level of detail, so it's hard to tell if something changed intentionally or if this is a bug. Should I report this through the feedback assistant?

Attached is the source of the reproducer, run it as:

clang dgramsend.c
./a.out

On macos 15.6.1, you will see that it will fail to send (and thus receive) the message on first attempt but the second one passes:

...
created and bound a datagram dual socket to ::ffff:192.168.1.2:65055
::ffff:192.168.1.2:65055 sendto() ::ffff:192.168.1.2:65055
---- Attempt 1 ----
sending greeting "hello 1"
sendto() succeeded, sent 8 bytes
calling recvfrom()
receive timed out
---------------------
---- Attempt 2 ----
sending greeting "hello 2"
sendto() succeeded, sent 8 bytes
calling recvfrom()
received 8 bytes: "hello 2"
---------------------
TEST FAILED
...

The output "log collect --last 2m" contains a related error (and this log message consistently shows up every time you run that reproducer):

...
default kernel  cfil_hash_entry_log:6088 <CFIL: Error: sosend_reinject() failed>:
          [86248 a.out] <UDP(17) out so 59faaa5dbbcef55d 127846646561221313 127846646561221313 age 0>
          lport 65055 fport 65055 laddr 192.168.1.2 faddr 192.168.1.2 hash 201AAC1
default kernel  cfil_service_inject_queue:4472 CFIL: sosend() failed 22
...

I don't know what it means though.

macos 15.6.1 - BSD sendto() fails for IPv4-mapped IPv6 addresses
 
 
Q