hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/net/wireless/ath/ath9k/htc_hst.c
....@@ -30,6 +30,7 @@
3030 hdr->endpoint_id = epid;
3131 hdr->flags = flags;
3232 hdr->payload_len = cpu_to_be16(len);
33
+ memset(hdr->control, 0, sizeof(hdr->control));
3334
3435 status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb);
3536
....@@ -113,7 +114,13 @@
113114
114115 if (svc_rspmsg->status == HTC_SERVICE_SUCCESS) {
115116 epid = svc_rspmsg->endpoint_id;
116
- if (epid < 0 || epid >= ENDPOINT_MAX)
117
+
118
+ /* Check that the received epid for the endpoint to attach
119
+ * a new service is valid. ENDPOINT0 can't be used here as it
120
+ * is already reserved for HTC_CTRL_RSVD_SVC service and thus
121
+ * should not be modified.
122
+ */
123
+ if (epid <= ENDPOINT0 || epid >= ENDPOINT_MAX)
117124 return;
118125
119126 service_id = be16_to_cpu(svc_rspmsg->service_id);
....@@ -173,7 +180,6 @@
173180 time_left = wait_for_completion_timeout(&target->cmd_wait, HZ);
174181 if (!time_left) {
175182 dev_err(target->dev, "HTC credit config timeout\n");
176
- kfree_skb(skb);
177183 return -ETIMEDOUT;
178184 }
179185
....@@ -209,7 +215,6 @@
209215 time_left = wait_for_completion_timeout(&target->cmd_wait, HZ);
210216 if (!time_left) {
211217 dev_err(target->dev, "HTC start timeout\n");
212
- kfree_skb(skb);
213218 return -ETIMEDOUT;
214219 }
215220
....@@ -274,6 +279,10 @@
274279 conn_msg->dl_pipeid = endpoint->dl_pipeid;
275280 conn_msg->ul_pipeid = endpoint->ul_pipeid;
276281
282
+ /* To prevent infoleak */
283
+ conn_msg->svc_meta_len = 0;
284
+ conn_msg->pad = 0;
285
+
277286 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0);
278287 if (ret)
279288 goto err;
....@@ -282,7 +291,6 @@
282291 if (!time_left) {
283292 dev_err(target->dev, "Service connection timeout for: %d\n",
284293 service_connreq->service_id);
285
- kfree_skb(skb);
286294 return -ETIMEDOUT;
287295 }
288296
....@@ -362,40 +370,34 @@
362370 }
363371
364372 static void ath9k_htc_fw_panic_report(struct htc_target *htc_handle,
365
- struct sk_buff *skb)
373
+ struct sk_buff *skb, u32 len)
366374 {
367375 uint32_t *pattern = (uint32_t *)skb->data;
368376
369
- switch (*pattern) {
370
- case 0x33221199:
371
- {
377
+ if (*pattern == 0x33221199 && len >= sizeof(struct htc_panic_bad_vaddr)) {
372378 struct htc_panic_bad_vaddr *htc_panic;
373379 htc_panic = (struct htc_panic_bad_vaddr *) skb->data;
374380 dev_err(htc_handle->dev, "ath: firmware panic! "
375381 "exccause: 0x%08x; pc: 0x%08x; badvaddr: 0x%08x.\n",
376382 htc_panic->exccause, htc_panic->pc,
377383 htc_panic->badvaddr);
378
- break;
379
- }
380
- case 0x33221299:
381
- {
384
+ return;
385
+ }
386
+ if (*pattern == 0x33221299) {
382387 struct htc_panic_bad_epid *htc_panic;
383388 htc_panic = (struct htc_panic_bad_epid *) skb->data;
384389 dev_err(htc_handle->dev, "ath: firmware panic! "
385390 "bad epid: 0x%08x\n", htc_panic->epid);
386
- break;
387
- }
388
- default:
389
- dev_err(htc_handle->dev, "ath: unknown panic pattern!\n");
390
- break;
391
+ return;
391392 }
393
+ dev_err(htc_handle->dev, "ath: unknown panic pattern!\n");
392394 }
393395
394396 /*
395397 * HTC Messages are handled directly here and the obtained SKB
396398 * is freed.
397399 *
398
- * Service messages (Data, WMI) passed to the corresponding
400
+ * Service messages (Data, WMI) are passed to the corresponding
399401 * endpoint RX handlers, which have to free the SKB.
400402 */
401403 void ath9k_htc_rx_msg(struct htc_target *htc_handle,
....@@ -409,16 +411,26 @@
409411 if (!htc_handle || !skb)
410412 return;
411413
414
+ /* A valid message requires len >= 8.
415
+ *
416
+ * sizeof(struct htc_frame_hdr) == 8
417
+ * sizeof(struct htc_ready_msg) == 8
418
+ * sizeof(struct htc_panic_bad_vaddr) == 16
419
+ * sizeof(struct htc_panic_bad_epid) == 8
420
+ */
421
+ if (unlikely(len < sizeof(struct htc_frame_hdr)))
422
+ goto invalid;
412423 htc_hdr = (struct htc_frame_hdr *) skb->data;
413424 epid = htc_hdr->endpoint_id;
414425
415426 if (epid == 0x99) {
416
- ath9k_htc_fw_panic_report(htc_handle, skb);
427
+ ath9k_htc_fw_panic_report(htc_handle, skb, len);
417428 kfree_skb(skb);
418429 return;
419430 }
420431
421432 if (epid < 0 || epid >= ENDPOINT_MAX) {
433
+invalid:
422434 if (pipe_id != USB_REG_IN_PIPE)
423435 dev_kfree_skb_any(skb);
424436 else
....@@ -430,21 +442,30 @@
430442
431443 /* Handle trailer */
432444 if (htc_hdr->flags & HTC_FLAGS_RECV_TRAILER) {
433
- if (be32_to_cpu(*(__be32 *) skb->data) == 0x00C60000)
445
+ if (be32_to_cpu(*(__be32 *) skb->data) == 0x00C60000) {
434446 /* Move past the Watchdog pattern */
435447 htc_hdr = (struct htc_frame_hdr *)(skb->data + 4);
448
+ len -= 4;
449
+ }
436450 }
437451
438452 /* Get the message ID */
453
+ if (unlikely(len < sizeof(struct htc_frame_hdr) + sizeof(__be16)))
454
+ goto invalid;
439455 msg_id = (__be16 *) ((void *) htc_hdr +
440456 sizeof(struct htc_frame_hdr));
441457
442458 /* Now process HTC messages */
443459 switch (be16_to_cpu(*msg_id)) {
444460 case HTC_MSG_READY_ID:
461
+ if (unlikely(len < sizeof(struct htc_ready_msg)))
462
+ goto invalid;
445463 htc_process_target_rdy(htc_handle, htc_hdr);
446464 break;
447465 case HTC_MSG_CONNECT_SERVICE_RESPONSE_ID:
466
+ if (unlikely(len < sizeof(struct htc_frame_hdr) +
467
+ sizeof(struct htc_conn_svc_rspmsg)))
468
+ goto invalid;
448469 htc_process_conn_rsp(htc_handle, htc_hdr);
449470 break;
450471 default:
....@@ -463,6 +484,8 @@
463484 if (endpoint->ep_callbacks.rx)
464485 endpoint->ep_callbacks.rx(endpoint->ep_callbacks.priv,
465486 skb, epid);
487
+ else
488
+ goto invalid;
466489 }
467490 }
468491