Hello community, here is the log from the commit of package tftp for openSUSE:Factory checked in at 2015-09-24 07:17:49 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/tftp (Old) and /work/SRC/openSUSE:Factory/.tftp.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "tftp" Changes: -------- --- /work/SRC/openSUSE:Factory/tftp/tftp.changes 2014-03-31 20:43:04.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.tftp.new/tftp.changes 2015-09-24 07:17:50.000000000 +0200 @@ -1,0 +2,17 @@ +Fri Sep 18 13:23:21 UTC 2015 - vci...@suse.com + +- respond from the destination address taken from the first udp + message's ancillary data (bnc#928283) + * added tftp-multi-addresses.patch + +------------------------------------------------------------------- +Fri Sep 18 13:22:12 UTC 2015 - vci...@suse.com + +- tftp-hpa-0.48-macros-crash.patch: + prevent buffer overflow in handling of \x macro (bnc#793883) +- tftp-hpa-0.48-macros-v6mapped.patch: + for \i and \x, expand v6-mapped addresses as native IPv4 + (bnc#793883) +- patches come from Michal Kubecek + +------------------------------------------------------------------- New: ---- tftp-hpa-0.48-macros-crash.patch tftp-hpa-0.48-macros-v6mapped.patch tftp-multi-addresses.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ tftp.spec ++++++ --- /var/tmp/diff_new_pack.NDnMhh/_old 2015-09-24 07:17:51.000000000 +0200 +++ /var/tmp/diff_new_pack.NDnMhh/_new 2015-09-24 07:17:51.000000000 +0200 @@ -1,7 +1,7 @@ # # spec file for package tftp # -# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -35,6 +35,9 @@ Patch4: tftp-hpa-0.49-fortify-strcpy-crash.patch Patch5: tftp-hpa-0.48-tzfix.patch Patch43: tftp-config_h.patch +Patch6: tftp-multi-addresses.patch +Patch7: tftp-hpa-0.48-macros-crash.patch +Patch8: tftp-hpa-0.48-macros-v6mapped.patch Provides: tftp(client) Provides: tftp(server) PreReq: pwdutils @@ -62,6 +65,9 @@ %patch1 %patch4 -p1 %patch5 -p1 +%patch6 -p1 +%patch7 +%patch8 %if 0%{?suse_version} < 1030 %patch42 %endif ++++++ tftp-hpa-0.48-macros-crash.patch ++++++ diff -up tftpd/tftpd.c.orig-len tftpd/tftpd.c --- tftpd/tftpd.c.orig-len 2012-12-11 16:31:29.658043427 +0100 +++ tftpd/tftpd.c 2012-12-11 16:32:22.234018253 +0100 @@ -1287,24 +1287,24 @@ static int rewrite_macros(char macro, ch return strlen(p); case 'x': - if (output) { - if (from.sa.sa_family == AF_INET) { + if (from.sa.sa_family == AF_INET) { + if (output) sprintf(output, "%08lX", (unsigned long)ntohl(from.si.sin_addr.s_addr)); - l = 8; + l = 8; #ifdef HAVE_IPV6 - } else { - unsigned char *c = (unsigned char *)SOCKADDR_P(&from); - p = tb; - for (l = 0; l < 16; l++) { - sprintf(p, "%02X", *c); - c++; - p += 2; - } + } else { + unsigned char *c = (unsigned char *)SOCKADDR_P(&from); + p = tb; + for (l = 0; l < 16; l++) { + sprintf(p, "%02X", *c); + c++; + p += 2; + } + if (output) strcpy(output, tb); - l = strlen(tb); + l = strlen(tb); #endif - } } return l; ++++++ tftp-hpa-0.48-macros-v6mapped.patch ++++++ diff -up tftpd/tftpd.c.orig-v6map tftpd/tftpd.c --- tftpd/tftpd.c.orig-v6map 2012-12-11 17:06:53.156624476 +0100 +++ tftpd/tftpd.c 2012-12-11 17:13:08.705298341 +0100 @@ -1263,6 +1263,21 @@ static void do_opt(const char *opt, cons #ifdef WITH_REGEX +#ifdef HAVE_IPV6 +static inline int is_v6_mapped(const union sock_addr* pa) +{ + const char v6_mapped[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF }; + + if (from.sa.sa_family != AF_INET6) + return 0; + if (memcmp(&pa->s6.sin6_addr.s6_addr, v6_mapped, sizeof(v6_mapped))) + return 0; + + return 1; +} +#endif + /* * This is called by the remap engine when it encounters macros such * as \i. It should write the output in "output" if non-NULL, and @@ -1274,10 +1289,20 @@ static int rewrite_macros(char macro, ch { char *p, tb[INET6_ADDRSTRLEN]; int l=0; + const union sock_addr *pfrom = &from; + +#ifdef HAVE_IPV6 + union sock_addr ipv4_from; + if (is_v6_mapped(&from)) { + ipv4_from.si.sin_family = AF_INET; + memcpy(&ipv4_from.si.sin_addr, from.s6.sin6_addr.s6_addr + 12, 4); + pfrom = &ipv4_from; + } +#endif switch (macro) { case 'i': - p = (char *)inet_ntop(from.sa.sa_family, SOCKADDR_P(&from), + p = (char *)inet_ntop(pfrom->sa.sa_family, SOCKADDR_P(pfrom), tb, INET6_ADDRSTRLEN); if (output && p) strcpy(output, p); @@ -1287,14 +1312,14 @@ static int rewrite_macros(char macro, ch return strlen(p); case 'x': - if (from.sa.sa_family == AF_INET) { + if (pfrom->sa.sa_family == AF_INET) { if (output) sprintf(output, "%08lX", - (unsigned long)ntohl(from.si.sin_addr.s_addr)); + (unsigned long)ntohl(pfrom->si.sin_addr.s_addr)); l = 8; #ifdef HAVE_IPV6 } else { - unsigned char *c = (unsigned char *)SOCKADDR_P(&from); + unsigned char *c = (unsigned char *)SOCKADDR_P(pfrom); p = tb; for (l = 0; l < 16; l++) { sprintf(p, "%02X", *c); ++++++ tftp-multi-addresses.patch ++++++ Index: tftp-hpa-5.2/tftpd/recvfrom.c =================================================================== --- tftp-hpa-5.2.orig/tftpd/recvfrom.c 2015-04-30 11:04:45.994568260 +0200 +++ tftp-hpa-5.2/tftpd/recvfrom.c 2015-05-14 16:02:28.104576816 +0200 @@ -148,17 +148,17 @@ myrecvfrom(int s, void *buf, int len, un #endif /* Try to enable getting the return address */ + /* Before the first packet we don't know the address family of the + * connection, so we set both ipv4 and ipv6 socket options + */ #ifdef IP_RECVDSTADDR - if (from->sa_family == AF_INET) setsockopt(s, IPPROTO_IP, IP_RECVDSTADDR, &on, sizeof(on)); #endif #ifdef IP_PKTINFO - if (from->sa_family == AF_INET) setsockopt(s, IPPROTO_IP, IP_PKTINFO, &on, sizeof(on)); #endif #ifdef HAVE_IPV6 #ifdef IPV6_RECVPKTINFO - if (from->sa_family == AF_INET6) setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on)); #endif #endif @@ -190,7 +190,7 @@ myrecvfrom(int s, void *buf, int len, un for (cmptr = CMSG_FIRSTHDR(&msg); cmptr != NULL; cmptr = CMSG_NXTHDR(&msg, cmptr)) { - if (from->sa_family == AF_INET) { + if (cmptr->cmsg_level == IPPROTO_IP) { myaddr->sa.sa_family = AF_INET; #ifdef IP_RECVDSTADDR if (cmptr->cmsg_level == IPPROTO_IP && @@ -209,15 +209,26 @@ myrecvfrom(int s, void *buf, int len, un sizeof(struct in_addr)); } #endif + if (from->sa_family == AF_INET6) { + from->sa_family = AF_INET; + /* Unmap the ipv4 address from ipv6. + * The ipv6 mapped address is in format: + * 10 0x0 bytes, 2 0xff bytes, 4 bytes of the ipv4 address + * so we cut out the first 12 bytes of the ipv6 and + * interpret the rest as the ipv4 + */ + ((struct sockaddr_in *)from)->sin_addr = *((struct in_addr *)(((struct sockaddr_in6 *)from)->sin6_addr.s6_addr+12)); + } } #ifdef HAVE_IPV6 - else if (from->sa_family == AF_INET6) { + else if (cmptr->cmsg_level == IPPROTO_IPV6) { myaddr->sa.sa_family = AF_INET6; #ifdef IP6_RECVDSTADDR if (cmptr->cmsg_level == IPPROTO_IPV6 && - cmptr->cmsg_type == IPV6_RECVDSTADDR ) + cmptr->cmsg_type == IPV6_RECVDSTADDR ) { memcpy(&myaddr->s6.sin6_addr, CMSG_DATA(cmptr), sizeof(struct in6_addr)); + } #endif #ifdef HAVE_STRUCT_IN6_PKTINFO