Commit fb762c4b authored by Pekka Pessi's avatar Pekka Pessi

Fixed error checking when decoding record in sresolv/sres.c.

darcs-hash:20060502131037-65a35-bffe0b3d7c8e9e1049e52e2845f3c792677bc1ed.gz
parent b6f16e3f
......@@ -2959,9 +2959,10 @@ static
sres_record_t *
sres_create_record(sres_resolver_t *res, sres_message_t *m)
{
sres_cache_t *cache = res->res_cache;
sres_record_t *rr = NULL;
uint16_t qtype, qclass, rdlen, size_old;
uint16_t qtype, qclass, rdlen, m_size;
uint32_t ttl;
char name[1024];
int name_length;
......@@ -2973,19 +2974,35 @@ sres_create_record(sres_resolver_t *res, sres_message_t *m)
ttl = m_get_uint32(m); /* TTL */
rdlen = m_get_uint16(m); /* rdlength */
if (m->m_error)
goto error;
SU_DEBUG_9(("rr received %.*s %s %s %d rdlen=%d\n", name_length, name,
sres_record_type(qtype, btype),
sres_record_class(qclass, bclass), ttl, rdlen));
if (m->m_error)
return NULL;
if (m->m_offset + rdlen > m->m_size) {
m->m_error = "truncated message";
goto error;
}
/* temporarily adjust m_size to check if the current rr is truncated */
size_old = m->m_size;
m_size = m->m_size;
/* limit m_size to indicated rdlen, check whether record is truncated */
m->m_size = m->m_offset + rdlen;
rr = sres_cache_alloc_record(res->res_cache, name, name_length, qtype, rdlen);
if (rr) switch(qtype) {
rr = sres_cache_alloc_record(cache, name, name_length, qtype, rdlen);
if (rr == NULL) {
m->m_error = "memory exhausted";
goto error;
}
/* Fill in the common fields */
rr->sr_type = qtype;
rr->sr_class = qclass;
rr->sr_ttl = ttl;
rr->sr_rdlen = rdlen;
switch(qtype) {
case sres_type_soa:
sres_init_rr_soa(res, rr->sr_soa, m);
break;
......@@ -3011,34 +3028,20 @@ sres_create_record(sres_resolver_t *res, sres_message_t *m)
sres_init_rr_naptr(res, rr->sr_naptr, m);
break;
default: /* copy the raw rdata to rr->r_data */
if (m->m_offset + rdlen > m->m_size) {
m->m_error = "truncated message";
} else {
memcpy(rr->sr_rdata, m->m_data + m->m_offset, rdlen);
m->m_offset += rdlen;
}
}
else
m->m_error = "memory exhausted";
if (m->m_error) {
SU_DEBUG_5(("sres_create_rr: %s\n", m->m_error));
su_free(res->res_home, rr);
return NULL;
memcpy(rr->sr_rdata, m->m_data + m->m_offset, rdlen);
m->m_offset += rdlen;
}
m->m_size = size_old;
m->m_size = m_size;
/* Fill in the common fields */
if (rr != NULL) {
rr->sr_name = su_strdup(res->res_home, name);
rr->sr_type = qtype;
rr->sr_class = qclass;
rr->sr_ttl = ttl;
rr->sr_rdlen = rdlen;
}
if (!m->m_error)
return rr;
return rr;
error:
if (rr)
su_free(res->res_home, rr);
SU_DEBUG_5(("%s: %s\n", "sres_create_record", m->m_error));
return NULL;
}
static void
......
......@@ -265,14 +265,15 @@ sres_cache_alloc_record(sres_cache_t *cache,
case sres_type_ptr: size = sizeof(sres_ptr_record_t); break;
case sres_type_srv: size = sizeof(sres_srv_record_t); break;
case sres_type_naptr: size = sizeof(sres_naptr_record_t); break;
default: size = sizeof(sres_common_t) + rdlen; break;
default: size = sizeof(sres_common_t) + rdlen + 1; break;
}
sr = su_zalloc(cache->cache_home, size + name_length + 1);
if (sr) {
sr->sr_size = size;
sr->sr_name = memcpy(size + (char *)sr, name, name_length + 1);
sr->sr_name = memcpy(size + (char *)sr, name, name_length);
sr->sr_name[name_length] = '\0';
}
return sr;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment