mirror of
git://anongit.mindrot.org/openssh.git
synced 2025-02-16 13:56:52 +00:00
- (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:
parent
3a38c5a856
commit
9b59ada7ca
@ -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 $
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user