[PATCH 1/2] dnsapi: migrating to res_nquery (ver.3)
Donat Enikeev
donat at enikeev.net
Fri Jan 15 02:35:34 CST 2016
1. Style, extra checks and potential memory leackage fix (per Hans Leidekker feedback in substance)
2. Using debugstr_a() when tracing untrusted values of arbitrary size (per Sebastian Lackner)
Signed-off-by: Donat Enikeev <donat at enikeev.net>
---
dlls/dnsapi/query.c | 72 ++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 49 insertions(+), 23 deletions(-)
diff --git a/dlls/dnsapi/query.c b/dlls/dnsapi/query.c
index a66db37..7fafb48 100644
--- a/dlls/dnsapi/query.c
+++ b/dlls/dnsapi/query.c
@@ -46,6 +46,10 @@
#include "winnls.h"
#include "windns.h"
#include "nb30.h"
+#define USE_WS_PREFIX
+#include "inaddr.h"
+#include "in6addr.h"
+#include "ws2tcpip.h"
#include "dnsapi.h"
@@ -53,12 +57,19 @@ WINE_DEFAULT_DEBUG_CHANNEL(dnsapi);
#ifdef HAVE_RESOLV
-/* call res_init() just once because of a bug in Mac OS X 10.4 */
-/* call once per thread on systems that have per-thread _res */
-static void initialise_resolver( void )
+static res_state initialise_resolver( void )
{
- if ((_res.options & RES_INIT) == 0)
- res_init();
+ res_state rs;
+ if ( !(rs = heap_alloc_zero(sizeof(struct __res_state))) )
+ return NULL;
+
+ if ( res_ninit(rs) == -1 )
+ {
+ heap_free(rs);
+ return NULL;
+ }
+
+ return rs;
}
static const char *dns_section_to_str( ns_sect section )
@@ -543,7 +554,7 @@ exit:
/* res_init() must have been called before calling these three functions.
*/
-static DNS_STATUS dns_set_serverlist( const IP4_ARRAY *addrs )
+static DNS_STATUS dns_set_serverlist( res_state rs, const IP4_ARRAY *addrs )
{
int i;
@@ -551,38 +562,39 @@ static DNS_STATUS dns_set_serverlist( const IP4_ARRAY *addrs )
{
WARN( "too many servers: %d only using the first: %d\n",
addrs->AddrCount, MAXNS );
- _res.nscount = MAXNS;
+ rs->nscount = MAXNS;
}
- else _res.nscount = addrs->AddrCount;
+ else
+ rs->nscount = addrs->AddrCount;
- for (i = 0; i < _res.nscount; i++)
- _res.nsaddr_list[i].sin_addr.s_addr = addrs->AddrArray[i];
+ for (i = 0; i < rs->nscount; i++)
+ rs->nsaddr_list[i].sin_addr.s_addr = addrs->AddrArray[i];
return ERROR_SUCCESS;
}
-static DNS_STATUS dns_get_serverlist( PIP4_ARRAY addrs, PDWORD len )
+static DNS_STATUS dns_get_serverlist( res_state rs, PIP4_ARRAY addrs, PDWORD len )
{
unsigned int size;
int i;
- size = FIELD_OFFSET(IP4_ARRAY, AddrArray[_res.nscount]);
+ size = FIELD_OFFSET(IP4_ARRAY, AddrArray[rs->nscount]);
if (!addrs || *len < size)
{
*len = size;
return ERROR_INSUFFICIENT_BUFFER;
}
- addrs->AddrCount = _res.nscount;
+ addrs->AddrCount = rs->nscount;
- for (i = 0; i < _res.nscount; i++)
- addrs->AddrArray[i] = _res.nsaddr_list[i].sin_addr.s_addr;
+ for (i = 0; i < rs->nscount; i++)
+ addrs->AddrArray[i] = rs->nsaddr_list[i].sin_addr.s_addr;
return ERROR_SUCCESS;
}
#define DNS_MAX_PACKET_SIZE 4096
-static DNS_STATUS dns_do_query( PCSTR name, WORD type, DWORD options, PDNS_RECORDA *result )
+static DNS_STATUS dns_do_query( res_state rs, PCSTR name, WORD type, DWORD options, PDNS_RECORDA *result )
{
DNS_STATUS ret = DNS_ERROR_RCODE_NOT_IMPLEMENTED;
@@ -597,7 +609,9 @@ static DNS_STATUS dns_do_query( PCSTR name, WORD type, DWORD options, PDNS_RECOR
DNS_RRSET_INIT( rrset );
- len = res_query( name, ns_c_in, type, answer, sizeof(answer) );
+ TRACE("Performing res_nquery(%p, %s, %u, %u, %p)\n", rs, debugstr_a(name), type, options, result);
+
+ len = res_nquery( rs, name, ns_c_in, type, answer, sizeof(answer) );
if (len < 0)
{
ret = dns_map_h_errno( h_errno );
@@ -706,6 +720,7 @@ DNS_STATUS WINAPI DnsQuery_UTF8( PCSTR name, WORD type, DWORD options, PVOID ser
{
DNS_STATUS ret = DNS_ERROR_RCODE_NOT_IMPLEMENTED;
#ifdef HAVE_RESOLV
+ res_state rs;
TRACE( "(%s,%s,0x%08x,%p,%p,%p)\n", debugstr_a(name), dns_type_to_str( type ),
options, servers, result, reserved );
@@ -713,13 +728,18 @@ DNS_STATUS WINAPI DnsQuery_UTF8( PCSTR name, WORD type, DWORD options, PVOID ser
if (!name || !result)
return ERROR_INVALID_PARAMETER;
- initialise_resolver();
- _res.options |= dns_map_options( options );
+ rs = initialise_resolver();
+ if ( !rs ) return ERROR_NOT_ENOUGH_MEMORY;
- if (servers && (ret = dns_set_serverlist( servers )))
+ rs->options |= dns_map_options( options );
+
+ if (servers && (ret = dns_set_serverlist( rs, servers )))
+ {
+ heap_free(rs);
return ret;
+ }
- ret = dns_do_query( name, type, options, result );
+ ret = dns_do_query( rs, name, type, options, result );
if (ret == DNS_ERROR_RCODE_NAME_ERROR && type == DNS_TYPE_A &&
!(options & DNS_QUERY_NO_NETBT))
@@ -728,6 +748,8 @@ DNS_STATUS WINAPI DnsQuery_UTF8( PCSTR name, WORD type, DWORD options, PVOID ser
ret = dns_do_query_netbios( name, result );
}
+ heap_free(rs);
+
#endif
return ret;
}
@@ -824,8 +846,12 @@ DNS_STATUS WINAPI DnsQueryConfig( DNS_CONFIG_TYPE config, DWORD flag, PCWSTR ada
case DnsConfigDnsServerList:
{
#ifdef HAVE_RESOLV
- initialise_resolver();
- ret = dns_get_serverlist( buffer, len );
+ res_state rs = initialise_resolver();
+ if (!rs) return ERROR_NOT_ENOUGH_MEMORY;
+
+ ret = dns_get_serverlist( rs, buffer, len );
+
+ heap_free(rs);
break;
#else
WARN( "compiled without resolver support\n" );
--
2.5.0
More information about the wine-patches
mailing list