/[packages]/updates/1/dnsmasq/current/SOURCES/dnsmasq-2.65-redhat-real-fix-CVE-2013-0198.patch
ViewVC logotype

Contents of /updates/1/dnsmasq/current/SOURCES/dnsmasq-2.65-redhat-real-fix-CVE-2013-0198.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 394724 - (show annotations) (download)
Tue Feb 5 19:44:40 2013 UTC (7 years, 6 months ago) by luigiwalser
File size: 6145 byte(s)
add patch0 from redhat to fix CVE-2013-0198 (completes fix for CVE-2012-3411) (MGA#8795)
1 --- dnsmasq-2.65/src/dnsmasq.c 2012-12-14 12:48:26.000000000 +0100
2 +++ dnsmasq-2.65/src/dnsmasq.c 2013-01-22 16:32:30.387640907 +0100
3 @@ -1384,7 +1384,7 @@ static void check_dns_listeners(fd_set *
4
5 if (listener->tcpfd != -1 && FD_ISSET(listener->tcpfd, set))
6 {
7 - int confd;
8 + int confd, client_ok = 1;
9 struct irec *iface = NULL;
10 pid_t p;
11 union mysockaddr tcp_addr;
12 @@ -1395,25 +1395,49 @@ static void check_dns_listeners(fd_set *
13 if (confd == -1 ||
14 getsockname(confd, (struct sockaddr *)&tcp_addr, &tcp_len) == -1)
15 continue;
16 -
17 - if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND))
18 +
19 + if (option_bool(OPT_NOWILD))
20 iface = listener->iface; /* May be NULL */
21 - else
22 - {
23 - /* Check for allowed interfaces when binding the wildcard address:
24 - we do this by looking for an interface with the same address as
25 - the local address of the TCP connection, then looking to see if that's
26 - an allowed interface. As a side effect, we get the netmask of the
27 - interface too, for localisation. */
28 -
29 - /* interface may be new since startup */
30 - if (enumerate_interfaces())
31 - for (iface = daemon->interfaces; iface; iface = iface->next)
32 - if (sockaddr_isequal(&iface->addr, &tcp_addr))
33 - break;
34 - }
35 -
36 - if (!iface && !(option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND)))
37 + else
38 + {
39 + int if_index;
40 +
41 + /* In full wildcard mode, need to refresh interface list.
42 + This happens automagically in CLEVERBIND */
43 + if (!option_bool(OPT_CLEVERBIND))
44 + enumerate_interfaces();
45 +
46 + /* if we can find the arrival interface, check it's one that's allowed */
47 + if ((if_index = tcp_interface(confd, tcp_addr.sa.sa_family)) != 0)
48 + {
49 + for (iface = daemon->interfaces; iface; iface = iface->next)
50 + if (iface->index == if_index)
51 + break;
52 +
53 + if (!iface)
54 + client_ok = 0;
55 + }
56 +
57 + if (option_bool(OPT_CLEVERBIND))
58 + iface = listener->iface; /* May be NULL */
59 + else
60 + {
61 + /* Check for allowed interfaces when binding the wildcard address:
62 + we do this by looking for an interface with the same address as
63 + the local address of the TCP connection, then looking to see if that's
64 + an allowed interface. As a side effect, we get the netmask of the
65 + interface too, for localisation. */
66 +
67 + for (iface = daemon->interfaces; iface; iface = iface->next)
68 + if (sockaddr_isequal(&iface->addr, &tcp_addr))
69 + break;
70 +
71 + if (!iface)
72 + client_ok = 0;
73 + }
74 + }
75 +
76 + if (!client_ok)
77 {
78 shutdown(confd, SHUT_RDWR);
79 close(confd);
80 --- dnsmasq-2.65/src/dnsmasq.h 2012-12-14 12:48:26.000000000 +0100
81 +++ dnsmasq-2.65/src/dnsmasq.h 2013-01-22 16:32:30.387640907 +0100
82 @@ -412,7 +412,7 @@ struct server {
83 struct irec {
84 union mysockaddr addr;
85 struct in_addr netmask; /* only valid for IPv4 */
86 - int tftp_ok, dhcp_ok, mtu, done, dad;
87 + int tftp_ok, dhcp_ok, mtu, done, dad, index;
88 char *name;
89 struct irec *next;
90 };
91 @@ -955,6 +955,7 @@ void create_bound_listeners(int die);
92 int is_dad_listeners(void);
93 int iface_check(int family, struct all_addr *addr, char *name);
94 int fix_fd(int fd);
95 +int tcp_interface(int fd, int af);
96 struct in_addr get_ifaddr(char *intr);
97 #ifdef HAVE_IPV6
98 int set_ipv6pktinfo(int fd);
99 --- dnsmasq-2.65/src/network.c 2012-12-14 12:48:26.000000000 +0100
100 +++ dnsmasq-2.65/src/network.c 2013-01-22 17:33:00.349128334 +0100
101 @@ -239,6 +239,7 @@ static int iface_allowed(struct irec **i
102 iface->mtu = mtu;
103 iface->dad = dad;
104 iface->done = 0;
105 + iface->index = if_index;
106 if ((iface->name = whine_malloc(strlen(ifr.ifr_name)+1)))
107 {
108 strcpy(iface->name, ifr.ifr_name);
109 @@ -420,6 +421,77 @@ int set_ipv6pktinfo(int fd)
110 return 0;
111 }
112 #endif
113 +
114 +
115 +/* Find the interface on which a TCP connection arrived, if possible, or zero otherwise. */
116 +int tcp_interface(int fd, int af)
117 +{
118 + int if_index = 0;
119 +
120 +#ifdef HAVE_LINUX_NETWORK
121 + int opt = 1;
122 + struct cmsghdr *cmptr;
123 + struct msghdr msg;
124 +
125 + /* use mshdr do that the CMSDG_* macros are available */
126 + msg.msg_control = daemon->packet;
127 + msg.msg_controllen = daemon->packet_buff_sz;
128 +
129 + /* we overwrote the buffer... */
130 + daemon->srv_save = NULL;
131 +
132 + if (af == AF_INET)
133 + {
134 + if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt)) != -1 &&
135 + getsockopt(fd, IPPROTO_IP, IP_PKTOPTIONS, msg.msg_control, (socklen_t *)&msg.msg_controllen) != -1)
136 + for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
137 + if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
138 + {
139 + union {
140 + unsigned char *c;
141 + struct in_pktinfo *p;
142 + } p;
143 +
144 + p.c = CMSG_DATA(cmptr);
145 + if_index = p.p->ipi_ifindex;
146 + }
147 + }
148 +#ifdef HAVE_IPV6
149 + else
150 + {
151 + /* Only the RFC-2292 API has the ability to find the interface for TCP connections,
152 + it was removed in RFC-3542 !!!!
153 +
154 + Fortunately, Linux kept the 2292 ABI when it moved to 3542. The following code always
155 + uses the old ABI, and should work with pre- and post-3542 kernel headers */
156 +
157 +#ifdef IPV6_2292PKTOPTIONS
158 +# define PKTOPTIONS IPV6_2292PKTOPTIONS
159 +#else
160 +# define PKTOPTIONS IPV6_PKTOPTIONS
161 +#endif
162 +
163 + if (set_ipv6pktinfo(fd) &&
164 + getsockopt(fd, IPPROTO_IPV6, PKTOPTIONS, msg.msg_control, (socklen_t *)&msg.msg_controllen) != -1)
165 + {
166 + for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
167 + if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon->v6pktinfo)
168 + {
169 + union {
170 + unsigned char *c;
171 + struct in6_pktinfo *p;
172 + } p;
173 + p.c = CMSG_DATA(cmptr);
174 +
175 + if_index = p.p->ipi6_ifindex;
176 + }
177 + }
178 + }
179 +#endif /* IPV6 */
180 +#endif /* Linux */
181 +
182 + return if_index;
183 +}
184
185 static struct listener *create_listeners(union mysockaddr *addr, int do_tftp, int dienow)
186 {

  ViewVC Help
Powered by ViewVC 1.1.28