Просмотр исходного кода

qcacld-3.0: Disable hdd_wmm_inactivity timer

Currently api hdd_wmm_free_context free the hdd_wmm context and
this api is getting invoked from several places without disabling
the inactivity timer.
Since the timer is not disabled, when hdd_wmm_inactivity_timer_cb
is invoked it tries to access the hdd_wmm context which is already
freed and the memory is reallocated to someone else resulting to
undefined behaviour.

To address this issue, disable hdd_wmm_inactivity timer before
calling  hdd_wmm_free_context function and add a check for
hdd_wmm context in hdd_wmm_inactivity_timer_cb, if hdd_wmm context
is NULL don't proceed further and return.

Change-Id: Ib085c70b3e5a57b5cd494bc2cd21edd0580c16c4
CRs-Fixed: 2233987
Ashish Kumar Dhanotiya 7 лет назад
Родитель
Сommit
80b01b55e4
1 измененных файлов с 48 добавлено и 5 удалено
  1. 48 5
      core/hdd/src/wlan_hdd_wmm.c

+ 48 - 5
core/hdd/src/wlan_hdd_wmm.c

@@ -318,7 +318,13 @@ static void hdd_wmm_inactivity_timer_cb(void *user_data)
 	hdd_wlan_wmm_status_e status;
 	QDF_STATUS qdf_status;
 	uint32_t currentTrafficCnt = 0;
-	sme_ac_enum_type acType = pQosContext->acType;
+	sme_ac_enum_type acType;
+
+	if (!pQosContext) {
+		hdd_err("invalid user data");
+		return;
+	}
+	acType = pQosContext->acType;
 
 	adapter = pQosContext->adapter;
 	if ((NULL == adapter) ||
@@ -452,6 +458,24 @@ hdd_wmm_disable_inactivity_timer(struct hdd_wmm_qos_context *pQosContext)
 
 	return qdf_status;
 }
+#else
+
+static void hdd_wmm_inactivity_timer_cb(void *user_data)
+{
+}
+
+static QDF_STATUS
+hdd_wmm_enable_inactivity_timer(struct hdd_wmm_qos_context *pQosContext,
+				uint32_t inactivity_time)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS
+hdd_wmm_disable_inactivity_timer(struct hdd_wmm_qos_context *pQosContext)
+{
+	return QDF_STATUS_SUCCESS;
+}
 #endif /* FEATURE_WLAN_ESE */
 
 /**
@@ -577,6 +601,9 @@ static QDF_STATUS hdd_wmm_sme_callback(tHalHandle hHal,
 			hdd_wmm_notify_app(pQosContext);
 		}
 
+		/* disable the inactivity timer */
+		hdd_wmm_disable_inactivity_timer(pQosContext);
+
 		/* Setting up QoS Failed, QoS context can be released.
 		 * SME is releasing this flow information and if HDD
 		 * doesn't release this context, next time if
@@ -745,6 +772,9 @@ static QDF_STATUS hdd_wmm_sme_callback(tHalHandle hHal,
 				HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
 			hdd_wmm_notify_app(pQosContext);
 		}
+		/* disable the inactivity timer */
+		hdd_wmm_disable_inactivity_timer(pQosContext);
+
 		/* we are done with this flow */
 		hdd_wmm_free_context(pQosContext);
 		break;
@@ -789,6 +819,9 @@ static QDF_STATUS hdd_wmm_sme_callback(tHalHandle hHal,
 			hdd_wmm_notify_app(pQosContext);
 		}
 
+		/* disable the inactivity timer */
+		hdd_wmm_disable_inactivity_timer(pQosContext);
+
 		/* we are done with this flow */
 		hdd_wmm_free_context(pQosContext);
 		break;
@@ -1189,6 +1222,9 @@ static void __hdd_wmm_do_implicit_qos(struct work_struct *work)
 		break;
 
 	case SME_QOS_STATUS_SETUP_FAILURE_RSP:
+		/* disable the inactivity timer */
+		hdd_wmm_disable_inactivity_timer(pQosContext);
+
 		/* we can't tell the difference between when a request
 		 * fails because AP rejected it versus when SME
 		 * encountered an internal error.  in either case SME
@@ -1352,9 +1388,9 @@ QDF_STATUS hdd_wmm_adapter_close(struct hdd_adapter *adapter)
 		pQosContext =
 			list_first_entry(&adapter->hdd_wmm_status.wmmContextList,
 					 struct hdd_wmm_qos_context, node);
-#ifdef FEATURE_WLAN_ESE
+
 		hdd_wmm_disable_inactivity_timer(pQosContext);
-#endif
+
 		if (pQosContext->handle == HDD_WMM_HANDLE_IMPLICIT
 			&& pQosContext->magic == HDD_WMM_CTX_MAGIC)
 			cds_flush_work(&pQosContext->wmmAcSetupImplicitQos);
@@ -2204,9 +2240,13 @@ hdd_wlan_wmm_status_e hdd_wmm_addts(struct hdd_adapter *adapter,
 		status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
 		break;
 	case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
+		/* disable the inactivity timer */
+		hdd_wmm_disable_inactivity_timer(pQosContext);
 		hdd_wmm_free_context(pQosContext);
 		return HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
 	case SME_QOS_STATUS_SETUP_FAILURE_RSP:
+		/* disable the inactivity timer */
+		hdd_wmm_disable_inactivity_timer(pQosContext);
 		/* we can't tell the difference between when a request
 		 * fails because AP rejected it versus when SME
 		 * encounterd an internal error
@@ -2214,9 +2254,13 @@ hdd_wlan_wmm_status_e hdd_wmm_addts(struct hdd_adapter *adapter,
 		hdd_wmm_free_context(pQosContext);
 		return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
 	case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
+		/* disable the inactivity timer */
+		hdd_wmm_disable_inactivity_timer(pQosContext);
 		hdd_wmm_free_context(pQosContext);
 		return HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
 	default:
+		/* disable the inactivity timer */
+		hdd_wmm_disable_inactivity_timer(pQosContext);
 		/* we didn't get back one of the
 		 * SME_QOS_STATUS_SETUP_* status codes
 		 */
@@ -2301,10 +2345,9 @@ hdd_wlan_wmm_status_e hdd_wmm_delts(struct hdd_adapter *adapter,
 		/* need to tell TL to stop trigger timer, etc */
 		hdd_wmm_disable_tl_uapsd(pQosContext);
 
-#ifdef FEATURE_WLAN_ESE
 		/* disable the inactivity timer */
 		hdd_wmm_disable_inactivity_timer(pQosContext);
-#endif
+
 		/* we are done with this context */
 		hdd_wmm_free_context(pQosContext);