mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-10-21 11:39:39 +00:00
Change "limit" arg to make_local_answer() to a length.
This fixes an OOB write caused by bad pointer arithmetic calculating the pointer-to-end-of-packet used before. Thanks to Donghyeon Jeong for spotting the bug.
This commit is contained in:
3 files changed
+7
-6
No files matched your search
+1
-1
@@ -1966,7 +1966,7 @@ int lookup_domain(char *qdomain, int flags, int *lowout, int *highout);
|
||||
int filter_servers(int seed, int flags, int *lowout, int *highout);
|
||||
int is_local_answer(time_t now, int first, char *name);
|
||||
size_t make_local_answer(int flags, int gotname, size_t size, struct dns_header *header,
|
||||
char *name, char *limit, int first, int last, int ede);
|
||||
char *name, size_t limit, int first, int last, int ede);
|
||||
int server_samegroup(struct server *a, struct server *b);
|
||||
#ifdef HAVE_DNSSEC
|
||||
int dnssec_server(struct server *server, char *keyname, int is_ds, int *firstp, int *lastp);
|
||||
|
||||
+4
-3
@@ -408,12 +408,13 @@ int is_local_answer(time_t now, int first, char *name)
|
||||
return rc;
|
||||
}
|
||||
|
||||
size_t make_local_answer(int flags, int gotname, size_t size, struct dns_header *header, char *name, char *limit, int first, int last, int ede)
|
||||
size_t make_local_answer(int flags, int gotname, size_t size, struct dns_header *header, char *name, size_t limit, int first, int last, int ede)
|
||||
{
|
||||
int trunc = 0, anscount = 0;
|
||||
unsigned char *p;
|
||||
int start;
|
||||
union all_addr addr;
|
||||
char *out_end = ((char *)header) + limit;
|
||||
|
||||
setup_reply(header, flags, ede);
|
||||
|
||||
@@ -443,7 +444,7 @@ size_t make_local_answer(int flags, int gotname, size_t size, struct dns_header
|
||||
else
|
||||
addr.addr4 = srv->addr;
|
||||
|
||||
if (add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_A, C_IN, "4", &addr))
|
||||
if (add_resource_record(header, out_end, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_A, C_IN, "4", &addr))
|
||||
anscount++;
|
||||
log_query((flags | F_CONFIG | F_FORWARD) & ~F_IPV6, name, (union all_addr *)&addr, NULL, 0);
|
||||
}
|
||||
@@ -458,7 +459,7 @@ size_t make_local_answer(int flags, int gotname, size_t size, struct dns_header
|
||||
else
|
||||
addr.addr6 = srv->addr;
|
||||
|
||||
if (add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_AAAA, C_IN, "6", &addr))
|
||||
if (add_resource_record(header, out_end, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_AAAA, C_IN, "6", &addr))
|
||||
anscount++;
|
||||
log_query((flags | F_CONFIG | F_FORWARD) & ~F_IPV4, name, (union all_addr *)&addr, NULL, 0);
|
||||
}
|
||||
|
||||
+2
-2
@@ -589,7 +589,7 @@ static void forward_query(int udpfd, union mysockaddr *udpaddr,
|
||||
reply:
|
||||
if (udpfd != -1)
|
||||
{
|
||||
if (!(plen = make_local_answer(flags, gotname, plen, header, daemon->namebuff, (char *)(header + replylimit), first, last, ede)))
|
||||
if (!(plen = make_local_answer(flags, gotname, plen, header, daemon->namebuff, replylimit, first, last, ede)))
|
||||
return;
|
||||
|
||||
if (fwd_flags & FREC_HAS_PHEADER)
|
||||
@@ -2731,7 +2731,7 @@ void tcp_request(int confd, time_t now, struct iovec *bigbuff,
|
||||
if (m == 0)
|
||||
{
|
||||
if (!(m = make_local_answer(flags, gotname, size, out_header, daemon->namebuff,
|
||||
((char *) out_header) + 65536, first, last, ede)))
|
||||
65536, first, last, ede)))
|
||||
break;
|
||||
}
|
||||
else if (ede == EDE_UNSET)
|
||||
|
||||
Reference in new issue
Block a user