From f85e6f6edb2c9415bc10bd2015479d72ea8c5ae2 Mon Sep 17 00:00:00 2001 From: jacob Date: Thu, 7 Aug 2003 16:04:33 +0000 Subject: [PATCH] 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()... git-svn-id: svn://svn.tartarus.org/sgt/putty@3383 cda61777-01e9-0310-a592-d414129be87e --- mac/mtcpnet.c | 2 ++ mac/otnet.c | 2 ++ network.h | 5 +++++ portfwd.c | 5 +++-- proxy.c | 5 ++--- raw.c | 6 +++--- rlogin.c | 6 +++--- ssh.c | 1 - telnet.c | 6 +++--- unix/uxnet.c | 2 ++ unix/uxproxy.c | 3 +++ winnet.c | 3 +++ x11fwd.c | 5 +++-- 13 files changed, 34 insertions(+), 17 deletions(-) diff --git a/mac/mtcpnet.c b/mac/mtcpnet.c index 5415fbc6..a8404b7a 100644 --- a/mac/mtcpnet.c +++ b/mac/mtcpnet.c @@ -517,6 +517,8 @@ Socket mactcp_new(SockAddr addr, int port, int privport, int oobinline, ret->next->prev = &ret->next; mactcp.socklist = ret; + sk_addr_free(addr); /* don't need this anymore */ + return (Socket)ret; } diff --git a/mac/otnet.c b/mac/otnet.c index 970a78e5..7881e02a 100644 --- a/mac/otnet.c +++ b/mac/otnet.c @@ -324,6 +324,8 @@ Socket ot_new(SockAddr addr, int port, int privport, int oobinline, ret->next->prev = &ret->next; ot.socklist = ret; + /* XXX: don't know whether we can sk_addr_free(addr); */ + return (Socket) ret; } diff --git a/network.h b/network.h index 46ec6bb7..cb077fdb 100644 --- a/network.h +++ b/network.h @@ -75,6 +75,8 @@ struct plug_function_table { }; /* 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, int port, int privport, int oobinline, int nodelay, Plug plug, @@ -85,6 +87,7 @@ SockAddr name_lookup(char *host, int port, char **canonicalname, const Config *cfg); /* platform-dependent callback from new_connection() */ +/* (same caveat about addr as new_connection()) */ Socket platform_new_connection(SockAddr addr, char *hostname, int port, int privport, int oobinline, int nodelay, Plug plug, @@ -105,6 +108,8 @@ int sk_addrtype(SockAddr addr); void sk_addrcopy(SockAddr addr, char *buf); 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, int nodelay, Plug p); diff --git a/portfwd.c b/portfwd.c index 00132ec6..e61c05b4 100644 --- a/portfwd.c +++ b/portfwd.c @@ -350,8 +350,10 @@ const char *pfd_newconnect(Socket *s, char *hostname, int port, * Try to find host. */ 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; + } /* * Open socket. @@ -373,7 +375,6 @@ const char *pfd_newconnect(Socket *s, char *hostname, int port, } sk_set_private_ptr(*s, pr); - sk_addr_free(addr); return NULL; } diff --git a/proxy.c b/proxy.c index 4a2dd19c..169be0d1 100644 --- a/proxy.c +++ b/proxy.c @@ -90,6 +90,7 @@ static void sk_proxy_close (Socket s) Proxy_Socket ps = (Proxy_Socket) s; sk_close(ps->sub_socket); + sk_addr_free(ps->remote_addr); sfree(ps); } @@ -391,7 +392,7 @@ Socket new_connection(SockAddr addr, char *hostname, ret->fn = &socket_fn_table; ret->cfg = *cfg; /* STRUCTURE COPY */ ret->plug = plug; - ret->remote_addr = addr; + ret->remote_addr = addr; /* will need to be freed on close */ ret->remote_port = port; ret->error = NULL; @@ -443,8 +444,6 @@ Socket new_connection(SockAddr addr, char *hostname, if (sk_socket_error(ret->sub_socket) != NULL) return (Socket) ret; - sk_addr_free(proxy_addr); - /* start the proxy negotiation process... */ sk_set_frozen(ret->sub_socket, 0); ret->negotiate(ret, PROXY_CHANGE_NEW); diff --git a/raw.c b/raw.c index c4936493..4c9e5bec 100644 --- a/raw.c +++ b/raw.c @@ -97,8 +97,10 @@ static const char *raw_init(void *frontend_handle, void **backend_handle, sfree(buf); } 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; + } if (port < 0) 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) return err; - sk_addr_free(addr); - return NULL; } diff --git a/rlogin.c b/rlogin.c index 455c2d9d..af3bd876 100644 --- a/rlogin.c +++ b/rlogin.c @@ -130,8 +130,10 @@ static const char *rlogin_init(void *frontend_handle, void **backend_handle, sfree(buf); } 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; + } if (port < 0) 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) return err; - sk_addr_free(addr); - /* * Send local username, remote username, terminal/speed */ diff --git a/ssh.c b/ssh.c index 8cb5a564..23602f6d 100644 --- a/ssh.c +++ b/ssh.c @@ -2169,7 +2169,6 @@ static const char *connect_to_host(Ssh ssh, char *host, int port, ssh->fn = &fn_table; ssh->s = new_connection(addr, *realhost, port, 0, 1, nodelay, (Plug) ssh, &ssh->cfg); - sk_addr_free(addr); if ((err = sk_socket_error(ssh->s)) != NULL) { ssh->s = NULL; return err; diff --git a/telnet.c b/telnet.c index f421cc58..2edae219 100644 --- a/telnet.c +++ b/telnet.c @@ -710,8 +710,10 @@ static const char *telnet_init(void *frontend_handle, void **backend_handle, sfree(buf); } 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; + } if (port < 0) 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) return err; - sk_addr_free(addr); - /* * Initialise option states. */ diff --git a/unix/uxnet.c b/unix/uxnet.c index 7e5cf6f7..ce062d8a 100644 --- a/unix/uxnet.c +++ b/unix/uxnet.c @@ -521,6 +521,8 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline, uxsel_tell(ret); add234(sktree, ret); + sk_addr_free(addr); + return (Socket) ret; } diff --git a/unix/uxproxy.c b/unix/uxproxy.c index cd256fdb..b3f75e81 100644 --- a/unix/uxproxy.c +++ b/unix/uxproxy.c @@ -299,5 +299,8 @@ Socket platform_new_connection(SockAddr addr, char *hostname, 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; } diff --git a/winnet.c b/winnet.c index 6052725b..c211f539 100644 --- a/winnet.c +++ b/winnet.c @@ -701,6 +701,9 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline, add234(sktree, ret); + /* We're done with 'addr' now. */ + sk_addr_free(addr); + return (Socket) ret; } diff --git a/x11fwd.c b/x11fwd.c index 16944ee1..8b045f31 100644 --- a/x11fwd.c +++ b/x11fwd.c @@ -277,8 +277,10 @@ const char *x11_init(Socket * s, char *display, void *c, void *auth, * Try to find host. */ 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; + } /* * 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_addr_free(addr); return NULL; } -- 2.11.0