Ron
2015-Jul-29 08:45 UTC
[syslinux] Bug#793921: tftpd-hpa: IPv6 address cannonization breaks IPv4
Take 2 at bouncing this to the rest of the original recipients through a different MTA, since mail.zytor.com refused to accept it the first time. Please re-add Jason Gunthorpe <jgg at obsidianresearch.com> and 793921 at bugs.debian.org to the CC for replies. On Wed, Jul 29, 2015 at 05:34:00PM +0930, Ron wrote:> > 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 <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 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
H. Peter Anvin
2015-Aug-07 18:52 UTC
[syslinux] Bug#793921: tftpd-hpa: IPv6 address cannonization breaks IPv4
On 07/29/2015 01:45 AM, Ron via Syslinux wrote:> > Take 2 at bouncing this to the rest of the original recipients through a > different MTA, since mail.zytor.com refused to accept it the first time. > > Please re-add Jason Gunthorpe <jgg at obsidianresearch.com> and > 793921 at bugs.debian.org to the CC for replies. > > > On Wed, Jul 29, 2015 at 05:34:00PM +0930, Ron wrote: >> >> 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 <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. -hpa
Ron
2015-Aug-08 05:04 UTC
[syslinux] Bug#793921: Bug#793921: tftpd-hpa: IPv6 address cannonization breaks IPv4
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