Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp1245270pxk; Fri, 25 Sep 2020 09:41:11 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwpPB7N6TsXjpoAwjQU1BjymffO0zAdfLJeqSnaY2qkJqlMEv+hcisidKRfHEkz2g7H4s/K X-Received: by 2002:a17:906:95cd:: with SMTP id n13mr3452342ejy.297.1601052071120; Fri, 25 Sep 2020 09:41:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1601052071; cv=none; d=google.com; s=arc-20160816; b=ZUzztKdpQcQrmjCs68gRm4o26rhnN4XDpnZHX3B0TNrcWk4kHXibx+3bfqWUwy992P FsNSlZYRfpyL3bH9abyuhFAnkpGHacxPuKcJxEJtV4xc6dVNhF4pSzHdKNGmNOI90l0q TupPS3HluhrHpURT+jWYp0cLf5E4C7TxjGd9HtyxVDEJjwz7/SbgXAloS5PzabJIAtkU vnC0aCsTWNoBZkjaxW/WtZwDCLNvgCHdm7RwMcjqFxZMX20NT5CktVzdxM6Vt5I9Rey4 OWrllkgrIMtClEMnijYUUxj7JOOdJyYXuW0x8g1xHebJumHyHMoauqS0TxyRifHLdEdQ 0a0w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:to:references:message-id :content-transfer-encoding:cc:date:in-reply-to:from:subject :mime-version; bh=sW9+2TUwSWuqIKpyH13JUZ4JgSwPZIYq2IZZBUP4I10=; b=LKKosNpBwnEjINE2wsz7LNijyr6s60l3JFVtx3db52puSP0fAnvJd6pVsTC30cBAsX HEfEiG1xprGfxtbq5tk2+3DajdmDM4jssqV/wViAgVoo/o5Dq8OYtZXjwyui91cGzPGe JkNC/qvTfxK/Oh/bQlkVm96vKFhhqpeEYFF3VPLrq1RefXB/5qAnUgwvaSQ6MXQnZwSH O0BLxRIlfcXWYvZ+Scavh25RtjlOO/CoEOarEMyPze52118y4qmFk+XbsRvHA6+r/Ixs 4prl7jDenRXmV0Tq61ypwH3uunxNqPxWZo5cZbfXN4XbzcPwBP38lruNnjlDQCfKRiI9 21+w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-bluetooth-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id pg2si2162628ejb.328.2020.09.25.09.40.45; Fri, 25 Sep 2020 09:41:11 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-bluetooth-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727874AbgIYQjm convert rfc822-to-8bit (ORCPT + 99 others); Fri, 25 Sep 2020 12:39:42 -0400 Received: from coyote.holtmann.net ([212.227.132.17]:56236 "EHLO mail.holtmann.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727151AbgIYQjk (ORCPT ); Fri, 25 Sep 2020 12:39:40 -0400 Received: from [172.20.10.2] (dynamic-046-114-136-219.46.114.pool.telefonica.de [46.114.136.219]) by mail.holtmann.org (Postfix) with ESMTPSA id B7A22CECDE; Fri, 25 Sep 2020 18:46:36 +0200 (CEST) Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.120.23.2.1\)) Subject: Re: [PATCH v1] Bluetooth: btintel: Fix issue reported by static analysis tool From: Marcel Holtmann In-Reply-To: Date: Fri, 25 Sep 2020 18:39:36 +0200 Cc: Luiz Augusto von Dentz , Kiran K , "linux-bluetooth@vger.kernel.org" , "Tumkur Narayan, Chethan" , "Srivatsa, Ravishankar" , "dan.carpenter@oracle.com" Content-Transfer-Encoding: 8BIT Message-Id: References: <1600747219-11626-1-git-send-email-kiran.k@intel.com> To: "K, Kiran" X-Mailer: Apple Mail (2.3608.120.23.2.1) Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org Hi Kiran, >>> Smatch tool reported the below issue: >>> >>> drivers/bluetooth/btintel.c:490 btintel_read_version_tlv() >>> error: 'tlv->len' from user is not capped properly >>> >>> Additional details in the below link >>> https://www.spinics.net/lists/linux-bluetooth/msg87786.html >>> >>> Signed-off-by: Kiran K >>> --- >>> drivers/bluetooth/btintel.c | 43 >>> ++++++++++++++++++++++++++++++++++++++++++- >>> 1 file changed, 42 insertions(+), 1 deletion(-) >>> >>> diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c >>> index 88ce5f0..47f2b3d 100644 >>> --- a/drivers/bluetooth/btintel.c >>> +++ b/drivers/bluetooth/btintel.c >>> @@ -431,62 +431,99 @@ int btintel_read_version_tlv(struct hci_dev >> *hdev, struct intel_version_tlv *ver >>> * version field like hw_platform, hw_variant, and fw_variant >>> * to keep the existing setup flow >>> */ >>> - while (skb->len) { >>> + while (skb->len >= sizeof(struct intel_tlv)) { >>> struct intel_tlv *tlv; >>> >>> tlv = (struct intel_tlv *)skb->data; >>> + if (struct_size(tlv, val, tlv->len) > skb->len) >>> + goto failed; >>> + >>> switch (tlv->type) { >>> case INTEL_TLV_CNVI_TOP: >>> + if (tlv->len < sizeof(u32)) >>> + goto failed; >>> version->cnvi_top = get_unaligned_le32(tlv->val); >>> break; >>> case INTEL_TLV_CNVR_TOP: >>> + if (tlv->len < sizeof(u32)) >>> + goto failed; >>> version->cnvr_top = get_unaligned_le32(tlv->val); >>> break; >>> case INTEL_TLV_CNVI_BT: >>> + if (tlv->len < sizeof(u32)) >>> + goto failed; >>> version->cnvi_bt = get_unaligned_le32(tlv->val); >>> break; >>> case INTEL_TLV_CNVR_BT: >>> + if (tlv->len < sizeof(u32)) >>> + goto failed; >>> version->cnvr_bt = get_unaligned_le32(tlv->val); >>> break; >>> case INTEL_TLV_DEV_REV_ID: >>> + if (tlv->len < sizeof(u16)) >>> + goto failed; >>> version->dev_rev_id = get_unaligned_le16(tlv->val); >>> break; >>> case INTEL_TLV_IMAGE_TYPE: >>> + if (tlv->len < sizeof(u8)) >>> + goto failed; >>> version->img_type = tlv->val[0]; >>> break; >>> case INTEL_TLV_TIME_STAMP: >>> + if (tlv->len < sizeof(u16)) >>> + goto failed; >>> version->timestamp = get_unaligned_le16(tlv->val); >>> break; >>> case INTEL_TLV_BUILD_TYPE: >>> + if (tlv->len < sizeof(u8)) >>> + goto failed; >>> version->build_type = tlv->val[0]; >>> break; >>> case INTEL_TLV_BUILD_NUM: >>> + if (tlv->len < sizeof(u32)) >>> + goto failed; >>> version->build_num = get_unaligned_le32(tlv->val); >>> break; >>> case INTEL_TLV_SECURE_BOOT: >>> + if (tlv->len < sizeof(u8)) >>> + goto failed; >>> version->secure_boot = tlv->val[0]; >>> break; >>> case INTEL_TLV_OTP_LOCK: >>> + if (tlv->len < sizeof(u8)) >>> + goto failed; >>> version->otp_lock = tlv->val[0]; >>> break; >>> case INTEL_TLV_API_LOCK: >>> + if (tlv->len < sizeof(u8)) >>> + goto failed; >>> version->api_lock = tlv->val[0]; >>> break; >>> case INTEL_TLV_DEBUG_LOCK: >>> + if (tlv->len < sizeof(u8)) >>> + goto failed; >>> version->debug_lock = tlv->val[0]; >>> break; >>> case INTEL_TLV_MIN_FW: >>> + if (tlv->len < 3) >>> + goto failed; >>> version->min_fw_build_nn = tlv->val[0]; >>> version->min_fw_build_cw = tlv->val[1]; >>> version->min_fw_build_yy = tlv->val[2]; >>> break; >>> case INTEL_TLV_LIMITED_CCE: >>> + if (tlv->len < sizeof(u8)) >>> + goto failed; >>> version->limited_cce = tlv->val[0]; >>> break; >>> case INTEL_TLV_SBE_TYPE: >>> + if (tlv->len < sizeof(u8)) >>> + goto failed; >>> version->sbe_type = tlv->val[0]; >>> break; >>> case INTEL_TLV_OTP_BDADDR: >>> + if (tlv->len != sizeof(version->otp_bd_addr)) >>> + goto failed; >> >> Do we really want to fail here? The advantage of using a TLV is that we can >> skip if the type is not understood or is malformed but with this checks the >> length becomes useless since the types will always have a fixed value, also > > Agree that the types are fixed here. But if due to some reason if controller is not honoring the same, then driver might end up reading unwanted data. The check is more about driver being defensive rather than believing what comes on wire. > >> we cannot extend the types later on since it would not be backward >> compatible if we maintain such strict checks. > > I didn’t get this part. Could you please be more specific ? please change this that you check the size of the TLV data part against the expected size of the field and only then assign it. Regards Marcel