- (djm) [openbsd-compat/getrrsetbyname.c] Sync to latest OpenBSD version,

resolving memory leak bz#1111 reported by kremenek AT cs.stanford.edu;
   ok dtucker@
This commit is contained in:
Damien Miller 2005-11-05 16:56:52 +11:00
parent 3a38c5a856
commit 9b59ada7ca
2 changed files with 66 additions and 51 deletions

View File

@ -103,6 +103,9 @@
Fix leaks in error paths, bz #1109 and #1110 reported by kremenek AT
cs.stanford.edu; ok dtucker@
- (dtucker) [README.platform] Add PAM section.
- (djm) [openbsd-compat/getrrsetbyname.c] Sync to latest OpenBSD version,
resolving memory leak bz#1111 reported by kremenek AT cs.stanford.edu;
ok dtucker@
20051102
- (dtucker) [openbsd-compat/bsd-misc.c] Bug #1108: fix broken strdup().
@ -3236,4 +3239,4 @@
- (djm) Trim deprecated options from INSTALL. Mention UsePAM
- (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu
$Id: ChangeLog,v 1.3953 2005/11/05 05:28:35 dtucker Exp $
$Id: ChangeLog,v 1.3954 2005/11/05 05:56:52 djm Exp $

View File

@ -1,6 +1,6 @@
/* OPENBSD ORIGINAL: lib/libc/net/getrrsetbyname.c */
/* $OpenBSD: getrrsetbyname.c,v 1.7 2003/03/07 07:34:14 itojun Exp $ */
/* $OpenBSD: getrrsetbyname.c,v 1.10 2005/03/30 02:58:28 tedu Exp $ */
/*
* Copyright (c) 2001 Jakob Schlyter. All rights reserved.
@ -51,48 +51,18 @@
#include "getrrsetbyname.h"
#define ANSWER_BUFFER_SIZE 1024*64
#if defined(HAVE_DECL_H_ERRNO) && !HAVE_DECL_H_ERRNO
extern int h_errno;
#endif
struct dns_query {
char *name;
u_int16_t type;
u_int16_t class;
struct dns_query *next;
};
/* We don't need multithread support here */
#ifdef _THREAD_PRIVATE
# undef _THREAD_PRIVATE
#endif
#define _THREAD_PRIVATE(a,b,c) (c)
struct __res_state _res;
struct dns_rr {
char *name;
u_int16_t type;
u_int16_t class;
u_int16_t ttl;
u_int16_t size;
void *rdata;
struct dns_rr *next;
};
struct dns_response {
HEADER header;
struct dns_query *query;
struct dns_rr *answer;
struct dns_rr *authority;
struct dns_rr *additional;
};
static struct dns_response *parse_dns_response(const u_char *, int);
static struct dns_query *parse_dns_qsection(const u_char *, int,
const u_char **, int);
static struct dns_rr *parse_dns_rrsection(const u_char *, int, const u_char **,
int);
static void free_dns_query(struct dns_query *);
static void free_dns_rr(struct dns_rr *);
static void free_dns_response(struct dns_response *);
static int count_dns_rr(struct dns_rr *, u_int16_t, u_int16_t);
/* Necessary functions and macros */
/*
* Inline versions of get/put short/long. Pointer is advanced.
@ -162,14 +132,56 @@ _getlong(msgp)
u_int32_t _getlong(register const u_char *);
#endif
/* ************** */
#define ANSWER_BUFFER_SIZE 1024*64
struct dns_query {
char *name;
u_int16_t type;
u_int16_t class;
struct dns_query *next;
};
struct dns_rr {
char *name;
u_int16_t type;
u_int16_t class;
u_int16_t ttl;
u_int16_t size;
void *rdata;
struct dns_rr *next;
};
struct dns_response {
HEADER header;
struct dns_query *query;
struct dns_rr *answer;
struct dns_rr *authority;
struct dns_rr *additional;
};
static struct dns_response *parse_dns_response(const u_char *, int);
static struct dns_query *parse_dns_qsection(const u_char *, int,
const u_char **, int);
static struct dns_rr *parse_dns_rrsection(const u_char *, int, const u_char **,
int);
static void free_dns_query(struct dns_query *);
static void free_dns_rr(struct dns_rr *);
static void free_dns_response(struct dns_response *);
static int count_dns_rr(struct dns_rr *, u_int16_t, u_int16_t);
int
getrrsetbyname(const char *hostname, unsigned int rdclass,
unsigned int rdtype, unsigned int flags,
struct rrsetinfo **res)
{
struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
int result;
struct rrsetinfo *rrset = NULL;
struct dns_response *response;
struct dns_response *response = NULL;
struct dns_rr *rr;
struct rdatainfo *rdata;
int length;
@ -195,19 +207,19 @@ getrrsetbyname(const char *hostname, unsigned int rdclass,
}
/* initialize resolver */
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
result = ERRSET_FAIL;
goto fail;
}
#ifdef DEBUG
_res.options |= RES_DEBUG;
_resp->options |= RES_DEBUG;
#endif /* DEBUG */
#ifdef RES_USE_DNSSEC
/* turn on DNSSEC if EDNS0 is configured */
if (_res.options & RES_USE_EDNS0)
_res.options |= RES_USE_DNSSEC;
if (_resp->options & RES_USE_EDNS0)
_resp->options |= RES_USE_DNSSEC;
#endif /* RES_USE_DNSEC */
/* make query */
@ -250,20 +262,16 @@ getrrsetbyname(const char *hostname, unsigned int rdclass,
rrset->rri_ttl = response->answer->ttl;
rrset->rri_nrdatas = response->header.ancount;
#ifdef HAVE_HEADER_AD
/* check for authenticated data */
if (response->header.ad == 1)
rrset->rri_flags |= RRSET_VALIDATED;
#endif
/* copy name from answer section */
length = strlen(response->answer->name);
rrset->rri_name = malloc(length + 1);
rrset->rri_name = strdup(response->answer->name);
if (rrset->rri_name == NULL) {
result = ERRSET_NOMEMORY;
goto fail;
}
strlcpy(rrset->rri_name, response->answer->name, length + 1);
/* count answers */
rrset->rri_nrdatas = count_dns_rr(response->answer, rrset->rri_rdclass,
@ -281,7 +289,7 @@ getrrsetbyname(const char *hostname, unsigned int rdclass,
/* allocate memory for signatures */
rrset->rri_sigs = calloc(rrset->rri_nsigs, sizeof(struct rdatainfo));
if (rrset->rri_nsigs > 0 && rrset->rri_sigs == NULL) {
if (rrset->rri_sigs == NULL) {
result = ERRSET_NOMEMORY;
goto fail;
}
@ -311,6 +319,7 @@ getrrsetbyname(const char *hostname, unsigned int rdclass,
memcpy(rdata->rdi_data, rr->rdata, rr->size);
}
}
free_dns_response(response);
*res = rrset;
return (ERRSET_SUCCESS);
@ -318,6 +327,8 @@ getrrsetbyname(const char *hostname, unsigned int rdclass,
fail:
if (rrset != NULL)
freerrset(rrset);
if (response != NULL)
free_dns_response(response);
return (result);
}
@ -467,7 +478,8 @@ parse_dns_qsection(const u_char *answer, int size, const u_char **cp, int count)
}
static struct dns_rr *
parse_dns_rrsection(const u_char *answer, int size, const u_char **cp, int count)
parse_dns_rrsection(const u_char *answer, int size, const u_char **cp,
int count)
{
struct dns_rr *head, *curr, *prev;
int i, length;