From 0dc52619b84a3d5e892032195ad6bdd9de0d2892 Mon Sep 17 00:00:00 2001 From: dwolav200 Date: Mon, 20 Jul 2026 11:31:20 -0400 Subject: [PATCH 1/7] RDKEMW-21962 : ctrlm-main - Use of potentially dangerous function --- src/ctrlm_utils.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/ctrlm_utils.cpp b/src/ctrlm_utils.cpp index 83dfba02..a085c713 100644 --- a/src/ctrlm_utils.cpp +++ b/src/ctrlm_utils.cpp @@ -293,21 +293,27 @@ void ctrlm_print_controller_status(const char *prefix, ctrlm_controller_status_t ERR_CHK(safec_rc); } else { time_binding_str[0] = '\0'; - strftime(time_binding_str, 20, "%F %T", localtime((time_t *)&status->time_binding)); + struct tm time_info; + localtime_r((time_t *)&status->time_binding, &time_info); + strftime(time_binding_str, 20, "%F %T", &time_info); } if(status->time_last_key == 0) { safec_rc = strcpy_s(time_last_key_str, sizeof(time_last_key_str), "NEVER"); ERR_CHK(safec_rc); } else { time_last_key_str[0] = '\0'; - strftime(time_last_key_str, 20, "%F %T", localtime((time_t *)&status->time_last_key)); + struct tm time_info; + localtime_r((time_t *)&status->time_last_key, &time_info); + strftime(time_last_key_str, 20, "%F %T", &time_info); } if(status->time_battery_update == 0) { safec_rc = strcpy_s(time_battery_update_str, sizeof(time_battery_update_str), "NEVER"); ERR_CHK(safec_rc); } else { time_battery_update_str[0] = '\0'; - strftime(time_battery_update_str, 20, "%F %T", localtime((time_t *)&status->time_battery_update)); + struct tm time_info; + localtime_r((time_t *)&status->time_battery_update, &time_info); + strftime(time_battery_update_str, 20, "%F %T", &time_info); } const xlog_args_t xlog_args_info = {.options = XLOG_OPTS_DEFAULT, .color = XLOG_COLOR_NONE, .function = prefix, .line = XLOG_LINE_NONE, .level = XLOG_LEVEL_INFO, .id = XLOG_MODULE_ID, .size_max = XLOG_BUF_SIZE_DEFAULT}; From f6302040c390c7193bdfb30ca9e1733c17013c02 Mon Sep 17 00:00:00 2001 From: dwolav200 Date: Mon, 20 Jul 2026 11:47:03 -0400 Subject: [PATCH 2/7] more fixes --- src/database/ctrlm_database.cpp | 3 ++- src/rf4ce/ctrlm_rf4ce_controller.cpp | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/database/ctrlm_database.cpp b/src/database/ctrlm_database.cpp index 2e9e6e5c..f5ea6a2c 100644 --- a/src/database/ctrlm_database.cpp +++ b/src/database/ctrlm_database.cpp @@ -1544,7 +1544,8 @@ void ctrlm_db_print() { ctrlm_db_rf4ce_read_validation_type(*it_network, *it_controller, &validation_type); ctrlm_db_rf4ce_read_time_binding(*it_network, *it_controller, &time_binding); - const tm* loc_time = localtime(&time_binding); + struct tm time_info; + const tm* loc_time = localtime_r(&time_binding, &time_info); if (loc_time != 0) { strftime(time_str, 40, "%x - %I:%M:%S %p", loc_time); } diff --git a/src/rf4ce/ctrlm_rf4ce_controller.cpp b/src/rf4ce/ctrlm_rf4ce_controller.cpp index c298ab9e..a3a2d2d3 100644 --- a/src/rf4ce/ctrlm_rf4ce_controller.cpp +++ b/src/rf4ce/ctrlm_rf4ce_controller.cpp @@ -2783,7 +2783,9 @@ void ctrlm_obj_controller_rf4ce_t::log_binding_for_telemetry() { } else { time_binding_str[0] = '\0'; time_t time_binding = this->time_binding_get(); - strftime(time_binding_str, 20, "%F %T", localtime((time_t *)&time_binding)); + struct tm time_info; + localtime_r(&time_binding, &time_info); + strftime(time_binding_str, 20, "%F %T", &time_info); } XLOGD_INFO("Model <%s>, Binding <%s>, Remote Bound (%u,%u), Time <%s>", product_name_->to_string().c_str(), ctrlm_rcu_binding_type_str(binding_type_), network_id_get(), controller_id_get(), time_binding_str); ctrlm_update_last_key_info(controller_id, CTRLM_KEY_SOURCE_RF, 0, product_name_->to_string().c_str(), false, true); @@ -2794,7 +2796,9 @@ void ctrlm_obj_controller_rf4ce_t::log_unbinding_for_telemetry() { time_t time_unbinding = time(NULL); time_unbinding_str[0] = '\0'; - strftime(time_unbinding_str, 20, "%F %T", localtime((time_t *)&time_unbinding)); + struct tm time_info; + localtime_r(&time_unbinding, &time_info); + strftime(time_unbinding_str, 20, "%F %T", &time_info); XLOGD_INFO("Model <%s>, Remote Unbound (%u,%u), Time <%s>", product_name_->to_string().c_str(), network_id_get(), controller_id_get(), time_unbinding_str); } From 8e9e1d902ac0efa6223af2296b9cb57b2ecc4976 Mon Sep 17 00:00:00 2001 From: dwolav200 Date: Mon, 20 Jul 2026 12:09:11 -0400 Subject: [PATCH 3/7] copilot fixes --- src/ctrlm_utils.cpp | 24 ++++++++++++++++++------ src/rf4ce/ctrlm_rf4ce_controller.cpp | 14 ++++++++++---- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/ctrlm_utils.cpp b/src/ctrlm_utils.cpp index a085c713..31554ec6 100644 --- a/src/ctrlm_utils.cpp +++ b/src/ctrlm_utils.cpp @@ -294,8 +294,12 @@ void ctrlm_print_controller_status(const char *prefix, ctrlm_controller_status_t } else { time_binding_str[0] = '\0'; struct tm time_info; - localtime_r((time_t *)&status->time_binding, &time_info); - strftime(time_binding_str, 20, "%F %T", &time_info); + time_t time_binding = (time_t)status->time_binding; + if(NULL == localtime_r(&time_binding, &time_info)) { + XLOGD_ERROR("Failed to convert time_binding to local time"); + } else { + strftime(time_binding_str, 20, "%F %T", &time_info); + } } if(status->time_last_key == 0) { safec_rc = strcpy_s(time_last_key_str, sizeof(time_last_key_str), "NEVER"); @@ -303,8 +307,12 @@ void ctrlm_print_controller_status(const char *prefix, ctrlm_controller_status_t } else { time_last_key_str[0] = '\0'; struct tm time_info; - localtime_r((time_t *)&status->time_last_key, &time_info); - strftime(time_last_key_str, 20, "%F %T", &time_info); + time_t time_last_key = (time_t)status->time_last_key; + if(NULL == localtime_r(&time_last_key, &time_info)) { + XLOGD_ERROR("Failed to convert time_last_key to local time"); + } else { + strftime(time_last_key_str, 20, "%F %T", &time_info); + } } if(status->time_battery_update == 0) { safec_rc = strcpy_s(time_battery_update_str, sizeof(time_battery_update_str), "NEVER"); @@ -312,8 +320,12 @@ void ctrlm_print_controller_status(const char *prefix, ctrlm_controller_status_t } else { time_battery_update_str[0] = '\0'; struct tm time_info; - localtime_r((time_t *)&status->time_battery_update, &time_info); - strftime(time_battery_update_str, 20, "%F %T", &time_info); + time_t time_battery_update = (time_t)status->time_battery_update; + if(NULL == localtime_r(&time_battery_update, &time_info)) { + XLOGD_ERROR("Failed to convert time_battery_update to local time"); + } else { + strftime(time_battery_update_str, 20, "%F %T", &time_info); + } } const xlog_args_t xlog_args_info = {.options = XLOG_OPTS_DEFAULT, .color = XLOG_COLOR_NONE, .function = prefix, .line = XLOG_LINE_NONE, .level = XLOG_LEVEL_INFO, .id = XLOG_MODULE_ID, .size_max = XLOG_BUF_SIZE_DEFAULT}; diff --git a/src/rf4ce/ctrlm_rf4ce_controller.cpp b/src/rf4ce/ctrlm_rf4ce_controller.cpp index a3a2d2d3..8ae0119d 100644 --- a/src/rf4ce/ctrlm_rf4ce_controller.cpp +++ b/src/rf4ce/ctrlm_rf4ce_controller.cpp @@ -2784,8 +2784,11 @@ void ctrlm_obj_controller_rf4ce_t::log_binding_for_telemetry() { time_binding_str[0] = '\0'; time_t time_binding = this->time_binding_get(); struct tm time_info; - localtime_r(&time_binding, &time_info); - strftime(time_binding_str, 20, "%F %T", &time_info); + if(NULL == localtime_r(&time_binding, &time_info)) { + XLOGD_ERROR("Failed to convert time_binding to local time"); + } else { + strftime(time_binding_str, 20, "%F %T", &time_info); + } } XLOGD_INFO("Model <%s>, Binding <%s>, Remote Bound (%u,%u), Time <%s>", product_name_->to_string().c_str(), ctrlm_rcu_binding_type_str(binding_type_), network_id_get(), controller_id_get(), time_binding_str); ctrlm_update_last_key_info(controller_id, CTRLM_KEY_SOURCE_RF, 0, product_name_->to_string().c_str(), false, true); @@ -2797,8 +2800,11 @@ void ctrlm_obj_controller_rf4ce_t::log_unbinding_for_telemetry() { time_unbinding_str[0] = '\0'; struct tm time_info; - localtime_r(&time_unbinding, &time_info); - strftime(time_unbinding_str, 20, "%F %T", &time_info); + if(NULL == localtime_r(&time_unbinding, &time_info)) { + XLOGD_ERROR("Failed to convert time_unbinding to local time"); + } else { + strftime(time_unbinding_str, 20, "%F %T", &time_info); + } XLOGD_INFO("Model <%s>, Remote Unbound (%u,%u), Time <%s>", product_name_->to_string().c_str(), network_id_get(), controller_id_get(), time_unbinding_str); } From b3b6aef8d66552610f73eb0b0cef066fc6958726 Mon Sep 17 00:00:00 2001 From: dwolav200 Date: Mon, 20 Jul 2026 12:38:08 -0400 Subject: [PATCH 4/7] delete instead of free --- src/thunder/ctrlm_thunder_plugin_powermanager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/thunder/ctrlm_thunder_plugin_powermanager.cpp b/src/thunder/ctrlm_thunder_plugin_powermanager.cpp index e84fa983..56957a9c 100755 --- a/src/thunder/ctrlm_thunder_plugin_powermanager.cpp +++ b/src/thunder/ctrlm_thunder_plugin_powermanager.cpp @@ -37,7 +37,8 @@ ctrlm_thunder_plugin_powermanager_t::ctrlm_thunder_plugin_powermanager_t() : ctr } ctrlm_thunder_plugin_powermanager_t::~ctrlm_thunder_plugin_powermanager_t() { - free(instance); + delete instance; + instance = NULL; } ctrlm_thunder_plugin_powermanager_t *ctrlm_thunder_plugin_powermanager_t::get_instance() { From 7ae17f5c28fc6e3add451b97881e7b7369c31330 Mon Sep 17 00:00:00 2001 From: dwolav200 Date: Mon, 20 Jul 2026 13:13:45 -0400 Subject: [PATCH 5/7] no throw --- src/factory/ctrlmf_audio_capture.cpp | 2 +- src/factory/ctrlmf_audio_playback.cpp | 2 +- src/factory/ctrlmf_mic_test.cpp | 13 +++++++++++-- src/rf4ce/ctrlm_rf4ce_network.cpp | 4 ++-- src/voice/ctrlm_voice_obj.cpp | 4 +--- 5 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/factory/ctrlmf_audio_capture.cpp b/src/factory/ctrlmf_audio_capture.cpp index 0d76772a..1b1087de 100644 --- a/src/factory/ctrlmf_audio_capture.cpp +++ b/src/factory/ctrlmf_audio_capture.cpp @@ -48,7 +48,7 @@ static ctrlmf_audio_cap_global_t g_audio_cap; bool ctrlmf_audio_capture_init(uint32_t audio_frame_size, bool *has_local_mic_tap) { - g_audio_cap.obj_ctrlm = new Iarm::ControlManager::ctrlm_iarm_client_control_manager_t; + g_audio_cap.obj_ctrlm = new(std::nothrow) Iarm::ControlManager::ctrlm_iarm_client_control_manager_t; if(g_audio_cap.obj_ctrlm == NULL) { XLOGD_ERROR("out of memory"); diff --git a/src/factory/ctrlmf_audio_playback.cpp b/src/factory/ctrlmf_audio_playback.cpp index 498e3caa..7c8bbeac 100644 --- a/src/factory/ctrlmf_audio_playback.cpp +++ b/src/factory/ctrlmf_audio_playback.cpp @@ -20,7 +20,7 @@ static void ctrlmf_audio_playback_event_handler(system_audio_player_event_t even static ctrlmf_audio_play_global_t g_audio_play; bool ctrlmf_audio_playback_init(void) { - g_audio_play.obj_sap = new Thunder::SystemAudioPlayer::ctrlm_thunder_plugin_system_audio_player_t; + g_audio_play.obj_sap = new(std::nothrow) Thunder::SystemAudioPlayer::ctrlm_thunder_plugin_system_audio_player_t; if(g_audio_play.obj_sap == NULL) { XLOGD_ERROR("out of memory"); diff --git a/src/factory/ctrlmf_mic_test.cpp b/src/factory/ctrlmf_mic_test.cpp index 1db94630..bf4a3c1b 100644 --- a/src/factory/ctrlmf_mic_test.cpp +++ b/src/factory/ctrlmf_mic_test.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -306,12 +307,20 @@ void ctrlmf_mic_test_audio_export(const char *filename, ctrlmf_audio_frame_t aud uint32_t pcm_data_size = frame_qty * SAMPLES_PER_FRAME * channel_qty * sample_size; errno = 0; - FILE *fh = fopen(filename, "w"); - if(NULL == fh) { + int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IWUSR | S_IRUSR); + if(fd < 0) { int errsv = errno; XLOGD_ERROR("Unable to open file <%s> <%s>", filename, strerror(errsv)); return; } + errno = 0; + FILE *fh = fdopen(fd, "w"); + if(NULL == fh) { + int errsv = errno; + XLOGD_ERROR("Unable to fdopen file <%s> <%s>", filename, strerror(errsv)); + close(fd); + return; + } XLOGD_INFO("write wave header - %u-bit PCM %u hz %u chans %lu bytes", sample_size * 8, sample_rate, channel_qty, pcm_data_size); diff --git a/src/rf4ce/ctrlm_rf4ce_network.cpp b/src/rf4ce/ctrlm_rf4ce_network.cpp index db7a2302..220220af 100644 --- a/src/rf4ce/ctrlm_rf4ce_network.cpp +++ b/src/rf4ce/ctrlm_rf4ce_network.cpp @@ -2251,7 +2251,7 @@ json_t *ctrlm_obj_network_rf4ce_t::xconf_export_controllers() { } else { // we dont have type in map so add it; - controller_type_details_t *new_type = new controller_type_details_t(); + controller_type_details_t *new_type = new(std::nothrow) controller_type_details_t(); if(new_type==NULL){ XLOGD_ERROR("error on allocating.. aborting" ); // if we could not malloc memory then we need to free our current mallocs and get out @@ -3989,7 +3989,7 @@ vector *ctrlm_obj_network_rf4ce_t::de } if(sessions == NULL) { - sessions = new vector; + sessions = new(std::nothrow) vector; if(sessions == NULL) { XLOGD_ERROR("out of memory"); break; diff --git a/src/voice/ctrlm_voice_obj.cpp b/src/voice/ctrlm_voice_obj.cpp index 808c0f87..43cfc1d0 100644 --- a/src/voice/ctrlm_voice_obj.cpp +++ b/src/voice/ctrlm_voice_obj.cpp @@ -1299,11 +1299,9 @@ ctrlm_voice_session_response_status_t ctrlm_voice_t::voice_session_req(ctrlm_net request_params.type = XRSR_SESSION_REQUEST_TYPE_AUDIO_FILE; request_params.value.audio_file.path = audio_file_in; - xrsr_audio_format_t xrsr_format; + xrsr_audio_format_t xrsr_format = { .type = XRSR_AUDIO_FORMAT_PCM}; if(format.type == CTRLM_VOICE_FORMAT_OPUS) { xrsr_format.type = XRSR_AUDIO_FORMAT_OPUS; - } else { - xrsr_format.type = XRSR_AUDIO_FORMAT_PCM; } if (false == xrsr_session_request(voice_device_to_xrsr(device_type), dst_index, xrsr_format, request_params, uuid, false, false)) { From e08d3b6ff2f8328cf2a199451cf4128cd59132dd Mon Sep 17 00:00:00 2001 From: dwolav200 Date: Mon, 20 Jul 2026 14:39:53 -0400 Subject: [PATCH 6/7] fix copilot comments --- src/factory/ctrlmf_audio_playback.cpp | 2 +- src/factory/ctrlmf_mic_test.cpp | 1 + src/thunder/ctrlm_thunder_plugin_powermanager.cpp | 6 ++++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/factory/ctrlmf_audio_playback.cpp b/src/factory/ctrlmf_audio_playback.cpp index 7c8bbeac..13fd9f3c 100644 --- a/src/factory/ctrlmf_audio_playback.cpp +++ b/src/factory/ctrlmf_audio_playback.cpp @@ -8,7 +8,7 @@ #include #include #include - +#include typedef struct { Thunder::SystemAudioPlayer::ctrlm_thunder_plugin_system_audio_player_t *obj_sap; diff --git a/src/factory/ctrlmf_mic_test.cpp b/src/factory/ctrlmf_mic_test.cpp index bf4a3c1b..8d9e2287 100644 --- a/src/factory/ctrlmf_mic_test.cpp +++ b/src/factory/ctrlmf_mic_test.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include diff --git a/src/thunder/ctrlm_thunder_plugin_powermanager.cpp b/src/thunder/ctrlm_thunder_plugin_powermanager.cpp index 56957a9c..74bce0cc 100755 --- a/src/thunder/ctrlm_thunder_plugin_powermanager.cpp +++ b/src/thunder/ctrlm_thunder_plugin_powermanager.cpp @@ -37,8 +37,10 @@ ctrlm_thunder_plugin_powermanager_t::ctrlm_thunder_plugin_powermanager_t() : ctr } ctrlm_thunder_plugin_powermanager_t::~ctrlm_thunder_plugin_powermanager_t() { - delete instance; - instance = NULL; + sem_destroy(&this->semaphore); + if(instance == this) { + instance = NULL; + } } ctrlm_thunder_plugin_powermanager_t *ctrlm_thunder_plugin_powermanager_t::get_instance() { From 1c5309a6a99794dbe10acb260880998341a7c92a Mon Sep 17 00:00:00 2001 From: dwolav200 Date: Mon, 20 Jul 2026 14:51:13 -0400 Subject: [PATCH 7/7] more includes --- src/factory/ctrlmf_audio_capture.cpp | 1 + src/rf4ce/ctrlm_rf4ce_network.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/factory/ctrlmf_audio_capture.cpp b/src/factory/ctrlmf_audio_capture.cpp index 1b1087de..a4e77580 100644 --- a/src/factory/ctrlmf_audio_capture.cpp +++ b/src/factory/ctrlmf_audio_capture.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include diff --git a/src/rf4ce/ctrlm_rf4ce_network.cpp b/src/rf4ce/ctrlm_rf4ce_network.cpp index 220220af..1791d243 100644 --- a/src/rf4ce/ctrlm_rf4ce_network.cpp +++ b/src/rf4ce/ctrlm_rf4ce_network.cpp @@ -28,6 +28,7 @@ #include #include #endif +#include #include #include #include