Repository: alexcrichton/ssh2-rs (language: rust)

Issue:
Dangling pointer used in pub function channel_forward_listen(), resulting in an Use-After-Free bug
Hi, I hv noticed that there is a dangling pointer used in the pub function `channel_forward_listen()`. When the `host` parameter is not None, it will generate a dangling pointer passed in `raw::libssh2_channel_forward_listen_ex()`, which results in a later Use-After-Free bug.
```
pub fn channel_forward_listen(
        &self,
        remote_port: u16,
        host: Option<&str>,
        queue_maxsize: Option<u32>,
    ) -> Result<(Listener, u16), Error> {
        let mut bound_port = 0;
        let host = host.map(|s| CString::new(s)).transpose()?;
        let inner = self.inner();
        unsafe {
            let ret = raw::libssh2_channel_forward_listen_ex(
                inner.raw,
                host.map(|s| s.as_ptr()).unwrap_or(null()),
                remote_port as c_int,
                &mut bound_port,
                queue_maxsize.unwrap_or(0) as c_int,
            );
            let err = inner.last_error();
            Listener::from_raw_opt(ret, err, &self.inner).map(|l| (l, bound_port as u16))
        }
    }
``` 

To reproduce the UAF, compile the below code:
```
    use std::net::TcpStream;
    use ssh2::Session;

    // Connect to the local SSH server
    let tcp = TcpStream::connect("127.0.0.1:22").unwrap();
    // Connect to the local SSH server
    let mut sess = Session::new().unwrap();
    sess.set_tcp_stream(tcp);
    sess.handshake().unwrap();

    sess.userauth_password("username", "password").unwrap();
    assert!(sess.authenticated());
    let (mut listen, port) = sess.channel_forward_listen(39249, Some("1.2.3.4"), None).unwrap();
```

Suggested Fix:
Change the code `host.map(|s| s.as_ptr()).unwrap_or(null())` to `host.as_ref().map(|s| s.as_ptr()).unwrap_or(null())`


Discussion / hints:

Fix patch:
diff --git a/src/session.rs b/src/session.rs
index a70b25b7..9d6e488d 100644
--- a/src/session.rs
+++ b/src/session.rs
@@ -838,7 +838,10 @@ impl Session {
         unsafe {
             let ret = raw::libssh2_channel_forward_listen_ex(
                 inner.raw,
-                host.map(|s| s.as_ptr()).unwrap_or(null()),
+                host
+                    .as_ref()
+                    .map(|s| s.as_ptr())
+                    .unwrap_or(null()),
                 remote_port as c_int,
                 &mut bound_port,
                 queue_maxsize.unwrap_or(0) as c_int,


Test patch: