]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
nfs: don't reuse file transactions
authorVictor Julien <victor@inliniac.net>
Thu, 18 Mar 2021 10:05:35 +0000 (11:05 +0100)
committerShivani Bhardwaj <shivanib134@gmail.com>
Fri, 17 Sep 2021 02:48:52 +0000 (08:18 +0530)
After a file has been closed (CLOSE, COMMIT command or EOF/SYNC part of
READ/WRITE data block) mark it as such so that new file commands on that
file do not reuse the transaction.

When a file transfer is completed it will be flagged as such and not be
found anymore by the NFSState::get_file_tx_by_handle() method. This forces
a new transaction to be created.

(cherry picked from commit 67759795c6405e449a80b282d290f84dc0fcd778)

rust/src/nfs/nfs.rs
rust/src/nfs/nfs3.rs
rust/src/nfs/nfs4.rs

index 112abbd94428ba3c21aecfeafa0046d7f8caad23..4ccd8c73d754a595942a4a49fb16daefe33d7efa 100644 (file)
@@ -168,6 +168,7 @@ pub struct NFSTransaction {
 
     /// is a special file tx that we look up by file_handle instead of XID
     pub is_file_tx: bool,
+    pub is_file_closed: bool,
     /// file transactions are unidirectional in the sense that they track
     /// a single file on one direction
     pub file_tx_direction: u8, // STREAM_TOCLIENT or STREAM_TOSERVER
@@ -203,6 +204,7 @@ impl NFSTransaction {
             response_done: false,
             nfs_version:0,
             is_file_tx: false,
+            is_file_closed: false,
             file_tx_direction: 0,
             file_handle:Vec::new(),
             type_data: None,
@@ -634,7 +636,7 @@ impl NFSState {
     {
         let fh = file_handle.to_vec();
         for tx in &mut self.transactions {
-            if tx.is_file_tx &&
+            if tx.is_file_tx && !tx.is_file_closed &&
                 direction == tx.file_tx_direction &&
                 tx.file_handle == fh
             {
@@ -677,6 +679,7 @@ impl NFSState {
                         tdf.file_last_xid = r.hdr.xid;
                         tx.is_last = true;
                         tx.response_done = true;
+                        tx.is_file_closed = true;
                     }
                     true
                 } else {
@@ -699,6 +702,7 @@ impl NFSState {
                     tdf.file_last_xid = r.hdr.xid;
                     tx.is_last = true;
                     tx.request_done = true;
+                    tx.is_file_closed = true;
                 }
             }
         }
@@ -856,9 +860,11 @@ impl NFSState {
                     if tdf.file_tracker.is_done() {
                         if direction == STREAM_TOCLIENT {
                             tx.response_done = true;
+                            tx.is_file_closed = true;
                             SCLogDebug!("TX {} response is done now that the file track is ready", tx.id);
                         } else {
                             tx.request_done = true;
+                            tx.is_file_closed = true;
                             SCLogDebug!("TX {} request is done now that the file track is ready", tx.id);
                         }
                     }
index f910b8a9195bbede5d322b6f8280a2d5c6724750..44701ca13a5ba0f53a89faa44c70db1c6c432590 100644 (file)
@@ -126,6 +126,7 @@ impl NFSState {
                         tdf.file_last_xid = r.hdr.xid;
                         tx.is_last = true;
                         tx.request_done = true;
+                        tx.is_file_closed = true;
                     }
                 }
             } else {
index 51d78800e3a77c6acbe5994f90ff454090da24a3..1f50c0eb46d43246f108c99d2f446b6d243b45a1 100644 (file)
@@ -91,6 +91,7 @@ impl NFSState {
                     tdf.file_last_xid = r.hdr.xid;
                     tx.is_last = true;
                     tx.request_done = true;
+                    tx.is_file_closed = true;
                 }
             }
         }
@@ -99,6 +100,11 @@ impl NFSState {
         self.ts_chunk_left = w.write_len as u32 - file_data_len as u32;
     }
 
+    fn close_v4<'b>(&mut self, r: &RpcPacket<'b>, fh: &'b[u8])
+    {
+        self.commit_v4(r, fh)
+    }
+
     fn commit_v4<'b>(&mut self, r: &RpcPacket<'b>, fh: &'b[u8])
     {
         SCLogDebug!("COMMIT, closing shop");
@@ -110,6 +116,7 @@ impl NFSState {
                 tdf.file_last_xid = r.hdr.xid;
                 tx.is_last = true;
                 tx.request_done = true;
+                tx.is_file_closed = true;
             }
         }
     }
@@ -188,6 +195,9 @@ impl NFSState {
                 }
                 &Nfs4RequestContent::Close(ref _rd) => {
                     SCLogDebug!("CLOSEv4: {:?}", _rd);
+                    if let Some(fh) = last_putfh {
+                        self.close_v4(r, fh);
+                    }
                 }
                 &Nfs4RequestContent::Create(ref rd) => {
                     SCLogDebug!("CREATEv4: {:?}", rd);