From daea77ff23db36ac4c81dafa0a0b7089b621e684 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Sun, 9 Aug 2026 17:14:06 -0400 Subject: [PATCH 1/9] dvbs2: fix leaked fec decoder writers Coverity reported a resource leak for the bitcount and errcount writers allocated by opt_writer(). Free them when the FEC decoder helper is destroyed, matching the existing cleanup used by other LeanSDR components. Signed-off-by: Robin Getz --- plugins/channelrx/demoddatv/leansdr/dvbs2.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/channelrx/demoddatv/leansdr/dvbs2.h b/plugins/channelrx/demoddatv/leansdr/dvbs2.h index 03061a5c7..4a2ff11b4 100644 --- a/plugins/channelrx/demoddatv/leansdr/dvbs2.h +++ b/plugins/channelrx/demoddatv/leansdr/dvbs2.h @@ -3292,6 +3292,12 @@ struct s2_fecdec_helper : runnable { free(command); killall(); // also deletes pools[mc][sf].procs if necessary + if (bitcount) { + delete bitcount; + } + if (errcount) { + delete errcount; + } } void run() From c88cc7236a4c8b3362383071168d218bad2fc022 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Sun, 9 Aug 2026 17:33:58 -0400 Subject: [PATCH 2/9] freqscanner: simplify frequency list handling SWGFreqScannerSettings is newly created without a frequency list, so there is no need to check for or copy into an existing list. Transfer the newly created frequency list directly to the settings object. The previous copy path left the newly allocated QList unowned when an existing frequency list was present. This leaked the list because the assignment copied its contents rather than transferring ownership. This also resolves that resource leak identified by Coverity. Signed-off-by: Robin Getz --- plugins/channelrx/freqscanner/freqscanner.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/plugins/channelrx/freqscanner/freqscanner.cpp b/plugins/channelrx/freqscanner/freqscanner.cpp index 54affd72e..9c4f903b5 100644 --- a/plugins/channelrx/freqscanner/freqscanner.cpp +++ b/plugins/channelrx/freqscanner/freqscanner.cpp @@ -1301,11 +1301,7 @@ void FreqScanner::webapiFormatChannelSettings( } if (channelSettingsKeys.contains("frequencies") || force) { QList *frequencies = createFrequencyList(settings); - if (swgFreqScannerSettings->getFrequencies()) { - *swgFreqScannerSettings->getFrequencies() = *frequencies; - } else { - swgFreqScannerSettings->setFrequencies(frequencies); - } + swgFreqScannerSettings->setFrequencies(frequencies); } if (channelSettingsKeys.contains("rgbColor") || force) { From 164a35b08329a572953c8dcb6394a847994d3c39 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Sun, 9 Aug 2026 17:41:39 -0400 Subject: [PATCH 3/9] map: release aircraft state with map item Add a destructor to ObjectMapItem to release its owned m_aircraftState. ObjectMapItem allocates m_aircraftState when aircraft state is present, but had no corresponding cleanup when the map item was destroyed. Coverity reported the allocation as a constructor/destructor resource leak. Signed-off-by: Robin Getz --- plugins/feature/map/mapitem.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/feature/map/mapitem.h b/plugins/feature/map/mapitem.h index e3220fee8..6084384f7 100644 --- a/plugins/feature/map/mapitem.h +++ b/plugins/feature/map/mapitem.h @@ -78,6 +78,12 @@ public: { update(mapItem); } + + ~ObjectMapItem() + { + delete m_aircraftState; + } + void update(SWGSDRangel::SWGMapItem *mapItem) override; protected: From 9039a6ec9d02217c2ed8d1d8b8a294c4eb55e52e Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Sun, 9 Aug 2026 18:00:17 -0400 Subject: [PATCH 4/9] chanalyzer: release FFT filter in RRCHelper destructor Delete the FFT-based RRC filter when RRCHelper is destroyed. RRCHelper allocates m_filterFFT but the destructor did not release it, leaking the filter for every RRCHelper instance. Coverity flagged the missing destructor cleanup as a CTOR_DTOR_LEAK. The existing destructor already releases the FIR filter and sample buffer, making the FFT filter cleanup part of the same ownership path. Signed-off-by: Robin Getz --- plugins/channelrx/chanalyzer/chanalyzersink.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/channelrx/chanalyzer/chanalyzersink.cpp b/plugins/channelrx/chanalyzer/chanalyzersink.cpp index 4ef49fddf..017be9273 100644 --- a/plugins/channelrx/chanalyzer/chanalyzersink.cpp +++ b/plugins/channelrx/chanalyzer/chanalyzersink.cpp @@ -41,6 +41,7 @@ ChannelAnalyzerSink::RRCHelper::RRCHelper(int flen) : ChannelAnalyzerSink::RRCHelper::~RRCHelper() { delete m_filterFIR; + delete m_filterFFT; delete[] m_buffer; } From 874fbbd65dd4d7a2edb350c48be7fb861de28b9b Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Sun, 9 Aug 2026 18:10:33 -0400 Subject: [PATCH 5/9] dvbs2: fix leaked fec decoder writers Free the bitcount and errcount pipe writers owned by s2_fecdec. The writers are allocated by opt_writer() but were not released when s2_fecdec was destroyed, causing the allocations to leak. Coverity reported a CTOR_DTOR_LEAK in the s2_fecdec constructor, identifying the allocations without corresponding destructor cleanup. Signed-off-by: Robin Getz --- plugins/channelrx/demoddatv/leansdr/dvbs2.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/plugins/channelrx/demoddatv/leansdr/dvbs2.h b/plugins/channelrx/demoddatv/leansdr/dvbs2.h index 4a2ff11b4..d4da05228 100644 --- a/plugins/channelrx/demoddatv/leansdr/dvbs2.h +++ b/plugins/channelrx/demoddatv/leansdr/dvbs2.h @@ -2979,6 +2979,16 @@ struct s2_fecdec : runnable } } + ~s2_fecdec() + { + if (bitcount) { + delete bitcount; + } + if (errcount) { + delete errcount; + } + } + void run() { while (in.readable() >= 1 && out.writable() >= 1 && From 4498bc62b24d6847ed6f4cd54b5c388b23c8ed1e Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Sun, 9 Aug 2026 18:22:34 -0400 Subject: [PATCH 6/9] udpsource: avoid leaking sample rate correction messages Only allocate `MsgSampleRateCorrection` when a feedback message queue is available. The message was previously allocated before checking `m_autoRWBalance` and `m_feedbackMessageQueue`. When either condition was false, the message was never queued and its allocation was leaked. Coverity CID 652413 reported a `RESOURCE_LEAK` after tracing the allocation from `MsgSampleRateCorrection::create()` to the point where the local pointer went out of scope without being transferred to the feedback queue. Signed-off-by: Robin Getz --- plugins/channeltx/udpsource/udpsourceudphandler.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/channeltx/udpsource/udpsourceudphandler.cpp b/plugins/channeltx/udpsource/udpsourceudphandler.cpp index 9a4605093..8f4aecf0a 100644 --- a/plugins/channeltx/udpsource/udpsourceudphandler.cpp +++ b/plugins/channeltx/udpsource/udpsourceudphandler.cpp @@ -223,9 +223,11 @@ void UDPSourceUDPHandler::advanceReadPointer(int nbBytes) float dd = d - m_d; // derivative float c = (d / 15.0) + (dd / 20.0); // damping and scaling c = c < -0.05 ? -0.05 : c > 0.05 ? 0.05 : c; // limit - UDPSourceMessages::MsgSampleRateCorrection *msg = UDPSourceMessages::MsgSampleRateCorrection::create(c, d); if (m_autoRWBalance && m_feedbackMessageQueue) { + // create and immediately transfer ownership to queue + UDPSourceMessages::MsgSampleRateCorrection *msg = + UDPSourceMessages::MsgSampleRateCorrection::create(c, d); m_feedbackMessageQueue->push(msg); } From c29e4911949e39f92216d4c32a9b165a49c9aa5f Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Sun, 9 Aug 2026 19:35:41 -0400 Subject: [PATCH 7/9] visa: close dynamically loaded VISA library Unload the dynamically loaded VISA library when the VISA object is destroyed and ensure radio astronomy VISA sessions are closed first. Coverity reported a resource leak because `visaLibrary` was loaded with `LoadLibrary`/`dlopen` but was never released. It also identified uninitialized VISA function pointers and the library handle. Initialize the remaining pointers, add platform-specific library cleanup, and close all radio astronomy instrument sessions before releasing the default VISA resource manager. The other VISA users were reviewed to verify that their sessions and default resource managers are also closed before their VISA objects are destroyed. The library is only unloaded when no default resource manager session remains active, avoiding unloading the VISA library while it is still in use. Signed-off-by: Robin Getz --- .../radioastronomy/radioastronomyworker.cpp | 10 +++++++++ sdrbase/util/visa.cpp | 21 +++++++++++++++++++ sdrbase/util/visa.h | 2 ++ 3 files changed, 33 insertions(+) diff --git a/plugins/channelrx/radioastronomy/radioastronomyworker.cpp b/plugins/channelrx/radioastronomy/radioastronomyworker.cpp index 17066831b..6c7346571 100644 --- a/plugins/channelrx/radioastronomy/radioastronomyworker.cpp +++ b/plugins/channelrx/radioastronomy/radioastronomyworker.cpp @@ -42,6 +42,16 @@ RadioAstronomyWorker::RadioAstronomyWorker(RadioAstronomy* radioAstronomy) : RadioAstronomyWorker::~RadioAstronomyWorker() { m_inputMessageQueue.clear(); + + for (int i = 0; i < RADIOASTRONOMY_SENSORS; i++) + { + if (m_session[i] != VI_NULL) + { + m_visa.close(m_session[i]); + m_session[i] = VI_NULL; + } + } + m_visa.closeDefault(); } diff --git a/sdrbase/util/visa.cpp b/sdrbase/util/visa.cpp index 4db92081b..49b09491f 100644 --- a/sdrbase/util/visa.cpp +++ b/sdrbase/util/visa.cpp @@ -33,6 +33,9 @@ VISA::VISA() : viClose(nullptr), viPrintf(nullptr), viScanf(nullptr), + viFindRsrc(nullptr), + viFindNext(nullptr), + visaLibrary(nullptr), m_available(false) { #ifdef _MSC_VER @@ -62,6 +65,14 @@ VISA::VISA() : } } +VISA::~VISA() +{ + if (visaLibrary && (m_defaultRM == 0)) { + libraryClose(visaLibrary); + visaLibrary = nullptr; + } +} + ViSession VISA::openDefault() { if (isAvailable() && (m_defaultRM == 0)) @@ -267,6 +278,11 @@ void *VISA::libraryFunc(void *library, const char *function) return GetProcAddress ((HMODULE)library, function); } +void VISA::libraryClose(void *library) +{ + FreeLibrary((HMODULE)library); +} + #else void *VISA::libraryOpen(const char *filename) @@ -279,4 +295,9 @@ void *VISA::libraryFunc(void *library, const char *function) return dlsym (library, function); } +void VISA::libraryClose(void *library) +{ + dlclose(library); +} + #endif diff --git a/sdrbase/util/visa.h b/sdrbase/util/visa.h index 5beeb2ae6..6ad64dab1 100644 --- a/sdrbase/util/visa.h +++ b/sdrbase/util/visa.h @@ -74,6 +74,7 @@ public: ViStatus (*viFindNext) (ViSession vi, ViChar desc[]); VISA(); + ~VISA(); ViSession openDefault(); void closeDefault(); @@ -100,6 +101,7 @@ protected: void *libraryOpen(const char *filename); void *libraryFunc(void *library, const char *function); + void libraryClose(void *library); }; #endif // INCLUDE_VISA_H From edd7092444b24cbeda4522e7c0c516e2ad0c2823 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Sun, 9 Aug 2026 19:45:52 -0400 Subject: [PATCH 8/9] leansdr: fix pipewriter leaks in s2_deframer Add a destructor to s2_deframer to release the pipewriter objects owned by state_out and locktime_out. opt_writer() allocates these pipewriters dynamically when the corresponding output pipe is provided. Without a destructor, the objects were leaked when s2_deframer was destroyed. Coverity reported CTOR_DTOR_LEAK findings for state_out and locktime_out. The existing leansdr code was reviewed and confirmed that other users of opt_writer() explicitly delete the resulting pipewriters in their destructors, so s2_deframer was missing the corresponding cleanup. Signed-off-by: Robin Getz --- plugins/channelrx/demoddatv/leansdr/dvbs2.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/plugins/channelrx/demoddatv/leansdr/dvbs2.h b/plugins/channelrx/demoddatv/leansdr/dvbs2.h index d4da05228..d1220c643 100644 --- a/plugins/channelrx/demoddatv/leansdr/dvbs2.h +++ b/plugins/channelrx/demoddatv/leansdr/dvbs2.h @@ -4080,6 +4080,16 @@ struct s2_deframer : runnable { } + ~s2_deframer() + { + if (state_out) { + delete state_out; + } + if (locktime_out) { + delete locktime_out; + } + } + void run() { while (in.readable() >= 1 && out.writable() >= MAX_TS_PER_BBFRAME && From ccc140fbf7a659ff54a42e6dd0d9c36ff05803cb Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Sun, 9 Aug 2026 19:53:20 -0400 Subject: [PATCH 9/9] vorlocalizer: fix leaked report message Create and populate the VOR service report message as before, but delete it when the feature message queue is not available. The message is normally transferred to `m_msgQueueToFeature` for ownership, but when the queue is null there is no owner and the allocated message leaked. Coverity reported the leak as CID 652338 (`RESOURCE_LEAK`) while analyzing `VorLocalizerWorker::rrNextTurn()`. Review of the surrounding message queue usage confirmed that queued messages are owned by the queue, making the missing-queue path the unhandled ownership case. Signed-off-by: Robin Getz --- plugins/feature/vorlocalizer/vorlocalizerworker.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/feature/vorlocalizer/vorlocalizerworker.cpp b/plugins/feature/vorlocalizer/vorlocalizerworker.cpp index e12cf071b..49d2219fc 100644 --- a/plugins/feature/vorlocalizer/vorlocalizerworker.cpp +++ b/plugins/feature/vorlocalizer/vorlocalizerworker.cpp @@ -752,5 +752,7 @@ void VorLocalizerWorker::rrNextTurn() if (m_msgQueueToFeature) { m_msgQueueToFeature->push(msg); + } else { + delete msg; } }