mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
Fix struct hostinfo free code and BSD compile.
The code added in6 c596f1cc1d92b2b90ef5ce043ace314eefa868b fails to free the returned datastructures from gethostinfo() because sdetails.hostinfo is used to loop through the addresses and ends up NULL. In some libc implementations this results in a SEGV when freeaddrinfo() is called. Also fix FTBFS under BSD. Thanks to Johnny S. Lee for the bug report.
This commit is contained in:
@@ -461,8 +461,8 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
|
|||||||
} while (dbus_message_iter_get_arg_type(&string_iter) == DBUS_TYPE_STRING);
|
} while (dbus_message_iter_get_arg_type(&string_iter) == DBUS_TYPE_STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sdetails.resolved)
|
if (sdetails.orig_hostinfo)
|
||||||
freeaddrinfo(sdetails.hostinfo);
|
freeaddrinfo(sdetails.orig_hostinfo);
|
||||||
|
|
||||||
/* jump to next element in outer array */
|
/* jump to next element in outer array */
|
||||||
dbus_message_iter_next(&array_iter);
|
dbus_message_iter_next(&array_iter);
|
||||||
|
|||||||
@@ -1295,9 +1295,9 @@ extern struct daemon {
|
|||||||
|
|
||||||
struct server_details {
|
struct server_details {
|
||||||
union mysockaddr *addr, *source_addr;
|
union mysockaddr *addr, *source_addr;
|
||||||
struct addrinfo *hostinfo;
|
struct addrinfo *hostinfo, *orig_hostinfo;
|
||||||
char *interface, *source, *scope_id, *interface_opt;
|
char *interface, *source, *scope_id, *interface_opt;
|
||||||
int serv_port, source_port, addr_type, scope_index, valid, resolved;
|
int serv_port, source_port, addr_type, scope_index, valid;
|
||||||
u16 *flags;
|
u16 *flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
35
src/option.c
35
src/option.c
@@ -860,10 +860,15 @@ char *parse_server(char *arg, struct server_details *sdetails)
|
|||||||
sdetails->serv_port = NAMESERVER_PORT;
|
sdetails->serv_port = NAMESERVER_PORT;
|
||||||
char *portno;
|
char *portno;
|
||||||
int ecode = 0;
|
int ecode = 0;
|
||||||
struct addrinfo hints = { 0 };
|
struct addrinfo hints;
|
||||||
|
|
||||||
|
memset(&hints, 0, sizeof(struct addrinfo));
|
||||||
|
|
||||||
*sdetails->interface = 0;
|
*sdetails->interface = 0;
|
||||||
sdetails->addr_type = AF_UNSPEC;
|
sdetails->addr_type = AF_UNSPEC;
|
||||||
|
sdetails->valid = 0;
|
||||||
|
sdetails->hostinfo = sdetails->orig_hostinfo = NULL;
|
||||||
|
|
||||||
|
|
||||||
if (strcmp(arg, "#") == 0)
|
if (strcmp(arg, "#") == 0)
|
||||||
{
|
{
|
||||||
@@ -943,7 +948,7 @@ char *parse_server(char *arg, struct server_details *sdetails)
|
|||||||
above, and returns a pointer to the start of the list in <hostinfo>.
|
above, and returns a pointer to the start of the list in <hostinfo>.
|
||||||
The items in the linked list are linked by the <ai_next> field. */
|
The items in the linked list are linked by the <ai_next> field. */
|
||||||
sdetails->valid = 1;
|
sdetails->valid = 1;
|
||||||
sdetails->resolved = 1;
|
sdetails->orig_hostinfo = sdetails->hostinfo;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -967,7 +972,7 @@ char *parse_server_addr(struct server_details *sdetails)
|
|||||||
sdetails->addr->in.sin_port = htons(sdetails->serv_port);
|
sdetails->addr->in.sin_port = htons(sdetails->serv_port);
|
||||||
sdetails->addr->sa.sa_family = sdetails->source_addr->sa.sa_family = AF_INET;
|
sdetails->addr->sa.sa_family = sdetails->source_addr->sa.sa_family = AF_INET;
|
||||||
#ifdef HAVE_SOCKADDR_SA_LEN
|
#ifdef HAVE_SOCKADDR_SA_LEN
|
||||||
source_addr->in.sin_len = addr->in.sin_len = sizeof(struct sockaddr_in);
|
sdetails->source_addr->in.sin_len = sdetails->addr->in.sin_len = sizeof(struct sockaddr_in);
|
||||||
#endif
|
#endif
|
||||||
sdetails->source_addr->in.sin_addr.s_addr = INADDR_ANY;
|
sdetails->source_addr->in.sin_addr.s_addr = INADDR_ANY;
|
||||||
sdetails->source_addr->in.sin_port = htons(daemon->query_port);
|
sdetails->source_addr->in.sin_port = htons(daemon->query_port);
|
||||||
@@ -985,7 +990,7 @@ char *parse_server_addr(struct server_details *sdetails)
|
|||||||
/* When resolving a server IP by hostname, we can simply skip mismatching
|
/* When resolving a server IP by hostname, we can simply skip mismatching
|
||||||
server / source IP pairs. Otherwise, when an IP address is given directly,
|
server / source IP pairs. Otherwise, when an IP address is given directly,
|
||||||
this is a fatal error. */
|
this is a fatal error. */
|
||||||
if (!sdetails->resolved)
|
if (!sdetails->orig_hostinfo)
|
||||||
return _("cannot use IPv4 server address with IPv6 source address");
|
return _("cannot use IPv4 server address with IPv6 source address");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1016,7 +1021,7 @@ char *parse_server_addr(struct server_details *sdetails)
|
|||||||
sdetails->addr->sa.sa_family = sdetails->source_addr->sa.sa_family = AF_INET6;
|
sdetails->addr->sa.sa_family = sdetails->source_addr->sa.sa_family = AF_INET6;
|
||||||
sdetails->addr->in6.sin6_flowinfo = sdetails->source_addr->in6.sin6_flowinfo = 0;
|
sdetails->addr->in6.sin6_flowinfo = sdetails->source_addr->in6.sin6_flowinfo = 0;
|
||||||
#ifdef HAVE_SOCKADDR_SA_LEN
|
#ifdef HAVE_SOCKADDR_SA_LEN
|
||||||
sdetails->addr->in6.sin6_len = sdetails->source_addr->in6.sin6_len = sizeof(addr->in6);
|
sdetails->addr->in6.sin6_len = sdetails->source_addr->in6.sin6_len = sizeof(sdetails->addr->in6);
|
||||||
#endif
|
#endif
|
||||||
if (sdetails->source)
|
if (sdetails->source)
|
||||||
{
|
{
|
||||||
@@ -1031,7 +1036,7 @@ char *parse_server_addr(struct server_details *sdetails)
|
|||||||
/* When resolving a server IP by hostname, we can simply skip mismatching
|
/* When resolving a server IP by hostname, we can simply skip mismatching
|
||||||
server / source IP pairs. Otherwise, when an IP address is given directly,
|
server / source IP pairs. Otherwise, when an IP address is given directly,
|
||||||
this is a fatal error. */
|
this is a fatal error. */
|
||||||
if(!sdetails->resolved)
|
if(!sdetails->orig_hostinfo)
|
||||||
return _("cannot use IPv6 server address with IPv4 source address");
|
return _("cannot use IPv6 server address with IPv4 source address");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1098,7 +1103,7 @@ static char *domain_rev4(int from_file, char *server, struct in_addr *addr4, int
|
|||||||
union mysockaddr serv_addr, source_addr;
|
union mysockaddr serv_addr, source_addr;
|
||||||
char interface[IF_NAMESIZE+1];
|
char interface[IF_NAMESIZE+1];
|
||||||
int count = 1, rem, addrbytes, addrbits;
|
int count = 1, rem, addrbytes, addrbits;
|
||||||
struct server_details sdetails = { 0 };
|
struct server_details sdetails;
|
||||||
sdetails.addr = &serv_addr;
|
sdetails.addr = &serv_addr;
|
||||||
sdetails.source_addr = &source_addr;
|
sdetails.source_addr = &source_addr;
|
||||||
sdetails.interface = interface;
|
sdetails.interface = interface;
|
||||||
@@ -1161,8 +1166,8 @@ static char *domain_rev4(int from_file, char *server, struct in_addr *addr4, int
|
|||||||
return _("error");
|
return _("error");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sdetails.resolved)
|
if (sdetails.orig_hostinfo)
|
||||||
freeaddrinfo(sdetails.hostinfo);
|
freeaddrinfo(sdetails.orig_hostinfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1179,7 +1184,7 @@ static char *domain_rev6(int from_file, char *server, struct in6_addr *addr6, in
|
|||||||
union mysockaddr serv_addr, source_addr;
|
union mysockaddr serv_addr, source_addr;
|
||||||
char interface[IF_NAMESIZE+1];
|
char interface[IF_NAMESIZE+1];
|
||||||
int count = 1, rem, addrbytes, addrbits;
|
int count = 1, rem, addrbytes, addrbits;
|
||||||
struct server_details sdetails = { 0 };
|
struct server_details sdetails;
|
||||||
sdetails.addr = &serv_addr;
|
sdetails.addr = &serv_addr;
|
||||||
sdetails.source_addr = &source_addr;
|
sdetails.source_addr = &source_addr;
|
||||||
sdetails.interface = interface;
|
sdetails.interface = interface;
|
||||||
@@ -1244,8 +1249,8 @@ static char *domain_rev6(int from_file, char *server, struct in6_addr *addr6, in
|
|||||||
return _("error");
|
return _("error");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sdetails.resolved)
|
if (sdetails.orig_hostinfo)
|
||||||
freeaddrinfo(sdetails.hostinfo);
|
freeaddrinfo(sdetails.orig_hostinfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2966,7 +2971,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
union mysockaddr serv_addr, source_addr;
|
union mysockaddr serv_addr, source_addr;
|
||||||
char interface[IF_NAMESIZE+1];
|
char interface[IF_NAMESIZE+1];
|
||||||
|
|
||||||
struct server_details sdetails = { 0 };
|
struct server_details sdetails;
|
||||||
sdetails.addr = &serv_addr;
|
sdetails.addr = &serv_addr;
|
||||||
sdetails.source_addr = &source_addr;
|
sdetails.source_addr = &source_addr;
|
||||||
sdetails.interface = interface;
|
sdetails.interface = interface;
|
||||||
@@ -3051,8 +3056,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sdetails.resolved)
|
if (sdetails.orig_hostinfo)
|
||||||
freeaddrinfo(sdetails.hostinfo);
|
freeaddrinfo(sdetails.orig_hostinfo);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user