Control of 'addr' is now handed over to {platform_,}new_connection() and
authorjacob <jacob@cda61777-01e9-0310-a592-d414129be87e>
Thu, 7 Aug 2003 16:04:33 +0000 (16:04 +0000)
committerjacob <jacob@cda61777-01e9-0310-a592-d414129be87e>
Thu, 7 Aug 2003 16:04:33 +0000 (16:04 +0000)
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

13 files changed:
mac/mtcpnet.c
mac/otnet.c
network.h
portfwd.c
proxy.c
raw.c
rlogin.c
ssh.c
telnet.c
unix/uxnet.c
unix/uxproxy.c
winnet.c
x11fwd.c

index 5415fbc..a8404b7 100644 (file)
@@ -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;
 }
 
index 970a78e..7881e02 100644 (file)
@@ -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;
 }
     
index 46ec6bb..cb077fd 100644 (file)
--- 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);
 
index 00132ec..e61c05b 100644 (file)
--- 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 4a2dd19..169be0d 100644 (file)
--- 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 c493649..4c9e5be 100644 (file)
--- 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;
 }
 
index 455c2d9..af3bd87 100644 (file)
--- 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 8cb5a56..23602f6 100644 (file)
--- 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;
index f421cc5..2edae21 100644 (file)
--- 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.
      */
index 7e5cf6f..ce062d8 100644 (file)
@@ -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;
 }
 
index cd256fd..b3f75e8 100644 (file)
@@ -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;
 }
index 6052725..c211f53 100644 (file)
--- 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;
 }
 
index 16944ee..8b045f3 100644 (file)
--- 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;
 }