From 181ebf835cccd2a8a733c815feff3fd83bc80070 Mon Sep 17 00:00:00 2001 From: Zhu Jianmin Date: Thu, 1 Feb 2018 09:32:46 +0800 Subject: [PATCH] qcacmn: Avoid memory corruption when calling cb to release cmd memory When serialization puts the command in active queue & activates the command, it gives the callback to command owner as part of the activation procedure. If this activation callback fails then serialization suppose to give a callback to the owner to release the memory. There are some instances observed in legacy platforms where owner releases the memory itself as part of activation callback failure first and gets serialization callback as well to release the same memory. These scenario creates "double free" or "memory corruption" phenomena. In order to avoid this scenario, add a sanity check to make sure command still present in active queue and memory is not released by command owner before calling callback to release the memory. Change-Id: Ide341e3288aadd7d6e4441a5768118cd1439d38d CRs-Fixed: 2161678 --- .../src/wlan_serialization_enqueue.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/umac/cmn_services/serialization/src/wlan_serialization_enqueue.c b/umac/cmn_services/serialization/src/wlan_serialization_enqueue.c index 071c7042ee34..e568679dd89c 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_enqueue.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_enqueue.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -141,17 +141,24 @@ void wlan_serialization_activate_cmd( */ qdf_status = cmd_list->cmd.cmd_cb(&cmd_list->cmd, WLAN_SER_CB_ACTIVATE_CMD); - if (qdf_status != QDF_STATUS_SUCCESS) { + if (QDF_IS_STATUS_SUCCESS(qdf_status)) + return; + if (wlan_serialization_is_cmd_present_in_active_queue( + psoc, &cmd_list->cmd)) { wlan_serialization_find_and_stop_timer(psoc, - &cmd_list->cmd); + &cmd_list->cmd); cmd_list->cmd.cmd_cb(&cmd_list->cmd, WLAN_SER_CB_RELEASE_MEM_CMD); wlan_serialization_put_back_to_global_list( queue, ser_pdev_obj, cmd_list); - wlan_serialization_move_pending_to_active( + } else { + serialization_err("cmd type:%d, id: %d is removed from active list already", + cmd_list->cmd.cmd_type, + cmd_list->cmd.cmd_id); + } + wlan_serialization_move_pending_to_active( cmd_list->cmd.cmd_type, ser_pdev_obj); - } } enum wlan_serialization_status