s3: smbd - smb1 - fix read of deleted memory in reply_writeclose().
authorNoel Power <nopower@suse.com>
Thu, 27 Feb 2014 20:07:11 +0000 (12:07 -0800)
committerKarolin Seeger <kseeger@samba.org>
Tue, 6 May 2014 11:28:35 +0000 (13:28 +0200)
While running smbtorture test raw.write under valgrind an "Invalid read"
was reported in methid reply_writeclose, it seems after closing a file
sometime later we try to access it again.

Signed-off-by: Noel Power <noel.power@suse.com>
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Mon Mar  3 20:42:40 CET 2014 on sn-devel-104
(cherry picked from commit 04e434661fa6b5f13776f925b0a7cbadb6b6d006)

Fix bug #10554 - request backport for 'smb1 - fix read of deleted memory in
reply_writeclose()'.

Autobuild-User(v4-1-test): Karolin Seeger <kseeger@samba.org>
Autobuild-Date(v4-1-test): Tue May  6 13:28:35 CEST 2014 on sn-devel-104

source3/smbd/reply.c

index 055efd377a6444d328edfff5e56431a5b9cc727c..76d3ed19df74aed2918a8f24c78547ec49d665f6 100644 (file)
@@ -5194,7 +5194,7 @@ void reply_writeclose(struct smb_request *req)
        mtime = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+4));
        data = (const char *)req->buf + 1;
 
-       if (!fsp->print_file) {
+       if (fsp->print_file == NULL) {
                init_strict_lock_struct(fsp, (uint64_t)req->smbpid,
                    (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
                    &lock);
@@ -5208,6 +5208,10 @@ void reply_writeclose(struct smb_request *req)
 
        nwritten = write_file(req,fsp,data,startpos,numtowrite);
 
+       if (fsp->print_file == NULL) {
+               SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+       }
+
        set_close_write_time(fsp, mtime);
 
        /*
@@ -5215,34 +5219,32 @@ void reply_writeclose(struct smb_request *req)
         * JRA.
         */
 
+       DEBUG(3,("writeclose %s num=%d wrote=%d (numopen=%d)\n",
+               fsp_fnum_dbg(fsp), (int)numtowrite, (int)nwritten,
+               (numtowrite) ? conn->num_files_open - 1 : conn->num_files_open));
+
        if (numtowrite) {
                DEBUG(3,("reply_writeclose: zero length write doesn't close "
                         "file %s\n", fsp_str_dbg(fsp)));
                close_status = close_file(req, fsp, NORMAL_CLOSE);
+               fsp = NULL;
        }
 
-       DEBUG(3,("writeclose %s num=%d wrote=%d (numopen=%d)\n",
-                fsp_fnum_dbg(fsp), (int)numtowrite, (int)nwritten,
-                conn->num_files_open));
-
        if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
                reply_nterror(req, NT_STATUS_DISK_FULL);
-               goto strict_unlock;
+               goto out;
        }
 
        if(!NT_STATUS_IS_OK(close_status)) {
                reply_nterror(req, close_status);
-               goto strict_unlock;
+               goto out;
        }
 
        reply_outbuf(req, 1, 0);
 
        SSVAL(req->outbuf,smb_vwv0,nwritten);
 
-strict_unlock:
-       if (numtowrite && !fsp->print_file) {
-               SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
-       }
+out:
 
        END_PROFILE(SMBwriteclose);
        return;