Fix a valgrind error found by SMB2-COMPOUND test.
authorJeremy Allison <jra@samba.org>
Wed, 9 Jun 2010 04:20:07 +0000 (21:20 -0700)
committerJeremy Allison <jra@samba.org>
Wed, 9 Jun 2010 04:20:07 +0000 (21:20 -0700)
If a file is closed we must also NULL out all chained_fsp
pointers when the fsp is freed to prevent invalid pointer
access.

Jeremy.

source3/smbd/files.c
source3/smbd/globals.h
source3/smbd/smb2_glue.c

index 43956e3903eac4525892c8cc5545a78a07907f40..7ad5ce3ae60966f31d6753f8a562672231ecc432 100644 (file)
@@ -503,6 +503,14 @@ void file_free(struct smb_request *req, files_struct *fsp)
                req->chain_fsp = NULL;
        }
 
+       /*
+        * Clear all possible chained fsp
+        * pointers in the SMB2 request queue.
+        */
+       if (req != NULL && req->smb2req) {
+               remove_smb2_chained_fsp(fsp);
+       }
+
        /* Closing a file can invalidate the positive cache. */
        if (fsp == fsp_fi_cache.fsp) {
                ZERO_STRUCT(fsp_fi_cache);
index 9df255475e39c4b9317472942fc2bd31437e0d1b..3533d60e7ad88b8b61dd8f003362d4f5119f0047 100644 (file)
@@ -277,6 +277,7 @@ NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req);
 NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req);
 
 struct smb_request *smbd_smb2_fake_smb_request(struct smbd_smb2_request *req);
+void remove_smb2_chained_fsp(files_struct *fsp);
 
 NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req);
 NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *req);
@@ -353,6 +354,8 @@ struct smbd_smb2_request {
        bool async;
        bool cancelled;
 
+       /* fake smb1 request. */
+       struct smb_request *smb1req;
        struct files_struct *compat_chain_fsp;
 
        NTSTATUS next_status;
index d6252ef3493b86e0ff189ebbf696cdd17ed74002..8b595affe0c1d40cc350ff522bf5be13a91fffb7 100644 (file)
@@ -49,6 +49,26 @@ struct smb_request *smbd_smb2_fake_smb_request(struct smbd_smb2_request *req)
        smbreq->mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
        smbreq->chain_fsp = req->compat_chain_fsp;
        smbreq->smb2req = req;
+       req->smb1req = smbreq;
 
        return smbreq;
 }
+
+/*********************************************************
+ Called from file_free() to remove any chained fsp pointers.
+*********************************************************/
+
+void remove_smb2_chained_fsp(files_struct *fsp)
+{
+       struct smbd_server_connection *sconn = smbd_server_conn;
+       struct smbd_smb2_request *smb2req;
+
+       for (smb2req = sconn->smb2.requests; smb2req; smb2req = smb2req->next) {
+               if (smb2req->compat_chain_fsp == fsp) {
+                       smb2req->compat_chain_fsp = NULL;
+               }
+               if (smb2req->smb1req && smb2req->smb1req->chain_fsp == fsp) {
+                       smb2req->smb1req->chain_fsp = NULL;
+               }
+       }
+}