Hi Jason, On Tue, Jul 28, 2015 at 03:45:30PM -0600, Jason Gunthorpe wrote: > Package: tftpd-hpa > Version: 5.2+20140608-3 > Severity: important > > This commit: > > tftp: convert IPv6-mapped IPv4 addresses to IPv4 > > If we receive IPv4 addresses mapped to IPv6, convert them back to IPv4 > so that mapping scripts which use \i behave sanely. > > Signed-off-by: H. Peter Anvin <[email protected]> > > Totally breaks IPv4 support when tftpd is used with an IPv6 listening socket > (eg when invoked from systemd) > > The issue is that the tftpd caller assumes that 'from' and 'myaddr' have the > same AF, however the above patch only cannonizes 'myaddr'. Ultimately this > results in the daemon attempting to use a socket with two address families and > fails: > > recvmsg(0, {msg_name(28)={sa_family=AF_INET6, sin6_port=htons(34500), > inet_pton(AF_INET6, "::ffff:10.0.0.192", &sin6_addr), sin6_flowinfo=0, > sin6_scope_id=0}, msg_iov(1)=[{"\0\1pxelinux.0\0netascii\0", 65468}], > msg_controllen=40, {cmsg_len=36, cmsg_level=SOL_IPV6, cmsg_type=, ...}, > msg_flags=0}, 0) = 22 > [..] > [pid 3757] socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 0 > [..] > [pid 3757] bind(0, {sa_family=AF_INET, sin_port=htons(0), > sin_addr=inet_addr("10.0.0.2")}, 16) = 0 > [pid 3757] connect(0, {sa_family=AF_INET6, sin6_port=htons(34500), > inet_pton(AF_INET6, "::ffff:10.0.0.192", &sin6_addr), sin6_flowinfo=0, > sin6_scope_id=0}, 28) = -1 EAFNOSUPPORT (Address family not supported by > protocol) > [pid 3757] sendto(3, "<27>Jul 28 15:32:20 tftpd[3757]: connect: Address > family not supported by protocol", 82, MSG_NOSIGNAL, NULL, 0) = 82 > > This makes the daemon utterly unusable. > > Suggest this tested patch: > > --- ../x/tftp-hpa-5.2+20140608/tftpd/recvfrom.c 2014-07-29 > 20:31:34.000000000 -0600 > +++ tftpd/recvfrom.c 2015-07-28 15:42:12.533074001 -0600 > @@ -24,6 +24,8 @@ > #include <machine/param.h> /* Needed on some versions of FreeBSD */ > #endif > > +#include <assert.h> > + > #if defined(HAVE_RECVMSG) && defined(HAVE_MSGHDR_MSG_CONTROL) > > #include <sys/uio.h> > @@ -253,6 +255,8 @@ > } > #endif > normalize_ip6_compat(myaddr); > + normalize_ip6_compat((union sock_addr *)from); > + assert(from->sa_family == myaddr->sa.sa_family); > } > #endif > }
I think I can see a couple of ways this might start to wind down a rathole of workaround upon workaround for various network configurations (like if the machine is only listening on an IPv6 socket, will local policy even allow it to send from an IPv4 one etc.) -- so I wonder if maybe the normalisation should only be applied to a separate value that is sent to the remapping code for use there, rather than to the actual address we use to send the reply ... It's also not clear to me that croaking with an assert is the ideal response here, but logging a warning at least would definitely be helpful. Let's see what HPA thinks is the right thing to do here. Cheers, Ron -- To UNSUBSCRIBE, email to [email protected] with a subject of "unsubscribe". Trouble? Contact [email protected]

