tsocks_gethostbyaddr_r scribbles garbage over data->hostname and then relies on it
Here's an edited version of the implementation with extraneous portions removed in an effort to make the mistake more clear:
struct data {
char *hostname;
char *addr_list[2];
char padding[];
} *data;
// ...
data = (struct data *) buf;
// ...
ret_str = inet_ntop(type, addr, buf, buflen);
// ...
if (data->hostname) {
Specifically, notice that data
is an alias for buf
and therefore the underlying memory is given to inet_ntop
to write on as a char*
but then tsocks_gethostbyaddr_r
tries to interpret that same memory through the data
struct to retrieve the hostname
field. The result is garbage which provokes a crash shortly afterwards:
he->h_length = strlen(he->h_name);
This case is triggered by an error response to the resolve_ptr request (\5\1\0\0
) when the IP address is valid (so that inet_ntop
writes the garbage to buf
).
I can imagine a couple fixes. The simplest overall would seem to be to stack allocated a new buffer for inet_ntop
. This makes calling tsocks_gethostbyaddr_r
a little more expensive (in terms of stack space) but greatly simplifies the code be removing the surprising aliasing.
Trac:
Username: exarkun