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