Blob Blame History Raw
From c8d43e94583cde7c5289d8206e658f2bcfce389a Mon Sep 17 00:00:00 2001
From: Coiby Xu <coiby.xu@gmail.com>
Date: Fri, 11 Jun 2021 11:15:06 +0800
Subject: [PATCH 3/8] fix RESOURCE_LEAK errors detected by covscan in
 src/dmidecodemodule.c

Fix the following errors found by covscan,

    Error: RESOURCE_LEAK (CWE-772): [#def1]
    python-dmidecode-3.12.2/src/dmidecodemodule.c:274: alloc_fn: Storage is returned from allocation function "xmlNewNode".
    python-dmidecode-3.12.2/src/dmidecodemodule.c:274: var_assign: Assigning: "dmixml_n" = storage returned from "xmlNewNode(NULL, (xmlChar *)"dmidecode")".
    python-dmidecode-3.12.2/src/dmidecodemodule.c:284: leaked_storage: Variable "dmixml_n" going out of scope leaks the storage it points to.
    #  282|           if( (group_n = load_mappingxml(opt)) == NULL) {
    #  283|                   // Exception already set by calling function
    #  284|->                 return NULL;
    #  285|           }
    #  286|

    Error: RESOURCE_LEAK (CWE-772): [#def2]
    python-dmidecode-3.12.2/src/dmidecodemodule.c:321: alloc_fn: Storage is returned from allocation function "log_retrieve".
    python-dmidecode-3.12.2/src/dmidecodemodule.c:321: var_assign: Assigning: "err" = storage returned from "log_retrieve(opt->logdata, 3)".
    python-dmidecode-3.12.2/src/dmidecodemodule.c:323: leaked_storage: Variable "err" going out of scope leaks the storage it points to.
    #  321|                           char *err = log_retrieve(opt->logdata, LOG_ERR);
    #  322|                           log_clear_partial(opt->logdata, LOG_ERR, 0);
    #  323|->                         PyReturnError(PyExc_RuntimeError, "Invalid type id '%s' -- %s", typeid, err);
    #  324|                   }
    #  325|

    Error: RESOURCE_LEAK (CWE-772): [#def3]
    python-dmidecode-3.12.2/src/dmidecodemodule.c:388: alloc_fn: Storage is returned from allocation function "xmlNewNode".
    python-dmidecode-3.12.2/src/dmidecodemodule.c:388: var_assign: Assigning: "dmixml_n" = storage returned from "xmlNewNode(NULL, (xmlChar *)"dmidecode")".
    python-dmidecode-3.12.2/src/dmidecodemodule.c:397: leaked_storage: Variable "dmixml_n" going out of scope leaks the storage it points to.
    #  395|           // Fetch the Mapping XML file
    #  396|           if( load_mappingxml(opt) == NULL) {
    #  397|->                 return NULL;
    #  398|           }
    #  399|

    Error: RESOURCE_LEAK (CWE-772): [#def4]
    python-dmidecode-3.12.2/src/dmidecodemodule.c:823: alloc_fn: Storage is returned from allocation function "malloc".
    python-dmidecode-3.12.2/src/dmidecodemodule.c:823: var_assign: Assigning: "opt" = storage returned from "malloc(58UL)".
    python-dmidecode-3.12.2/src/dmidecodemodule.c:824: noescape: Resource "opt" is not freed or pointed-to in "memset". [Note: The source code implementation of the function has been overridden by a builtin model.]
    python-dmidecode-3.12.2/src/dmidecodemodule.c:825: noescape: Resource "opt" is not freed or pointed-to in "init".
    python-dmidecode-3.12.2/src/dmidecodemodule.c:833: leaked_storage: Variable "opt" going out of scope leaks the storage it points to.
    #  831|   #endif
    #  832|           if (module == NULL)
    #  833|->                 MODINITERROR;
    #  834|
    #  835|           version = PYTEXT_FROMSTRING(VERSION);

Note for "Error: RESOURCE_LEAK (CWE-772): [#def2]", we have to call  _PyReturnError directly so we can free the memory before return.

Signed-off-by: Coiby Xu <coiby.xu@gmail.com>
---
 src/dmidecodemodule.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c
index b31c002..b73811e 100644
--- a/src/dmidecodemodule.c
+++ b/src/dmidecodemodule.c
@@ -280,6 +280,7 @@ xmlNode *__dmidecode_xml_getsection(options *opt, const char *section) {
 
         // Fetch the Mapping XML file
         if( (group_n = load_mappingxml(opt)) == NULL) {
+                xmlFreeNode(dmixml_n);
                 // Exception already set by calling function
                 return NULL;
         }
@@ -320,7 +321,9 @@ xmlNode *__dmidecode_xml_getsection(options *opt, const char *section) {
                 if(opt->type == -1) {
                         char *err = log_retrieve(opt->logdata, LOG_ERR);
                         log_clear_partial(opt->logdata, LOG_ERR, 0);
-                        PyReturnError(PyExc_RuntimeError, "Invalid type id '%s' -- %s", typeid, err);
+                        _pyReturnError(PyExc_RuntimeError, "Invalid type id '%s' -- %s", typeid, err);
+                        free(err);
+                        return NULL;
                 }
 
                 // Parse the DMI data and put the result into dmixml_n node chain.
@@ -394,6 +397,7 @@ xmlNode *__dmidecode_xml_gettypeid(options *opt, int typeid)
 
         // Fetch the Mapping XML file
         if( load_mappingxml(opt) == NULL) {
+                xmlFreeNode(dmixml_n);
                 return NULL;
         }
 
@@ -829,8 +833,10 @@ initdmidecodemod(void)
         module = Py_InitModule3((char *)"dmidecodemod", DMIDataMethods,
                                 "Python extension module for dmidecode");
 #endif
-        if (module == NULL)
+        if (module == NULL) {
+                free(opt);
                 MODINITERROR;
+        }
 
         version = PYTEXT_FROMSTRING(VERSION);
         Py_INCREF(version);
-- 
2.31.1