In udp_send two decisions are made:
- when to get a read lock or a write lock on the inp.
- when to provide the inp_route pointer to the IP output call.
Originally they were coupled. If no destination address was provided or the inp was unbound, the write lock was used and the inp_route was provided. Later, in udp: fix sending of IPv4-mapped addresses improved the sending towards mapped address. This resulted in taking also the write lock and provide the inp_route when sending on an IPv6 socket. This resulted in a bug reported in PR 275774 that was fixed in Fix udp IPv4-mapped address by using in the IPv6 case the write lock, but don't provide the inp_route in that case.
There is still a problem. On the first sendto()-call, the route is cached. If you then do a connect()-call followed by a send()-call, the cached route is used, even if it doesn't make sense. This might result in sending the packet on the wrong interface.
The correct fix is to take the write lock when needed (no address provided, or not bound yet, or using IPv6) and only cache the route when no address is provided.
This fixes also the issue reported by syzkaller.