From c8d43e94583cde7c5289d8206e658f2bcfce389a Mon Sep 17 00:00:00 2001 From: Coiby Xu 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 --- 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