mirror of
git://git.musl-libc.org/musl
synced 2025-03-06 20:48:29 +01:00
prevent CNAME/PTR parsing from reading data past the response end
DNS parsing callbacks pass the response buffer end instead of the actual response end to dn_expand, so a malformed DNS response can use message compression to make dn_expand jump past the response end and attempt to parse uninitialized parts of that buffer, which might succeed and return garbage.
This commit is contained in:
parent
12590c8bbd
commit
9b132e5567
4 changed files with 7 additions and 7 deletions
|
@ -1,7 +1,7 @@
|
|||
#include <string.h>
|
||||
#include "lookup.h"
|
||||
|
||||
int __dns_parse(const unsigned char *r, int rlen, int (*callback)(void *, int, const void *, int, const void *), void *ctx)
|
||||
int __dns_parse(const unsigned char *r, int rlen, int (*callback)(void *, int, const void *, int, const void *, int), void *ctx)
|
||||
{
|
||||
int qdcount, ancount;
|
||||
const unsigned char *p;
|
||||
|
@ -26,7 +26,7 @@ int __dns_parse(const unsigned char *r, int rlen, int (*callback)(void *, int, c
|
|||
p += 1 + !!*p;
|
||||
len = p[8]*256 + p[9];
|
||||
if (len+10 > r+rlen-p) return -1;
|
||||
if (callback(ctx, p[1], p+10, len, r) < 0) return -1;
|
||||
if (callback(ctx, p[1], p+10, len, r, rlen) < 0) return -1;
|
||||
p += 10 + len;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -108,10 +108,10 @@ static void reverse_services(char *buf, int port, int dgram)
|
|||
__fclose_ca(f);
|
||||
}
|
||||
|
||||
static int dns_parse_callback(void *c, int rr, const void *data, int len, const void *packet)
|
||||
static int dns_parse_callback(void *c, int rr, const void *data, int len, const void *packet, int plen)
|
||||
{
|
||||
if (rr != RR_PTR) return 0;
|
||||
if (__dn_expand(packet, (const unsigned char *)packet + 512,
|
||||
if (__dn_expand(packet, (const unsigned char *)packet + plen,
|
||||
data, c, 256) <= 0)
|
||||
*(char *)c = 0;
|
||||
return 0;
|
||||
|
|
|
@ -50,6 +50,6 @@ hidden int __lookup_ipliteral(struct address buf[static 1], const char *name, in
|
|||
hidden int __get_resolv_conf(struct resolvconf *, char *, size_t);
|
||||
hidden int __res_msend_rc(int, const unsigned char *const *, const int *, unsigned char *const *, int *, int, const struct resolvconf *);
|
||||
|
||||
hidden int __dns_parse(const unsigned char *, int, int (*)(void *, int, const void *, int, const void *), void *);
|
||||
hidden int __dns_parse(const unsigned char *, int, int (*)(void *, int, const void *, int, const void *, int), void *);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -111,13 +111,13 @@ struct dpc_ctx {
|
|||
|
||||
#define ABUF_SIZE 768
|
||||
|
||||
static int dns_parse_callback(void *c, int rr, const void *data, int len, const void *packet)
|
||||
static int dns_parse_callback(void *c, int rr, const void *data, int len, const void *packet, int plen)
|
||||
{
|
||||
char tmp[256];
|
||||
int family;
|
||||
struct dpc_ctx *ctx = c;
|
||||
if (rr == RR_CNAME) {
|
||||
if (__dn_expand(packet, (const unsigned char *)packet + ABUF_SIZE,
|
||||
if (__dn_expand(packet, (const unsigned char *)packet + plen,
|
||||
data, tmp, sizeof tmp) > 0 && is_valid_hostname(tmp))
|
||||
strcpy(ctx->canon, tmp);
|
||||
return 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue