hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/net/wireless/ath/ath9k/wmi.c
....@@ -221,6 +221,10 @@
221221 if (unlikely(wmi->stopped))
222222 goto free_skb;
223223
224
+ /* Validate the obtained SKB. */
225
+ if (unlikely(skb->len < sizeof(struct wmi_cmd_hdr)))
226
+ goto free_skb;
227
+
224228 hdr = (struct wmi_cmd_hdr *) skb->data;
225229 cmd_id = be16_to_cpu(hdr->command_id);
226230
....@@ -238,10 +242,10 @@
238242 spin_unlock_irqrestore(&wmi->wmi_lock, flags);
239243 goto free_skb;
240244 }
241
- spin_unlock_irqrestore(&wmi->wmi_lock, flags);
242245
243246 /* WMI command response */
244247 ath9k_wmi_rsp_callback(wmi, skb);
248
+ spin_unlock_irqrestore(&wmi->wmi_lock, flags);
245249
246250 free_skb:
247251 kfree_skb(skb);
....@@ -279,7 +283,8 @@
279283
280284 static int ath9k_wmi_cmd_issue(struct wmi *wmi,
281285 struct sk_buff *skb,
282
- enum wmi_cmd_id cmd, u16 len)
286
+ enum wmi_cmd_id cmd, u16 len,
287
+ u8 *rsp_buf, u32 rsp_len)
283288 {
284289 struct wmi_cmd_hdr *hdr;
285290 unsigned long flags;
....@@ -289,6 +294,11 @@
289294 hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id);
290295
291296 spin_lock_irqsave(&wmi->wmi_lock, flags);
297
+
298
+ /* record the rsp buffer and length */
299
+ wmi->cmd_rsp_buf = rsp_buf;
300
+ wmi->cmd_rsp_len = rsp_len;
301
+
292302 wmi->last_seq_id = wmi->tx_seq_id;
293303 spin_unlock_irqrestore(&wmi->wmi_lock, flags);
294304
....@@ -304,8 +314,8 @@
304314 struct ath_common *common = ath9k_hw_common(ah);
305315 u16 headroom = sizeof(struct htc_frame_hdr) +
306316 sizeof(struct wmi_cmd_hdr);
317
+ unsigned long time_left, flags;
307318 struct sk_buff *skb;
308
- unsigned long time_left;
309319 int ret = 0;
310320
311321 if (ah->ah_flags & AH_UNPLUGGED)
....@@ -329,11 +339,7 @@
329339 goto out;
330340 }
331341
332
- /* record the rsp buffer and length */
333
- wmi->cmd_rsp_buf = rsp_buf;
334
- wmi->cmd_rsp_len = rsp_len;
335
-
336
- ret = ath9k_wmi_cmd_issue(wmi, skb, cmd_id, cmd_len);
342
+ ret = ath9k_wmi_cmd_issue(wmi, skb, cmd_id, cmd_len, rsp_buf, rsp_len);
337343 if (ret)
338344 goto out;
339345
....@@ -341,6 +347,9 @@
341347 if (!time_left) {
342348 ath_dbg(common, WMI, "Timeout waiting for WMI command: %s\n",
343349 wmi_cmd_to_name(cmd_id));
350
+ spin_lock_irqsave(&wmi->wmi_lock, flags);
351
+ wmi->last_seq_id = 0;
352
+ spin_unlock_irqrestore(&wmi->wmi_lock, flags);
344353 mutex_unlock(&wmi->op_mutex);
345354 return -ETIMEDOUT;
346355 }