From fe070b4f564b3727758b408477b7d4c7cb822040 Mon Sep 17 00:00:00 2001
From: Vladimir Stoilov <vladimir@safing.io>
Date: Mon, 25 Nov 2024 14:03:35 +0200
Subject: [PATCH] Feature/kext default action drop (#1747)

* [windows_kext] Make default action to drop

* [windows_kext] Minor improvments
---
 windows_kext/driver/src/ale_callouts.rs            |  3 +++
 windows_kext/driver/src/packet_callouts.rs         |  7 +++++--
 windows_kext/wdk/src/filter_engine/callout_data.rs | 11 ++++-------
 windows_kext/wdk/src/filter_engine/classify.rs     |  5 +++++
 windows_kext/wdk/src/filter_engine/ffi.rs          |  2 +-
 5 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/windows_kext/driver/src/ale_callouts.rs b/windows_kext/driver/src/ale_callouts.rs
index ed478938..51c5cc30 100644
--- a/windows_kext/driver/src/ale_callouts.rs
+++ b/windows_kext/driver/src/ale_callouts.rs
@@ -105,6 +105,9 @@ pub fn ale_layer_connect_v6(data: CalloutData) {
 }
 
 fn ale_layer_auth(mut data: CalloutData, ale_data: AleLayerData) {
+    // Make the default path as drop.
+    data.block_and_absorb();
+
     let Some(device) = crate::entry::get_device() else {
         return;
     };
diff --git a/windows_kext/driver/src/packet_callouts.rs b/windows_kext/driver/src/packet_callouts.rs
index 4609aad0..1e8c28f1 100644
--- a/windows_kext/driver/src/packet_callouts.rs
+++ b/windows_kext/driver/src/packet_callouts.rs
@@ -110,9 +110,12 @@ fn ip_packet_layer(
     interface_index: u32,
     sub_interface_index: u32,
 ) {
+    // Make the default path as drop.
+    data.block_and_absorb();
+
     // Block all fragment data. No easy way to keep track of the origin and they are rarely used.
     if data.is_fragment_data() {
-        data.action_block();
+        data.block_and_absorb();
         crate::err!("blocked fragment packet");
         return;
     }
@@ -147,7 +150,7 @@ fn ip_packet_layer(
         } {
             Ok(key) => key,
             Err(err) => {
-                crate::dbg!("failed to get key from nbl: {}", err);
+                crate::err!("failed to get key from nbl: {}", err);
                 return;
             }
         };
diff --git a/windows_kext/wdk/src/filter_engine/callout_data.rs b/windows_kext/wdk/src/filter_engine/callout_data.rs
index abb5e318..ff155dd1 100644
--- a/windows_kext/wdk/src/filter_engine/callout_data.rs
+++ b/windows_kext/wdk/src/filter_engine/callout_data.rs
@@ -161,24 +161,28 @@ impl<'a> CalloutData<'a> {
     pub fn action_permit(&mut self) {
         unsafe {
             (*self.classify_out).action_permit();
+            (*self.classify_out).clear_absorb_flag();
         }
     }
 
     pub fn action_continue(&mut self) {
         unsafe {
             (*self.classify_out).action_continue();
+            (*self.classify_out).clear_absorb_flag();
         }
     }
 
     pub fn action_block(&mut self) {
         unsafe {
             (*self.classify_out).action_block();
+            (*self.classify_out).clear_absorb_flag();
         }
     }
 
     pub fn action_none(&mut self) {
         unsafe {
             (*self.classify_out).set_none();
+            (*self.classify_out).clear_absorb_flag();
         }
     }
 
@@ -198,13 +202,6 @@ impl<'a> CalloutData<'a> {
         self.get_value_u32(flags_index) & FWP_CONDITION_FLAG_IS_REAUTHORIZE > 0
     }
 
-    pub fn parmit_and_absorb(&mut self) {
-        unsafe {
-            (*self.classify_out).action_permit();
-            (*self.classify_out).set_absorb();
-        }
-    }
-
     pub fn get_callout_id(&self) -> usize {
         self.callout_id
     }
diff --git a/windows_kext/wdk/src/filter_engine/classify.rs b/windows_kext/wdk/src/filter_engine/classify.rs
index 1acff2ed..6d5b9b05 100644
--- a/windows_kext/wdk/src/filter_engine/classify.rs
+++ b/windows_kext/wdk/src/filter_engine/classify.rs
@@ -80,6 +80,11 @@ impl ClassifyOut {
         self.flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB;
     }
 
+    // Removes the absorb flag.
+    pub fn clear_absorb_flag(&mut self) {
+        self.flags &= !FWPS_CLASSIFY_OUT_FLAG_ABSORB;
+    }
+
     // Clear the write flag permission. Next filter in the chain will not change the action.
     pub fn clear_write_flag(&mut self) {
         self.rights &= !FWPS_RIGHT_ACTION_WRITE;
diff --git a/windows_kext/wdk/src/filter_engine/ffi.rs b/windows_kext/wdk/src/filter_engine/ffi.rs
index 45103272..bf5fa361 100644
--- a/windows_kext/wdk/src/filter_engine/ffi.rs
+++ b/windows_kext/wdk/src/filter_engine/ffi.rs
@@ -62,7 +62,7 @@ pub(crate) fn register_sublayer(
         sublayer.displayData.name = name.as_ptr() as _;
         sublayer.displayData.description = description.as_ptr() as _;
         sublayer.flags = 0;
-        sublayer.weight = 0xFFFF;
+        sublayer.weight = 0xFFFF; // Set to Max value. Weight compared to other sublayers.
 
         let status = FwpmSubLayerAdd0(filter_engine_handle, &sublayer, core::ptr::null_mut());
         check_ntstatus(status as i32)?;