From dcfe68c40687031273cf90d09d8ca1bf231c3f5e Mon Sep 17 00:00:00 2001 From: tomasz-karczewski-red Date: Thu, 29 Jan 2026 09:36:53 +0100 Subject: [PATCH] ARRISEOS-48521 OCDM: protect against double-delete There are some scenarios where OCDM::Deinitialize seems to be run more than once in parallel (likely on Thunder shutdown). The change protects against double-release/use-after-free bugs. --- OpenCDMi/OCDM.cpp | 10 ++++++++-- OpenCDMi/OCDM.h | 3 +++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/OpenCDMi/OCDM.cpp b/OpenCDMi/OCDM.cpp index a867b3ea43..1cb0851e1b 100644 --- a/OpenCDMi/OCDM.cpp +++ b/OpenCDMi/OCDM.cpp @@ -109,6 +109,7 @@ namespace Plugin { ForceLinkingOfOpenCDM(); #endif + std::lock_guard lock {_serviceInitMutex}; string message; ASSERT(service != nullptr); @@ -157,8 +158,13 @@ namespace Plugin { /*virtual*/ void OCDM::Deinitialize(PluginHost::IShell* service) { + std::lock_guard lock {_serviceInitMutex}; ASSERT(_service == service); + if (_service == nullptr) { + TRACE(Trace::Error, (_T("OCDM::Deinitialize called with null _service; will be skipped. %d"), __LINE__)); + return; + } _service->Unregister(&_notification); if(_opencdmi != nullptr) { @@ -169,7 +175,7 @@ namespace Plugin { } _opencdmi->Unregister(&_notification); - _opencdmi->Deinitialize(service); + _opencdmi->Deinitialize(_service); RPC::IRemoteConnection* connection(_service->RemoteConnection(_connectionId)); UnregisterAll(); @@ -193,7 +199,7 @@ namespace Plugin { } } - PluginHost::ISubSystem* subSystem = service->SubSystems(); + PluginHost::ISubSystem* subSystem = _service->SubSystems(); if (subSystem != nullptr) { if(subSystem->IsActive(PluginHost::ISubSystem::DECRYPTION) == true) { diff --git a/OpenCDMi/OCDM.h b/OpenCDMi/OCDM.h index a78969b2b0..73c5b42426 100644 --- a/OpenCDMi/OCDM.h +++ b/OpenCDMi/OCDM.h @@ -20,6 +20,8 @@ #ifndef __OPENCDMI_H #define __OPENCDMI_H +#include + #include "Module.h" #include #include @@ -225,6 +227,7 @@ namespace Plugin { Exchange::IContentDecryption* _opencdmi; Exchange::IMemory* _memory; Core::Sink _notification; + std::recursive_mutex _serviceInitMutex; }; } //namespace Plugin