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:
		| @@ -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; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Love Hörnquist Åstrand
					Love Hörnquist Åstrand