From f312165663ceb445738c722d3466ef6cdb4610c4 Mon Sep 17 00:00:00 2001 From: EylonKrause Date: Wed, 24 Jun 2026 13:00:38 +0300 Subject: [PATCH] fix: close XML file on parse-error paths to avoid FILE* leak ncclTopoGetXmlFromFile, ncclTopoGetXmlGraphFromFile and ncclTopoDumpXmlToFile only called fclose() on the success path; any error from xmlLoadSub/ncclTopoDumpXmlRec returned via NCCLCHECK before the fclose, leaking the FILE* (and its fd) on every malformed NCCL_TOPO_FILE/NCCL_GRAPH_FILE. Close the file first, then propagate. Signed-off-by: EylonKrause --- src/graph/xml.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/graph/xml.cc b/src/graph/xml.cc index 4520bff5ad..2e38fd9ae4 100644 --- a/src/graph/xml.cc +++ b/src/graph/xml.cc @@ -298,8 +298,9 @@ ncclResult_t ncclTopoDumpXmlToFile(const char* xmlTopoFile, struct ncclXml* xml) INFO(NCCL_GRAPH | NCCL_ENV, "Unable to open %s, not dumping topology.", xmlTopoFile); return ncclSuccess; } - NCCLCHECK(ncclTopoDumpXmlRec(0, file, xml->nodes)); + ncclResult_t res = ncclTopoDumpXmlRec(0, file, xml->nodes); fclose(file); + NCCLCHECK(res); return ncclSuccess; } @@ -418,8 +419,9 @@ ncclResult_t ncclTopoGetXmlFromFile(const char* xmlTopoFile, struct ncclXml* xml INFO(NCCL_GRAPH, "Loading topology file %s", xmlTopoFile); struct xmlHandler handlers[] = {{"system", ncclTopoXmlLoadSystem}}; xml->maxIndex = 0; - NCCLCHECK(xmlLoadSub(file, xml, NULL, handlers, 1)); + ncclResult_t res = xmlLoadSub(file, xml, NULL, handlers, 1); fclose(file); + NCCLCHECK(res); #elif NCCL_OS_WINDOWS (void)xmlTopoFile; (void)xml; @@ -1259,8 +1261,9 @@ ncclResult_t ncclTopoGetXmlGraphFromFile(const char* xmlGraphFile, struct ncclXm } struct xmlHandler handlers[] = {{"graphs", ncclTopoXmlGraphLoadGraphs}}; xml->maxIndex = 0; - NCCLCHECK(xmlLoadSub(file, xml, NULL, handlers, 1)); + ncclResult_t res = xmlLoadSub(file, xml, NULL, handlers, 1); fclose(file); + NCCLCHECK(res); return ncclSuccess; }