s3:libsmb: add tstream_cli_np_ref as protection to talloc_free(smbXcli_conn)
authorStefan Metzmacher <metze@samba.org>
Thu, 19 Sep 2013 23:11:40 +0000 (01:11 +0200)
committerStefan Metzmacher <metze@samba.org>
Tue, 7 Jan 2014 07:37:41 +0000 (08:37 +0100)
This makes sure that we don't have dangling pointers.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
source3/libsmb/cli_np_tstream.c

index 4aa826c752168c92abdc86171f6123071338fb95..8bc81791c501a3176c976a283adeb8ab806dc82c 100644 (file)
@@ -49,7 +49,10 @@ static const struct tstream_context_ops tstream_cli_np_ops;
  */
 #define TSTREAM_CLI_NP_MAX_BUF_SIZE 4280
 
+struct tstream_cli_np_ref;
+
 struct tstream_cli_np {
+       struct tstream_cli_np_ref *ref;
        struct smbXcli_conn *conn;
        struct smbXcli_session *session;
        struct smbXcli_tcon *tcon;
@@ -76,10 +79,19 @@ struct tstream_cli_np {
        } read, write;
 };
 
+struct tstream_cli_np_ref {
+       struct tstream_cli_np *cli_nps;
+};
+
 static int tstream_cli_np_destructor(struct tstream_cli_np *cli_nps)
 {
        NTSTATUS status;
 
+       if (cli_nps->ref != NULL) {
+               cli_nps->ref->cli_nps = NULL;
+               TALLOC_FREE(cli_nps->ref);
+       }
+
        if (!smbXcli_conn_is_connected(cli_nps->conn)) {
                return 0;
        }
@@ -124,6 +136,20 @@ static int tstream_cli_np_destructor(struct tstream_cli_np *cli_nps)
        return 0;
 }
 
+static int tstream_cli_np_ref_destructor(struct tstream_cli_np_ref *ref)
+{
+       if (ref->cli_nps == NULL) {
+               return 0;
+       }
+
+       ref->cli_nps->conn = NULL;
+       ref->cli_nps->session = NULL;
+       ref->cli_nps->tcon = NULL;
+       ref->cli_nps->ref = NULL;
+
+       return 0;
+};
+
 struct tstream_cli_np_open_state {
        struct smbXcli_conn *conn;
        struct smbXcli_session *session;
@@ -274,6 +300,13 @@ NTSTATUS _tstream_cli_np_open_recv(struct tevent_req *req,
        }
        ZERO_STRUCTP(cli_nps);
 
+       cli_nps->ref = talloc_zero(state->conn, struct tstream_cli_np_ref);
+       if (cli_nps->ref == NULL) {
+               TALLOC_FREE(cli_nps);
+               tevent_req_received(req);
+               return NT_STATUS_NO_MEMORY;
+       }
+       cli_nps->ref->cli_nps = cli_nps;
        cli_nps->conn = state->conn;
        cli_nps->session = state->session;
        cli_nps->tcon = state->tcon;
@@ -286,6 +319,7 @@ NTSTATUS _tstream_cli_np_open_recv(struct tevent_req *req,
        cli_nps->fid_volatile = state->fid_volatile;
 
        talloc_set_destructor(cli_nps, tstream_cli_np_destructor);
+       talloc_set_destructor(cli_nps->ref, tstream_cli_np_ref_destructor);
 
        cli_nps->trans.active = false;
        cli_nps->trans.read_req = NULL;