Project

General

Profile

Actions

Bug #8009

open

NFSv3: File extraction bug when stable equal with FILE_SYNC

Added by QianKai Lin 3 months ago. Updated 22 days ago.

Status:
New
Priority:
Normal
Assignee:
Target version:
Affected Versions:
Effort:
medium
Difficulty:
Label:
Protocol, Rust

Description

Description

When I used Suricata to read this pcap file, the generated file was only a little over 1 KB in size.

Reason

In process_write_record, that assume stable == 2 is last chunk, but file_data.len() maybe less than file_len from WRITE command, so it lead to the file data loss.


Files

test_nfsv3.pcap (13.3 MB) test_nfsv3.pcap QianKai Lin, 10/21/2025 02:04 AM
Actions #1

Updated by Philippe Antoine 22 days ago

  • Assignee set to OISF Dev
  • Target version changed from TBD to 9.0.0-beta1
  • Affected Versions 8.0.0 added
  • Affected Versions deleted (git main)

I see the bug indeed

Actions #2

Updated by Philippe Antoine 22 days ago

Fix using is_last && w.file_len as usize >= w.file_data.len() is not enough...

Actions #3

Updated by Philippe Antoine 22 days ago

POC patch

diff --git a/rust/src/nfs/nfs.rs b/rust/src/nfs/nfs.rs
index 43a9219f83..8c15a43e65 100644
--- a/rust/src/nfs/nfs.rs
+++ b/rust/src/nfs/nfs.rs
@@ -1026,7 +1026,7 @@ impl NFSState {
                     w.offset,
                     w.file_len,
                     fill_bytes as u8,
-                    is_last,
+                    is_last && w.file_len as usize >= w.file_data.len(),
                     &r.hdr.xid,
                 );
                 tx.procedure = NFSPROC3_WRITE;
@@ -1036,9 +1036,11 @@ impl NFSState {
                 if is_last {
                     tdf.file_last_xid = r.hdr.xid;
                     tx.is_last = true;
-                    tx.request_done = true;
-                    tx.is_file_closed = true;
-                    sc_app_layer_parser_trigger_raw_stream_inspection(flow, Direction::ToServer as i32);
+                    if w.file_len as usize <= w.file_data.len() {
+                        tx.request_done = true;
+                        tx.is_file_closed = true;
+                        sc_app_layer_parser_trigger_raw_stream_inspection(flow, Direction::ToServer as i32);
+                    }
                 }
             }
         }
Actions

Also available in: Atom PDF