From: Dan Carpenter <dan.carpenter@oracle.com>
To: kiraank@gmail.com
Cc: linux-bluetooth@vger.kernel.org
Subject: [bug report] Bluetooth: btintel: Add infrastructure to read controller information
Date: Fri, 18 Sep 2020 12:39:02 +0300 [thread overview]
Message-ID: <20200918093902.GA882111@mwanda> (raw)
Hello Kiran K,
The patch 57375beef71a: "Bluetooth: btintel: Add infrastructure to
read controller information" from Sep 14, 2020, leads to the
following static checker warning:
drivers/bluetooth/btintel.c:490 btintel_read_version_tlv()
error: 'tlv->len' from user is not capped properly
drivers/bluetooth/btintel.c
426 /* Consume Command Complete Status field */
427 skb_pull(skb, 1);
428
429 /* Event parameters contatin multiple TLVs. Read each of them
430 * and only keep the required data. Also, it use existing legacy
431 * version field like hw_platform, hw_variant, and fw_variant
432 * to keep the existing setup flow
433 */
434 while (skb->len) {
^^^^^^^^
I feel like these days we are trying to not trust firmware... Smatch
is complaining because it distrusts all skb->data information, but
unless the devs at Google have a way to connect a fuzzer to this then
trusting is probably harmless. Anyway, the rest of this email assumes
that fuzzing is possible.
If skb->len is less than sizeof(*tlv) then it will read beyond the end
of the skb.
while (skb->len >= sizeof(struct intel_tlv)) {
But struct intel_tlv is variable length so it's more complicated than
just testing while we need aditional tests below.
435 struct intel_tlv *tlv;
436
437 tlv = (struct intel_tlv *)skb->data;
if (struct_size(tlv->len, val, tvl) > skb->len)
return -EINVAL;
The length has to be at least 1.
if (tvl->len < 1)
return -EINVAL;
438 switch (tlv->type) {
439 case INTEL_TLV_CNVI_TOP:
Ever test which is reads more than 1 byte has to have a check:
if (tvl->len < sizeof(u32))
return -EINVAL;
440 version->cnvi_top = get_unaligned_le32(tlv->val);
441 break;
442 case INTEL_TLV_CNVR_TOP:
Here too, etc.
443 version->cnvr_top = get_unaligned_le32(tlv->val);
444 break;
445 case INTEL_TLV_CNVI_BT:
446 version->cnvi_bt = get_unaligned_le32(tlv->val);
447 break;
448 case INTEL_TLV_CNVR_BT:
449 version->cnvr_bt = get_unaligned_le32(tlv->val);
450 break;
451 case INTEL_TLV_DEV_REV_ID:
452 version->dev_rev_id = get_unaligned_le16(tlv->val);
453 break;
454 case INTEL_TLV_IMAGE_TYPE:
455 version->img_type = tlv->val[0];
456 break;
457 case INTEL_TLV_TIME_STAMP:
if (tvl->len < sizeof(u16))
return -EINVAL;
458 version->timestamp = get_unaligned_le16(tlv->val);
459 break;
460 case INTEL_TLV_BUILD_TYPE:
461 version->build_type = tlv->val[0];
462 break;
463 case INTEL_TLV_BUILD_NUM:
464 version->build_num = get_unaligned_le32(tlv->val);
465 break;
466 case INTEL_TLV_SECURE_BOOT:
467 version->secure_boot = tlv->val[0];
468 break;
469 case INTEL_TLV_OTP_LOCK:
470 version->otp_lock = tlv->val[0];
471 break;
472 case INTEL_TLV_API_LOCK:
473 version->api_lock = tlv->val[0];
474 break;
475 case INTEL_TLV_DEBUG_LOCK:
476 version->debug_lock = tlv->val[0];
477 break;
478 case INTEL_TLV_MIN_FW:
if (tvl->len < 3)
return -EINVAL;
479 version->min_fw_build_nn = tlv->val[0];
480 version->min_fw_build_cw = tlv->val[1];
481 version->min_fw_build_yy = tlv->val[2];
482 break;
483 case INTEL_TLV_LIMITED_CCE:
484 version->limited_cce = tlv->val[0];
485 break;
486 case INTEL_TLV_SBE_TYPE:
487 version->sbe_type = tlv->val[0];
488 break;
489 case INTEL_TLV_OTP_BDADDR:
490 memcpy(&version->otp_bd_addr, tlv->val, tlv->len);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
tlv->len comes from the network and it's 0-255. If it's more than 6
then this will corrupt memory. There is no caller for this function yet
in linux-next so if tvl->len is less than 6 will that leave
uninitialized memory in ->otp_bd_addr?
if (tlv->len != sizeof(version->otp_bd_addr))
return -EINVAL;
491 break;
492 default:
493 /* Ignore rest of information */
494 break;
495 }
496 /* consume the current tlv and move to next*/
497 skb_pull(skb, tlv->len + sizeof(*tlv));
498 }
499
500 kfree_skb(skb);
501 return 0;
regards,
dan carpenter
next reply other threads:[~2020-09-18 9:41 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-09-18 9:39 Dan Carpenter [this message]
2020-09-21 3:03 ` [bug report] Bluetooth: btintel: Add infrastructure to read controller information K, Kiran
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200918093902.GA882111@mwanda \
--to=dan.carpenter@oracle.com \
--cc=kiraank@gmail.com \
--cc=linux-bluetooth@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.