From f923eda87854adb2d245f43ba3656b0fb46fe7c1 Mon Sep 17 00:00:00 2001
From: chenjiayi <chenjiayi22@huawei.com>
Date: Fri, 3 Nov 2023 01:47:16 +0800
Subject: [PATCH 028/103] fix(devmaster): check the validity of kmod context
 during new method

The kmod_sys::kmod_new may return a null pointer. Check the validity
of the pointer before using it to constuct the kmod instance.
---
 exts/devmaster/src/lib/builtin/kmod.rs | 21 +++++++++++++++++----
 libs/kmod_rs/src/lib.rs                | 17 ++++++++---------
 2 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/exts/devmaster/src/lib/builtin/kmod.rs b/exts/devmaster/src/lib/builtin/kmod.rs
index ac73d1bb..cf718d41 100644
--- a/exts/devmaster/src/lib/builtin/kmod.rs
+++ b/exts/devmaster/src/lib/builtin/kmod.rs
@@ -24,14 +24,14 @@ use std::rc::Rc;
 /// kmod builtin command
 pub(crate) struct Kmod {
     /// kmod struct
-    kernel_module: Rc<RefCell<kmod_rs::LibKmod>>,
+    kernel_module: Option<Rc<RefCell<kmod_rs::LibKmod>>>,
 }
 
 impl Kmod {
     /// create Kmod
     pub(crate) fn new() -> Kmod {
         Kmod {
-            kernel_module: Rc::new(RefCell::new(kmod_rs::LibKmod::new())),
+            kernel_module: kmod_rs::LibKmod::new().map(|inner| Rc::new(RefCell::new(inner))),
         }
     }
 }
@@ -53,7 +53,8 @@ impl Builtin for Kmod {
     ) -> Result<bool> {
         let device = exec_unit.get_device();
 
-        if self.kernel_module.borrow().is_ctx_null() {
+        if self.kernel_module.is_none() {
+            log::error!("Kmod context is not loaded.");
             return Ok(true);
         }
 
@@ -72,6 +73,8 @@ impl Builtin for Kmod {
             if !modalias.is_empty() {
                 if let Err(e) = self
                     .kernel_module
+                    .as_ref()
+                    .unwrap()
                     .borrow_mut()
                     .module_load_and_warn(&modalias, false)
                 {
@@ -82,6 +85,8 @@ impl Builtin for Kmod {
             for i in 2..argc {
                 if let Err(e) = self
                     .kernel_module
+                    .as_ref()
+                    .unwrap()
                     .borrow_mut()
                     .module_load_and_warn(&argv[i as usize], false)
                 {
@@ -94,7 +99,13 @@ impl Builtin for Kmod {
 
     /// builtin init function
     fn init(&self) {
-        if let Err(e) = self.kernel_module.borrow_mut().load_resources() {
+        if let Err(e) = self
+            .kernel_module
+            .as_ref()
+            .unwrap()
+            .borrow_mut()
+            .load_resources()
+        {
             log::error!("Load resources failed! {}", e);
         }
     }
@@ -105,6 +116,8 @@ impl Builtin for Kmod {
     /// check whether builtin command should reload
     fn should_reload(&self) -> bool {
         self.kernel_module
+            .as_ref()
+            .unwrap()
             .borrow_mut()
             .validate_resources()
             .map_or(false, |e| {
diff --git a/libs/kmod_rs/src/lib.rs b/libs/kmod_rs/src/lib.rs
index d0efabc5..f95cd32a 100644
--- a/libs/kmod_rs/src/lib.rs
+++ b/libs/kmod_rs/src/lib.rs
@@ -73,21 +73,20 @@ impl Drop for LibKmod {
     }
 }
 
-impl Default for LibKmod {
-    fn default() -> Self {
-        Self::new()
-    }
-}
-
 impl LibKmod {
     /// Create libkmod
-    pub fn new() -> LibKmod {
+    pub fn new() -> Option<LibKmod> {
         let c = unsafe { kmod_sys::kmod_new(std::ptr::null(), std::ptr::null()) };
-        LibKmod {
+
+        if c.is_null() {
+            return None;
+        }
+
+        Some(LibKmod {
             ctx: c,
             kmod_list_head: ptr::null::<kmod_sys::kmod_list>() as *mut kmod_sys::kmod_list,
             module: ptr::null::<kmod_sys::kmod_module>() as *mut kmod_sys::kmod_module,
-        }
+        })
     }
 
     /// Create KmodListIter with internal members
-- 
2.33.0

