diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-05-22 17:41:01 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-05-22 17:41:01 +0000 |
commit | e9b76e1f1e37f91ec9b30274594b7953f1afa6a2 (patch) | |
tree | 5343576f8522de07b5ff92a91be17b538323b396 | |
parent | ae84b11467c56316a43de6146100ce22f24cf622 (diff) | |
download | busybox-w32-e9b76e1f1e37f91ec9b30274594b7953f1afa6a2.tar.gz busybox-w32-e9b76e1f1e37f91ec9b30274594b7953f1afa6a2.tar.bz2 busybox-w32-e9b76e1f1e37f91ec9b30274594b7953f1afa6a2.zip |
dnsd: fixes various segfaults.
One was a lib api change that was not updated and another
is a stack buffer overflow.
It also adds support for '*' in dnsd.conf. It resolves all hostnames to
a specific ip address. This is useful if you for example want redirect
all http traffic to your first-boot-web-wizard on you router/firewall.
By Timo Teras
-rw-r--r-- | libbb/udp_io.c | 17 | ||||
-rw-r--r-- | networking/dnsd.c | 8 |
2 files changed, 16 insertions, 9 deletions
diff --git a/libbb/udp_io.c b/libbb/udp_io.c index 689c39a82..c99e51643 100644 --- a/libbb/udp_io.c +++ b/libbb/udp_io.c | |||
@@ -36,11 +36,12 @@ send_to_from(int fd, void *buf, size_t len, int flags, | |||
36 | #else | 36 | #else |
37 | struct iovec iov[1]; | 37 | struct iovec iov[1]; |
38 | struct msghdr msg; | 38 | struct msghdr msg; |
39 | char cbuf[sizeof(struct in_pktinfo) | 39 | union { |
40 | char cmsg[CMSG_SPACE(sizeof(struct in_pktinfo))]; | ||
40 | #if ENABLE_FEATURE_IPV6 && defined(IPV6_PKTINFO) | 41 | #if ENABLE_FEATURE_IPV6 && defined(IPV6_PKTINFO) |
41 | | sizeof(struct in6_pktinfo) /* (a|b) is poor man's max(a,b) */ | 42 | char cmsg6[CMSG_SPACE(sizeof(struct in6_pktinfo))]; |
42 | #endif | 43 | #endif |
43 | ]; | 44 | } u; |
44 | struct cmsghdr* cmsgptr; | 45 | struct cmsghdr* cmsgptr; |
45 | 46 | ||
46 | if (from->sa_family != AF_INET | 47 | if (from->sa_family != AF_INET |
@@ -57,15 +58,15 @@ send_to_from(int fd, void *buf, size_t len, int flags, | |||
57 | iov[0].iov_base = buf; | 58 | iov[0].iov_base = buf; |
58 | iov[0].iov_len = len; | 59 | iov[0].iov_len = len; |
59 | 60 | ||
60 | memset(cbuf, 0, sizeof(cbuf)); | 61 | memset(&u, 0, sizeof(u)); |
61 | 62 | ||
62 | memset(&msg, 0, sizeof(msg)); | 63 | memset(&msg, 0, sizeof(msg)); |
63 | msg.msg_name = (void *)(struct sockaddr *)to; /* or compiler will annoy us */ | 64 | msg.msg_name = (void *)(struct sockaddr *)to; /* or compiler will annoy us */ |
64 | msg.msg_namelen = tolen; | 65 | msg.msg_namelen = tolen; |
65 | msg.msg_iov = iov; | 66 | msg.msg_iov = iov; |
66 | msg.msg_iovlen = 1; | 67 | msg.msg_iovlen = 1; |
67 | msg.msg_control = cbuf; | 68 | msg.msg_control = &u; |
68 | msg.msg_controllen = sizeof(cbuf); | 69 | msg.msg_controllen = sizeof(u); |
69 | msg.msg_flags = flags; | 70 | msg.msg_flags = flags; |
70 | 71 | ||
71 | cmsgptr = CMSG_FIRSTHDR(&msg); | 72 | cmsgptr = CMSG_FIRSTHDR(&msg); |
@@ -89,6 +90,8 @@ send_to_from(int fd, void *buf, size_t len, int flags, | |||
89 | pktptr->ipi6_addr = ((struct sockaddr_in6*)from)->sin6_addr; | 90 | pktptr->ipi6_addr = ((struct sockaddr_in6*)from)->sin6_addr; |
90 | } | 91 | } |
91 | #endif | 92 | #endif |
93 | msg.msg_controllen = cmsgptr->cmsg_len; | ||
94 | |||
92 | return sendmsg(fd, &msg, flags); | 95 | return sendmsg(fd, &msg, flags); |
93 | #endif | 96 | #endif |
94 | } | 97 | } |
@@ -109,7 +112,9 @@ recv_from_to(int fd, void *buf, size_t len, int flags, | |||
109 | struct iovec iov[1]; | 112 | struct iovec iov[1]; |
110 | union { | 113 | union { |
111 | char cmsg[CMSG_SPACE(sizeof(struct in_pktinfo))]; | 114 | char cmsg[CMSG_SPACE(sizeof(struct in_pktinfo))]; |
115 | #if ENABLE_FEATURE_IPV6 && defined(IPV6_PKTINFO) | ||
112 | char cmsg6[CMSG_SPACE(sizeof(struct in6_pktinfo))]; | 116 | char cmsg6[CMSG_SPACE(sizeof(struct in6_pktinfo))]; |
117 | #endif | ||
113 | } u; | 118 | } u; |
114 | struct cmsghdr *cmsgptr; | 119 | struct cmsghdr *cmsgptr; |
115 | struct msghdr msg; | 120 | struct msghdr msg; |
diff --git a/networking/dnsd.c b/networking/dnsd.c index cb62d2081..97ba2dc6a 100644 --- a/networking/dnsd.c +++ b/networking/dnsd.c | |||
@@ -194,7 +194,8 @@ static int table_lookup(uint16_t type, uint8_t * as, uint8_t * qs) | |||
194 | for (i = 1; i <= (int)(d->name[0]); i++) | 194 | for (i = 1; i <= (int)(d->name[0]); i++) |
195 | if (tolower(qs[i]) != d->name[i]) | 195 | if (tolower(qs[i]) != d->name[i]) |
196 | break; | 196 | break; |
197 | if (i > (int)(d->name[0])) { | 197 | if (i > (int)(d->name[0]) || |
198 | (d->name[0] == 1 && d->name[1] == '*')) { | ||
198 | strcpy((char *)as, d->ip); | 199 | strcpy((char *)as, d->ip); |
199 | #if DEBUG | 200 | #if DEBUG |
200 | fprintf(stderr, " OK as:%s\n", as); | 201 | fprintf(stderr, " OK as:%s\n", as); |
@@ -202,7 +203,8 @@ static int table_lookup(uint16_t type, uint8_t * as, uint8_t * qs) | |||
202 | return 0; | 203 | return 0; |
203 | } | 204 | } |
204 | } else if (type == REQ_PTR) { /* search by IP-address */ | 205 | } else if (type == REQ_PTR) { /* search by IP-address */ |
205 | if (!strncmp((char*)&d->rip[1], (char*)&qs[1], strlen(d->rip)-1)) { | 206 | if ((d->name[0] != 1 || d->name[1] != '*') && |
207 | !strncmp((char*)&d->rip[1], (char*)&qs[1], strlen(d->rip)-1)) { | ||
206 | strcpy((char *)as, d->name); | 208 | strcpy((char *)as, d->name); |
207 | return 0; | 209 | return 0; |
208 | } | 210 | } |
@@ -401,7 +403,7 @@ int dnsd_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
401 | r = process_packet(buf); | 403 | r = process_packet(buf); |
402 | if (r <= 0) | 404 | if (r <= 0) |
403 | continue; | 405 | continue; |
404 | send_to_from(udps, buf, r, 0, &to->u.sa, &from->u.sa, lsa->len); | 406 | send_to_from(udps, buf, r, 0, &from->u.sa, &to->u.sa, lsa->len); |
405 | } | 407 | } |
406 | return 0; | 408 | return 0; |
407 | } | 409 | } |