Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 685285 Details for
Bug 901555
CVE-2013-0198 dnsmasq: Incomplete fix for the CVE-2012-3411 issue [fedora-all]
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
Correct behaviour for TCP queries to allowed address via banned interface.
dnsmasq-2.65-Correct-behaviour-for-TCP-queries-to-allowed-address.patch (text/plain), 6.27 KB, created by
Tomáš Hozza
on 2013-01-22 16:36:46 UTC
(
hide
)
Description:
Correct behaviour for TCP queries to allowed address via banned interface.
Filename:
MIME Type:
Creator:
Tomáš Hozza
Created:
2013-01-22 16:36:46 UTC
Size:
6.27 KB
patch
obsolete
>diff -up dnsmasq-2.65/src/dnsmasq.c.CVE-2013-0198 dnsmasq-2.65/src/dnsmasq.c >--- dnsmasq-2.65/src/dnsmasq.c.CVE-2013-0198 2012-12-14 12:48:26.000000000 +0100 >+++ dnsmasq-2.65/src/dnsmasq.c 2013-01-22 16:32:30.387640907 +0100 >@@ -1384,7 +1384,7 @@ static void check_dns_listeners(fd_set * > > if (listener->tcpfd != -1 && FD_ISSET(listener->tcpfd, set)) > { >- int confd; >+ int confd, client_ok = 1; > struct irec *iface = NULL; > pid_t p; > union mysockaddr tcp_addr; >@@ -1395,25 +1395,49 @@ static void check_dns_listeners(fd_set * > if (confd == -1 || > getsockname(confd, (struct sockaddr *)&tcp_addr, &tcp_len) == -1) > continue; >- >- if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND)) >+ >+ if (option_bool(OPT_NOWILD)) > iface = listener->iface; /* May be NULL */ >- else >- { >- /* Check for allowed interfaces when binding the wildcard address: >- we do this by looking for an interface with the same address as >- the local address of the TCP connection, then looking to see if that's >- an allowed interface. As a side effect, we get the netmask of the >- interface too, for localisation. */ >- >- /* interface may be new since startup */ >- if (enumerate_interfaces()) >- for (iface = daemon->interfaces; iface; iface = iface->next) >- if (sockaddr_isequal(&iface->addr, &tcp_addr)) >- break; >- } >- >- if (!iface && !(option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND))) >+ else >+ { >+ int if_index; >+ >+ /* In full wildcard mode, need to refresh interface list. >+ This happens automagically in CLEVERBIND */ >+ if (!option_bool(OPT_CLEVERBIND)) >+ enumerate_interfaces(); >+ >+ /* if we can find the arrival interface, check it's one that's allowed */ >+ if ((if_index = tcp_interface(confd, tcp_addr.sa.sa_family)) != 0) >+ { >+ for (iface = daemon->interfaces; iface; iface = iface->next) >+ if (iface->index == if_index) >+ break; >+ >+ if (!iface) >+ client_ok = 0; >+ } >+ >+ if (option_bool(OPT_CLEVERBIND)) >+ iface = listener->iface; /* May be NULL */ >+ else >+ { >+ /* Check for allowed interfaces when binding the wildcard address: >+ we do this by looking for an interface with the same address as >+ the local address of the TCP connection, then looking to see if that's >+ an allowed interface. As a side effect, we get the netmask of the >+ interface too, for localisation. */ >+ >+ for (iface = daemon->interfaces; iface; iface = iface->next) >+ if (sockaddr_isequal(&iface->addr, &tcp_addr)) >+ break; >+ >+ if (!iface) >+ client_ok = 0; >+ } >+ } >+ >+ if (!client_ok) > { > shutdown(confd, SHUT_RDWR); > close(confd); >diff -up dnsmasq-2.65/src/dnsmasq.h.CVE-2013-0198 dnsmasq-2.65/src/dnsmasq.h >--- dnsmasq-2.65/src/dnsmasq.h.CVE-2013-0198 2012-12-14 12:48:26.000000000 +0100 >+++ dnsmasq-2.65/src/dnsmasq.h 2013-01-22 16:32:30.387640907 +0100 >@@ -412,7 +412,7 @@ struct server { > struct irec { > union mysockaddr addr; > struct in_addr netmask; /* only valid for IPv4 */ >- int tftp_ok, dhcp_ok, mtu, done, dad; >+ int tftp_ok, dhcp_ok, mtu, done, dad, index; > char *name; > struct irec *next; > }; >@@ -955,6 +955,7 @@ void create_bound_listeners(int die); > int is_dad_listeners(void); > int iface_check(int family, struct all_addr *addr, char *name); > int fix_fd(int fd); >+int tcp_interface(int fd, int af); > struct in_addr get_ifaddr(char *intr); > #ifdef HAVE_IPV6 > int set_ipv6pktinfo(int fd); >diff -up dnsmasq-2.65/src/network.c.CVE-2013-0198 dnsmasq-2.65/src/network.c >--- dnsmasq-2.65/src/network.c.CVE-2013-0198 2012-12-14 12:48:26.000000000 +0100 >+++ dnsmasq-2.65/src/network.c 2013-01-22 17:33:00.349128334 +0100 >@@ -239,6 +239,7 @@ static int iface_allowed(struct irec **i > iface->mtu = mtu; > iface->dad = dad; > iface->done = 0; >+ iface->index = if_index; > if ((iface->name = whine_malloc(strlen(ifr.ifr_name)+1))) > { > strcpy(iface->name, ifr.ifr_name); >@@ -420,6 +421,77 @@ int set_ipv6pktinfo(int fd) > return 0; > } > #endif >+ >+ >+/* Find the interface on which a TCP connection arrived, if possible, or zero otherwise. */ >+int tcp_interface(int fd, int af) >+{ >+ int if_index = 0; >+ >+#ifdef HAVE_LINUX_NETWORK >+ int opt = 1; >+ struct cmsghdr *cmptr; >+ struct msghdr msg; >+ >+ /* use mshdr do that the CMSDG_* macros are available */ >+ msg.msg_control = daemon->packet; >+ msg.msg_controllen = daemon->packet_buff_sz; >+ >+ /* we overwrote the buffer... */ >+ daemon->srv_save = NULL; >+ >+ if (af == AF_INET) >+ { >+ if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt)) != -1 && >+ getsockopt(fd, IPPROTO_IP, IP_PKTOPTIONS, msg.msg_control, (socklen_t *)&msg.msg_controllen) != -1) >+ for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr)) >+ if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO) >+ { >+ union { >+ unsigned char *c; >+ struct in_pktinfo *p; >+ } p; >+ >+ p.c = CMSG_DATA(cmptr); >+ if_index = p.p->ipi_ifindex; >+ } >+ } >+#ifdef HAVE_IPV6 >+ else >+ { >+ /* Only the RFC-2292 API has the ability to find the interface for TCP connections, >+ it was removed in RFC-3542 !!!! >+ >+ Fortunately, Linux kept the 2292 ABI when it moved to 3542. The following code always >+ uses the old ABI, and should work with pre- and post-3542 kernel headers */ >+ >+#ifdef IPV6_2292PKTOPTIONS >+# define PKTOPTIONS IPV6_2292PKTOPTIONS >+#else >+# define PKTOPTIONS IPV6_PKTOPTIONS >+#endif >+ >+ if (set_ipv6pktinfo(fd) && >+ getsockopt(fd, IPPROTO_IPV6, PKTOPTIONS, msg.msg_control, (socklen_t *)&msg.msg_controllen) != -1) >+ { >+ for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr)) >+ if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon->v6pktinfo) >+ { >+ union { >+ unsigned char *c; >+ struct in6_pktinfo *p; >+ } p; >+ p.c = CMSG_DATA(cmptr); >+ >+ if_index = p.p->ipi6_ifindex; >+ } >+ } >+ } >+#endif /* IPV6 */ >+#endif /* Linux */ >+ >+ return if_index; >+} > > static struct listener *create_listeners(union mysockaddr *addr, int do_tftp, int dienow) > {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 901555
: 685285