Plug memory leak found by IBM checker (and try to please it).

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@16923 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Love Hörnquist Åstrand
2006-04-02 00:01:55 +00:00
parent 2b6c24ce1a
commit 16a5f30931

View File

@@ -99,6 +99,16 @@ dns_type_to_string(int type)
#if (defined(HAVE_RES_SEARCH) || defined(HAVE_RES_NSEARCH)) && defined(HAVE_DN_EXPAND)
static void
dns_free_rr(struct resource_record *rr)
{
if(rr->domain)
free(rr->domain);
if(rr->u.data)
free(rr->u.data);
free(rr);
}
void ROKEN_LIB_FUNCTION
dns_free_data(struct dns_reply *r)
{
@@ -107,29 +117,30 @@ dns_free_data(struct dns_reply *r)
free(r->q.domain);
for(rr = r->head; rr;){
struct resource_record *tmp = rr;
if(rr->domain)
free(rr->domain);
if(rr->u.data)
free(rr->u.data);
rr = rr->next;
free(tmp);
dns_free_rr(tmp);
}
free (r);
}
static int
parse_record(const unsigned char *data, const unsigned char *end_data,
const unsigned char **pp, struct resource_record **rr)
const unsigned char **pp, struct resource_record **ret_rr)
{
struct resource_record *rr;
int type, class, ttl, size;
int status;
char host[MAXDNAME];
const unsigned char *p = *pp;
*ret_rr = NULL;
status = dn_expand(data, end_data, p, host, sizeof(host));
if(status < 0)
return -1;
if (p + status + 10 > end_data)
return -1;
p += status;
type = (p[0] << 8) | p[1];
p += 2;
@@ -143,30 +154,30 @@ parse_record(const unsigned char *data, const unsigned char *end_data,
if (p + size > end_data)
return -1;
*rr = calloc(1, sizeof(**rr));
if(*rr == NULL)
rr = calloc(1, sizeof(*rr));
if(rr == NULL)
return -1;
(*rr)->domain = strdup(host);
if((*rr)->domain == NULL) {
free(*rr);
rr->domain = strdup(host);
if(rr->domain == NULL) {
dns_free_rr(rr);
return -1;
}
(*rr)->type = type;
(*rr)->class = class;
(*rr)->ttl = ttl;
(*rr)->size = size;
rr->type = type;
rr->class = class;
rr->ttl = ttl;
rr->size = size;
switch(type){
case rk_ns_t_ns:
case rk_ns_t_cname:
case rk_ns_t_ptr:
status = dn_expand(data, end_data, p, host, sizeof(host));
if(status < 0) {
free(*rr);
dns_free_rr(rr);
return -1;
}
(*rr)->u.txt = strdup(host);
if((*rr)->u.txt == NULL) {
free(*rr);
rr->u.txt = strdup(host);
if(rr->u.txt == NULL) {
dns_free_rr(rr);
return -1;
}
break;
@@ -176,101 +187,101 @@ parse_record(const unsigned char *data, const unsigned char *end_data,
status = dn_expand(data, end_data, p + 2, host, sizeof(host));
if(status < 0){
free(*rr);
dns_free_rr(rr);
return -1;
}
if (status + 2 > size) {
free(*rr);
dns_free_rr(rr);
return -1;
}
hostlen = strlen(host);
(*rr)->u.mx = (struct mx_record*)malloc(sizeof(struct mx_record) +
rr->u.mx = (struct mx_record*)malloc(sizeof(struct mx_record) +
hostlen);
if((*rr)->u.mx == NULL) {
free(*rr);
if(rr->u.mx == NULL) {
dns_free_rr(rr);
return -1;
}
(*rr)->u.mx->preference = (p[0] << 8) | p[1];
strlcpy((*rr)->u.mx->domain, host, hostlen + 1);
rr->u.mx->preference = (p[0] << 8) | p[1];
strlcpy(rr->u.mx->domain, host, hostlen + 1);
break;
}
case rk_ns_t_srv:{
size_t hostlen;
status = dn_expand(data, end_data, p + 6, host, sizeof(host));
if(status < 0){
free(*rr);
dns_free_rr(rr);
return -1;
}
if (status + 6 > size) {
free(*rr);
dns_free_rr(rr);
return -1;
}
hostlen = strlen(host);
(*rr)->u.srv =
rr->u.srv =
(struct srv_record*)malloc(sizeof(struct srv_record) +
hostlen);
if((*rr)->u.srv == NULL) {
free(*rr);
if(rr->u.srv == NULL) {
dns_free_rr(rr);
return -1;
}
(*rr)->u.srv->priority = (p[0] << 8) | p[1];
(*rr)->u.srv->weight = (p[2] << 8) | p[3];
(*rr)->u.srv->port = (p[4] << 8) | p[5];
strlcpy((*rr)->u.srv->target, host, hostlen + 1);
rr->u.srv->priority = (p[0] << 8) | p[1];
rr->u.srv->weight = (p[2] << 8) | p[3];
rr->u.srv->port = (p[4] << 8) | p[5];
strlcpy(rr->u.srv->target, host, hostlen + 1);
break;
}
case rk_ns_t_txt:{
if(size == 0 || size < *p + 1) {
free(*rr);
dns_free_rr(rr);
return -1;
}
(*rr)->u.txt = (char*)malloc(*p + 1);
if((*rr)->u.txt == NULL) {
free(*rr);
rr->u.txt = (char*)malloc(*p + 1);
if(rr->u.txt == NULL) {
dns_free_rr(rr);
return -1;
}
strncpy((*rr)->u.txt, (const char*)(p + 1), *p);
(*rr)->u.txt[*p] = '\0';
strncpy(rr->u.txt, (const char*)(p + 1), *p);
rr->u.txt[*p] = '\0';
break;
}
case rk_ns_t_key : {
size_t key_len;
if (size < 4) {
free(*rr);
dns_free_rr(rr);
return -1;
}
key_len = size - 4;
(*rr)->u.key = malloc (sizeof(*(*rr)->u.key) + key_len - 1);
if ((*rr)->u.key == NULL) {
free(*rr);
rr->u.key = malloc (sizeof(*rr->u.key) + key_len - 1);
if (rr->u.key == NULL) {
dns_free_rr(rr);
return -1;
}
(*rr)->u.key->flags = (p[0] << 8) | p[1];
(*rr)->u.key->protocol = p[2];
(*rr)->u.key->algorithm = p[3];
(*rr)->u.key->key_len = key_len;
memcpy ((*rr)->u.key->key_data, p + 4, key_len);
rr->u.key->flags = (p[0] << 8) | p[1];
rr->u.key->protocol = p[2];
rr->u.key->algorithm = p[3];
rr->u.key->key_len = key_len;
memcpy (rr->u.key->key_data, p + 4, key_len);
break;
}
case rk_ns_t_sig : {
size_t sig_len, hostlen;
if(size <= 18) {
free(*rr);
dns_free_rr(rr);
return -1;
}
status = dn_expand (data, end_data, p + 18, host, sizeof(host));
if (status < 0) {
free(*rr);
dns_free_rr(rr);
return -1;
}
if (status + 18 > size) {
free(*rr);
dns_free_rr(rr);
return -1;
}
@@ -281,26 +292,26 @@ parse_record(const unsigned char *data, const unsigned char *end_data,
*/
sig_len = size - 18 - status;
hostlen = strlen(host);
(*rr)->u.sig = malloc(sizeof(*(*rr)->u.sig)
rr->u.sig = malloc(sizeof(*rr->u.sig)
+ hostlen + sig_len);
if ((*rr)->u.sig == NULL) {
free(*rr);
if (rr->u.sig == NULL) {
dns_free_rr(rr);
return -1;
}
(*rr)->u.sig->type = (p[0] << 8) | p[1];
(*rr)->u.sig->algorithm = p[2];
(*rr)->u.sig->labels = p[3];
(*rr)->u.sig->orig_ttl = (p[4] << 24) | (p[5] << 16)
rr->u.sig->type = (p[0] << 8) | p[1];
rr->u.sig->algorithm = p[2];
rr->u.sig->labels = p[3];
rr->u.sig->orig_ttl = (p[4] << 24) | (p[5] << 16)
| (p[6] << 8) | p[7];
(*rr)->u.sig->sig_expiration = (p[8] << 24) | (p[9] << 16)
rr->u.sig->sig_expiration = (p[8] << 24) | (p[9] << 16)
| (p[10] << 8) | p[11];
(*rr)->u.sig->sig_inception = (p[12] << 24) | (p[13] << 16)
rr->u.sig->sig_inception = (p[12] << 24) | (p[13] << 16)
| (p[14] << 8) | p[15];
(*rr)->u.sig->key_tag = (p[16] << 8) | p[17];
(*rr)->u.sig->sig_len = sig_len;
memcpy ((*rr)->u.sig->sig_data, p + 18 + status, sig_len);
(*rr)->u.sig->signer = &(*rr)->u.sig->sig_data[sig_len];
strlcpy((*rr)->u.sig->signer, host, hostlen + 1);
rr->u.sig->key_tag = (p[16] << 8) | p[17];
rr->u.sig->sig_len = sig_len;
memcpy (rr->u.sig->sig_data, p + 18 + status, sig_len);
rr->u.sig->signer = &rr->u.sig->sig_data[sig_len];
strlcpy(rr->u.sig->signer, host, hostlen + 1);
break;
}
@@ -308,78 +319,81 @@ parse_record(const unsigned char *data, const unsigned char *end_data,
size_t cert_len;
if (size < 5) {
free(*rr);
dns_free_rr(rr);
return -1;
}
cert_len = size - 5;
(*rr)->u.cert = malloc (sizeof(*(*rr)->u.cert) + cert_len - 1);
if ((*rr)->u.cert == NULL) {
free(*rr);
rr->u.cert = malloc (sizeof(*rr->u.cert) + cert_len - 1);
if (rr->u.cert == NULL) {
dns_free_rr(rr);
return -1;
}
(*rr)->u.cert->type = (p[0] << 8) | p[1];
(*rr)->u.cert->tag = (p[2] << 8) | p[3];
(*rr)->u.cert->algorithm = p[4];
(*rr)->u.cert->cert_len = cert_len;
memcpy ((*rr)->u.cert->cert_data, p + 5, cert_len);
rr->u.cert->type = (p[0] << 8) | p[1];
rr->u.cert->tag = (p[2] << 8) | p[3];
rr->u.cert->algorithm = p[4];
rr->u.cert->cert_len = cert_len;
memcpy (rr->u.cert->cert_data, p + 5, cert_len);
break;
}
case rk_ns_t_sshfp : {
size_t sshfp_len;
if (size < 2) {
free(*rr);
dns_free_rr(rr);
return -1;
}
sshfp_len = size - 2;
(*rr)->u.sshfp = malloc (sizeof(*(*rr)->u.sshfp) + sshfp_len - 1);
if ((*rr)->u.sshfp == NULL) {
free(*rr);
rr->u.sshfp = malloc (sizeof(*rr->u.sshfp) + sshfp_len - 1);
if (rr->u.sshfp == NULL) {
dns_free_rr(rr);
return -1;
}
(*rr)->u.sshfp->algorithm = p[0];
(*rr)->u.sshfp->type = p[1];
(*rr)->u.sshfp->sshfp_len = sshfp_len;
memcpy ((*rr)->u.sshfp->sshfp_data, p + 2, sshfp_len);
rr->u.sshfp->algorithm = p[0];
rr->u.sshfp->type = p[1];
rr->u.sshfp->sshfp_len = sshfp_len;
memcpy (rr->u.sshfp->sshfp_data, p + 2, sshfp_len);
break;
}
case rk_ns_t_ds: {
size_t digest_len;
if (size < 4) {
free(*rr);
dns_free_rr(rr);
return -1;
}
digest_len = size - 4;
(*rr)->u.ds = malloc (sizeof(*(*rr)->u.ds) + digest_len - 1);
if ((*rr)->u.ds == NULL) {
free(*rr);
rr->u.ds = malloc (sizeof(*rr->u.ds) + digest_len - 1);
if (rr->u.ds == NULL) {
dns_free_rr(rr);
return -1;
}
(*rr)->u.ds->key_tag = (p[0] << 8) | p[1];
(*rr)->u.ds->algorithm = p[2];
(*rr)->u.ds->digest_type = p[3];
(*rr)->u.ds->digest_len = digest_len;
memcpy ((*rr)->u.ds->digest_data, p + 4, digest_len);
rr->u.ds->key_tag = (p[0] << 8) | p[1];
rr->u.ds->algorithm = p[2];
rr->u.ds->digest_type = p[3];
rr->u.ds->digest_len = digest_len;
memcpy (rr->u.ds->digest_data, p + 4, digest_len);
break;
}
default:
(*rr)->u.data = (unsigned char*)malloc(size);
if(size != 0 && (*rr)->u.data == NULL) {
free(*rr);
rr->u.data = (unsigned char*)malloc(size);
if(size != 0 && rr->u.data == NULL) {
dns_free_rr(rr);
return -1;
}
memcpy((*rr)->u.data, p, size);
if (size)
memcpy(rr->u.data, p, size);
}
*pp = p + size;
*ret_rr = rr;
return 0;
}