mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-10 09:58:01 +00:00
Control of 'addr' is now handed over to {platform_,}new_connection() and
sk_new() on invocation; these functions become responsible for (eventually)
freeing it. The caller must not do anything with 'addr' after it's been passed
in. (Ick.)
Why:
A SOCKS5 crash appears to have been caused by overzealous freeing of
a SockAddr (ssh.c:1.257 [r2492]), which for proxied connections is
squirreled away long-term (and this can't easily be avoided).
It would have been nice to make a copy of the SockAddr, in case the caller has
a use for it, but one of the implementations (uxnet.c) hides a "struct
addrinfo" in there, and we have no defined way to duplicate those. (None of the
current callers _do_ have a further use for the SockAddr.)
As far as I can tell, everything _except_ proxying only needs addr for the
duration of the call, so sk_addr_free()s immediately. If I'm mistaken, it
should at least be easier to find the offending free()...
[originally from svn r3383]
[r2492 == bdd6633970
]
This commit is contained in:
parent
f110a51d1f
commit
92db92af5a
@ -517,6 +517,8 @@ Socket mactcp_new(SockAddr addr, int port, int privport, int oobinline,
|
|||||||
ret->next->prev = &ret->next;
|
ret->next->prev = &ret->next;
|
||||||
mactcp.socklist = ret;
|
mactcp.socklist = ret;
|
||||||
|
|
||||||
|
sk_addr_free(addr); /* don't need this anymore */
|
||||||
|
|
||||||
return (Socket)ret;
|
return (Socket)ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,6 +324,8 @@ Socket ot_new(SockAddr addr, int port, int privport, int oobinline,
|
|||||||
ret->next->prev = &ret->next;
|
ret->next->prev = &ret->next;
|
||||||
ot.socklist = ret;
|
ot.socklist = ret;
|
||||||
|
|
||||||
|
/* XXX: don't know whether we can sk_addr_free(addr); */
|
||||||
|
|
||||||
return (Socket) ret;
|
return (Socket) ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +75,8 @@ struct plug_function_table {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* proxy indirection layer */
|
/* proxy indirection layer */
|
||||||
|
/* NB, control of 'addr' is passed via new_connection, which takes
|
||||||
|
* responsibility for freeing it */
|
||||||
Socket new_connection(SockAddr addr, char *hostname,
|
Socket new_connection(SockAddr addr, char *hostname,
|
||||||
int port, int privport,
|
int port, int privport,
|
||||||
int oobinline, int nodelay, Plug plug,
|
int oobinline, int nodelay, Plug plug,
|
||||||
@ -85,6 +87,7 @@ SockAddr name_lookup(char *host, int port, char **canonicalname,
|
|||||||
const Config *cfg);
|
const Config *cfg);
|
||||||
|
|
||||||
/* platform-dependent callback from new_connection() */
|
/* platform-dependent callback from new_connection() */
|
||||||
|
/* (same caveat about addr as new_connection()) */
|
||||||
Socket platform_new_connection(SockAddr addr, char *hostname,
|
Socket platform_new_connection(SockAddr addr, char *hostname,
|
||||||
int port, int privport,
|
int port, int privport,
|
||||||
int oobinline, int nodelay, Plug plug,
|
int oobinline, int nodelay, Plug plug,
|
||||||
@ -105,6 +108,8 @@ int sk_addrtype(SockAddr addr);
|
|||||||
void sk_addrcopy(SockAddr addr, char *buf);
|
void sk_addrcopy(SockAddr addr, char *buf);
|
||||||
void sk_addr_free(SockAddr addr);
|
void sk_addr_free(SockAddr addr);
|
||||||
|
|
||||||
|
/* NB, control of 'addr' is passed via sk_new, which takes responsibility
|
||||||
|
* for freeing it, as for new_connection() */
|
||||||
Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
|
Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
|
||||||
int nodelay, Plug p);
|
int nodelay, Plug p);
|
||||||
|
|
||||||
|
@ -350,8 +350,10 @@ const char *pfd_newconnect(Socket *s, char *hostname, int port,
|
|||||||
* Try to find host.
|
* Try to find host.
|
||||||
*/
|
*/
|
||||||
addr = name_lookup(hostname, port, &dummy_realhost, cfg);
|
addr = name_lookup(hostname, port, &dummy_realhost, cfg);
|
||||||
if ((err = sk_addr_error(addr)) != NULL)
|
if ((err = sk_addr_error(addr)) != NULL) {
|
||||||
|
sk_addr_free(addr);
|
||||||
return err;
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Open socket.
|
* Open socket.
|
||||||
@ -373,7 +375,6 @@ const char *pfd_newconnect(Socket *s, char *hostname, int port,
|
|||||||
}
|
}
|
||||||
|
|
||||||
sk_set_private_ptr(*s, pr);
|
sk_set_private_ptr(*s, pr);
|
||||||
sk_addr_free(addr);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
5
proxy.c
5
proxy.c
@ -90,6 +90,7 @@ static void sk_proxy_close (Socket s)
|
|||||||
Proxy_Socket ps = (Proxy_Socket) s;
|
Proxy_Socket ps = (Proxy_Socket) s;
|
||||||
|
|
||||||
sk_close(ps->sub_socket);
|
sk_close(ps->sub_socket);
|
||||||
|
sk_addr_free(ps->remote_addr);
|
||||||
sfree(ps);
|
sfree(ps);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,7 +392,7 @@ Socket new_connection(SockAddr addr, char *hostname,
|
|||||||
ret->fn = &socket_fn_table;
|
ret->fn = &socket_fn_table;
|
||||||
ret->cfg = *cfg; /* STRUCTURE COPY */
|
ret->cfg = *cfg; /* STRUCTURE COPY */
|
||||||
ret->plug = plug;
|
ret->plug = plug;
|
||||||
ret->remote_addr = addr;
|
ret->remote_addr = addr; /* will need to be freed on close */
|
||||||
ret->remote_port = port;
|
ret->remote_port = port;
|
||||||
|
|
||||||
ret->error = NULL;
|
ret->error = NULL;
|
||||||
@ -443,8 +444,6 @@ Socket new_connection(SockAddr addr, char *hostname,
|
|||||||
if (sk_socket_error(ret->sub_socket) != NULL)
|
if (sk_socket_error(ret->sub_socket) != NULL)
|
||||||
return (Socket) ret;
|
return (Socket) ret;
|
||||||
|
|
||||||
sk_addr_free(proxy_addr);
|
|
||||||
|
|
||||||
/* start the proxy negotiation process... */
|
/* start the proxy negotiation process... */
|
||||||
sk_set_frozen(ret->sub_socket, 0);
|
sk_set_frozen(ret->sub_socket, 0);
|
||||||
ret->negotiate(ret, PROXY_CHANGE_NEW);
|
ret->negotiate(ret, PROXY_CHANGE_NEW);
|
||||||
|
6
raw.c
6
raw.c
@ -97,8 +97,10 @@ static const char *raw_init(void *frontend_handle, void **backend_handle,
|
|||||||
sfree(buf);
|
sfree(buf);
|
||||||
}
|
}
|
||||||
addr = name_lookup(host, port, realhost, cfg);
|
addr = name_lookup(host, port, realhost, cfg);
|
||||||
if ((err = sk_addr_error(addr)) != NULL)
|
if ((err = sk_addr_error(addr)) != NULL) {
|
||||||
|
sk_addr_free(addr);
|
||||||
return err;
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
if (port < 0)
|
if (port < 0)
|
||||||
port = 23; /* default telnet port */
|
port = 23; /* default telnet port */
|
||||||
@ -118,8 +120,6 @@ static const char *raw_init(void *frontend_handle, void **backend_handle,
|
|||||||
if ((err = sk_socket_error(raw->s)) != NULL)
|
if ((err = sk_socket_error(raw->s)) != NULL)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
sk_addr_free(addr);
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
6
rlogin.c
6
rlogin.c
@ -130,8 +130,10 @@ static const char *rlogin_init(void *frontend_handle, void **backend_handle,
|
|||||||
sfree(buf);
|
sfree(buf);
|
||||||
}
|
}
|
||||||
addr = name_lookup(host, port, realhost, cfg);
|
addr = name_lookup(host, port, realhost, cfg);
|
||||||
if ((err = sk_addr_error(addr)) != NULL)
|
if ((err = sk_addr_error(addr)) != NULL) {
|
||||||
|
sk_addr_free(addr);
|
||||||
return err;
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
if (port < 0)
|
if (port < 0)
|
||||||
port = 513; /* default rlogin port */
|
port = 513; /* default rlogin port */
|
||||||
@ -151,8 +153,6 @@ static const char *rlogin_init(void *frontend_handle, void **backend_handle,
|
|||||||
if ((err = sk_socket_error(rlogin->s)) != NULL)
|
if ((err = sk_socket_error(rlogin->s)) != NULL)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
sk_addr_free(addr);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send local username, remote username, terminal/speed
|
* Send local username, remote username, terminal/speed
|
||||||
*/
|
*/
|
||||||
|
1
ssh.c
1
ssh.c
@ -2169,7 +2169,6 @@ static const char *connect_to_host(Ssh ssh, char *host, int port,
|
|||||||
ssh->fn = &fn_table;
|
ssh->fn = &fn_table;
|
||||||
ssh->s = new_connection(addr, *realhost, port,
|
ssh->s = new_connection(addr, *realhost, port,
|
||||||
0, 1, nodelay, (Plug) ssh, &ssh->cfg);
|
0, 1, nodelay, (Plug) ssh, &ssh->cfg);
|
||||||
sk_addr_free(addr);
|
|
||||||
if ((err = sk_socket_error(ssh->s)) != NULL) {
|
if ((err = sk_socket_error(ssh->s)) != NULL) {
|
||||||
ssh->s = NULL;
|
ssh->s = NULL;
|
||||||
return err;
|
return err;
|
||||||
|
6
telnet.c
6
telnet.c
@ -710,8 +710,10 @@ static const char *telnet_init(void *frontend_handle, void **backend_handle,
|
|||||||
sfree(buf);
|
sfree(buf);
|
||||||
}
|
}
|
||||||
addr = name_lookup(host, port, realhost, &telnet->cfg);
|
addr = name_lookup(host, port, realhost, &telnet->cfg);
|
||||||
if ((err = sk_addr_error(addr)) != NULL)
|
if ((err = sk_addr_error(addr)) != NULL) {
|
||||||
|
sk_addr_free(addr);
|
||||||
return err;
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
if (port < 0)
|
if (port < 0)
|
||||||
port = 23; /* default telnet port */
|
port = 23; /* default telnet port */
|
||||||
@ -731,8 +733,6 @@ static const char *telnet_init(void *frontend_handle, void **backend_handle,
|
|||||||
if ((err = sk_socket_error(telnet->s)) != NULL)
|
if ((err = sk_socket_error(telnet->s)) != NULL)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
sk_addr_free(addr);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialise option states.
|
* Initialise option states.
|
||||||
*/
|
*/
|
||||||
|
@ -521,6 +521,8 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
|
|||||||
uxsel_tell(ret);
|
uxsel_tell(ret);
|
||||||
add234(sktree, ret);
|
add234(sktree, ret);
|
||||||
|
|
||||||
|
sk_addr_free(addr);
|
||||||
|
|
||||||
return (Socket) ret;
|
return (Socket) ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,5 +299,8 @@ Socket platform_new_connection(SockAddr addr, char *hostname,
|
|||||||
|
|
||||||
uxsel_set(ret->from_cmd, 1, localproxy_select_result);
|
uxsel_set(ret->from_cmd, 1, localproxy_select_result);
|
||||||
|
|
||||||
|
/* We are responsible for this and don't need it any more */
|
||||||
|
sk_addr_free(addr);
|
||||||
|
|
||||||
return (Socket) ret;
|
return (Socket) ret;
|
||||||
}
|
}
|
||||||
|
3
winnet.c
3
winnet.c
@ -701,6 +701,9 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
|
|||||||
|
|
||||||
add234(sktree, ret);
|
add234(sktree, ret);
|
||||||
|
|
||||||
|
/* We're done with 'addr' now. */
|
||||||
|
sk_addr_free(addr);
|
||||||
|
|
||||||
return (Socket) ret;
|
return (Socket) ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
5
x11fwd.c
5
x11fwd.c
@ -277,8 +277,10 @@ const char *x11_init(Socket * s, char *display, void *c, void *auth,
|
|||||||
* Try to find host.
|
* Try to find host.
|
||||||
*/
|
*/
|
||||||
addr = name_lookup(host, port, &dummy_realhost, cfg);
|
addr = name_lookup(host, port, &dummy_realhost, cfg);
|
||||||
if ((err = sk_addr_error(addr)) != NULL)
|
if ((err = sk_addr_error(addr)) != NULL) {
|
||||||
|
sk_addr_free(addr);
|
||||||
return err;
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Open socket.
|
* Open socket.
|
||||||
@ -315,7 +317,6 @@ const char *x11_init(Socket * s, char *display, void *c, void *auth,
|
|||||||
}
|
}
|
||||||
|
|
||||||
sk_set_private_ptr(*s, pr);
|
sk_set_private_ptr(*s, pr);
|
||||||
sk_addr_free(addr);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user