Procházet zdrojové kódy

icnss2: refine processing for restart level notification

It's possible that the 'rproc name' doesn't contain
'wpss' when 'rproc_restart_level_notifier()' gets called,
there are two issues in such case:

1. The fixed length 'ICNSS_RPROC_LEN(100)' for strnstr()
is too long for some cases, which may leads to
'slab-out-of-bounds' issue in strnstr().

To fix it, pass strlen of the rproc name instead.

2. It returns without freeing memory for the event data
and results in memory leak.

To fix it, allocate memory for the event only when
the notification is for 'wpss'.

Change-Id: Icf48f2f9cb8b8fcb4b766971169dd6dbeba9839d
CRs-Fixed: 3848536
Yu Wang před 8 měsíci
rodič
revize
4365c23bf2
1 změnil soubory, kde provedl 14 přidání a 12 odebrání
  1. 14 12
      icnss2/main.c

+ 14 - 12
icnss2/main.c

@@ -115,7 +115,6 @@ uint64_t dynamic_feature_mask = ICNSS_DEFAULT_FEATURE_MASK;
 #define WLAN_EN_TEMP_THRESHOLD		5000
 #define WLAN_EN_DELAY			500
 
-#define ICNSS_RPROC_LEN			100
 static DEFINE_IDA(rd_minor_id);
 
 enum icnss_pdr_cause_index {
@@ -1883,16 +1882,18 @@ static int icnss_subsys_restart_level(struct icnss_priv *priv, void *data)
 	int ret = 0;
 	struct icnss_subsys_restart_level_data *event_data = data;
 
-	if (!priv)
-		return -ENODEV;
-
 	if (!data)
 		return -EINVAL;
 
+	if (!priv) {
+		ret = -ENODEV;
+		goto out;
+	}
+
 	ret = wlfw_subsys_restart_level_msg(priv, event_data->restart_level);
 
+out:
 	kfree(data);
-
 	return ret;
 }
 
@@ -4714,14 +4715,15 @@ static void rproc_restart_level_notifier(void *data, struct rproc *rproc)
 {
 	struct icnss_subsys_restart_level_data *restart_level_data;
 
-	icnss_pr_info("rproc name: %s recovery disable: %d",
-		      rproc->name, rproc->recovery_disabled);
-
-	restart_level_data = kzalloc(sizeof(*restart_level_data), GFP_ATOMIC);
-	if (!restart_level_data)
-		return;
+	icnss_pr_info("rproc name: %s(%zu) recovery disable: %d",
+		      rproc->name, strlen(rproc->name),
+		      rproc->recovery_disabled);
+	if (strnstr(rproc->name, "wpss", strlen(rproc->name))) {
+		restart_level_data = kzalloc(sizeof(*restart_level_data),
+					     GFP_ATOMIC);
+		if (!restart_level_data)
+			return;
 
-	if (strnstr(rproc->name, "wpss", ICNSS_RPROC_LEN)) {
 		if (rproc->recovery_disabled)
 			restart_level_data->restart_level = ICNSS_DISABLE_M3_SSR;
 		else