diff options
author | Jeremy Allison <jra@samba.org> | 2010-06-08 21:20:07 -0700 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2010-06-08 21:20:07 -0700 |
commit | 34a8324409961c4837e83c714fb1a285f238312d (patch) | |
tree | d6372f70e6fdd55728e52c58e71c83820a727b71 | |
parent | 0c5d0e1c37daf5b802e990bde8469934ae33f6cc (diff) | |
download | samba-34a8324409961c4837e83c714fb1a285f238312d.tar.gz samba-34a8324409961c4837e83c714fb1a285f238312d.tar.bz2 samba-34a8324409961c4837e83c714fb1a285f238312d.zip |
Fix a valgrind error found by SMB2-COMPOUND test.
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.
-rw-r--r-- | source3/smbd/files.c | 8 | ||||
-rw-r--r-- | source3/smbd/globals.h | 3 | ||||
-rw-r--r-- | source3/smbd/smb2_glue.c | 20 |
3 files changed, 31 insertions, 0 deletions
diff --git a/source3/smbd/files.c b/source3/smbd/files.c index 43956e3903..7ad5ce3ae6 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -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); diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 9df255475e..3533d60e7a 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -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; diff --git a/source3/smbd/smb2_glue.c b/source3/smbd/smb2_glue.c index d6252ef349..8b595affe0 100644 --- a/source3/smbd/smb2_glue.c +++ b/source3/smbd/smb2_glue.c @@ -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; + } + } +} |