[syslinux] Bug#793921: Bug#793921: tftpd-hpa: IPv6 address cannonization breaks IPv4

Ron ron at debian.org
Fri Aug 7 22:04:55 PDT 2015


On Fri, Aug 07, 2015 at 11:52:49AM -0700, H. Peter Anvin wrote:
> >> 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 <hpa at zytor.com>
> >>>
> >>> 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 have applied the solution of canonicalizing all the addresses into git
> for now.  I would appreciate if someone could try to test it.
> 
> I ended up going for canonicalize everywhere because I found other
> places in the code which probably would fail to operate correctly on
> IPv6-mapped IPv4 addresses.

Thanks, that looks good to me by eye at least.  I'll push it out to
unstable to get some broader testing on it.

  Ron




More information about the Syslinux mailing list