Received: by 2002:a05:6a10:a841:0:0:0:0 with SMTP id d1csp4748130pxy; Tue, 27 Apr 2021 11:39:35 -0700 (PDT) X-Google-Smtp-Source: ABdhPJx0NAQidctbDgx8WuF7R4nMQW7M2ORm2U5svFKHzIeJH/Iatd+pujAzC/hKlCwZGi84S80E X-Received: by 2002:a63:dc10:: with SMTP id s16mr23998596pgg.288.1619548775251; Tue, 27 Apr 2021 11:39:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1619548775; cv=none; d=google.com; s=arc-20160816; b=HiYJtXdGRpUQn698pi0Ptt1+Ko1PMjxEOZPue2MKi0wZxLiQZwhfDPgsxqHg1neuP3 EYlMR2M6PryESWAlw6FIrlxWtZXoqjCj2pU3cp6IfA039+zSeZdKNxWdt7xt0P+Mtaht LZWi5om+B/ZFmpLS7Q4vdMr+5OtQC7FW7/UjuzgcKxwJrz0bugCHVAGjNV0octXVfbSs dzcZFbwKLoahIyc90zizl2bMpX5Qj3+XDPG3HJU99FPy82q4D1aMxIVpGpeLbXxJcK7l nAxPsv9l/EkF78qKPSVGbODgZYsRMYv/kTbxsL/zuGonmxMX4vdDAybDEpii4tjmwGNA ONcA== 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=p5n5AVHUyTNdMvOs7ke5MWPOVM8/PW594MSkLvBt9oQ=; b=V3hipUnh/OJ612Xcw1PHh673K5+AZYJPPLGZJyvr8q5PbO5kc0HqzHQiIRBf8FUQAd tOmCNhN64GEJriFyFh2uQdXpoc+wMIv5u5kH7pwO0Df3mlY0OO+GKZ9ZJB8a93QKbuYu bfmxLOtajnbg/uFjzlaLD2EZEvt9uUkY06PD+KNbMXTiA+GCjhwFuLJG2XXDYG2psgrG dx10cS+mGqhKjIWtocgPmaDoT5CcoPLFPb+p4uOFbXblsT2uh+QFK6WHBKQ1XXr2MotF GPlW5nFOHkSmDgPUvUByRplvB+lmlUe+PpHa385K3r00uhGeU6Zhn/w07cHGlQ6sMHdF Cyaw== 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 b12si4073954pji.74.2021.04.27.11.39.05; Tue, 27 Apr 2021 11:39:35 -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 S236960AbhD0SiK convert rfc822-to-8bit (ORCPT + 99 others); Tue, 27 Apr 2021 14:38:10 -0400 Received: from coyote.holtmann.net ([212.227.132.17]:60749 "EHLO mail.holtmann.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236834AbhD0SiK (ORCPT ); Tue, 27 Apr 2021 14:38:10 -0400 Received: from smtpclient.apple (p4fefc624.dip0.t-ipconnect.de [79.239.198.36]) by mail.holtmann.org (Postfix) with ESMTPSA id DD9AECED05; Tue, 27 Apr 2021 20:45:13 +0200 (CEST) Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 14.0 \(3654.80.0.2.43\)) Subject: Re: [PATCH v2 01/10] Bluetooth: HCI: Use skb_pull to parse BR/EDR events From: Marcel Holtmann In-Reply-To: Date: Tue, 27 Apr 2021 20:37:25 +0200 Cc: "linux-bluetooth@vger.kernel.org" Content-Transfer-Encoding: 8BIT Message-Id: <79A4150F-9DD2-4370-993F-495248D8D377@holtmann.org> References: <20210419171257.3865181-1-luiz.dentz@gmail.com> <20210419171257.3865181-2-luiz.dentz@gmail.com> <25D86C94-89CE-44CC-BB9C-724486444C12@holtmann.org> To: Luiz Augusto von Dentz X-Mailer: Apple Mail (2.3654.80.0.2.43) Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org Hi Luiz, >>>>> This uses skb_pull to check the BR/EDR events received have the minimum >>>>> required length. >>>>> >>>>> Signed-off-by: Luiz Augusto von Dentz >>>>> --- >>>>> include/net/bluetooth/hci.h | 4 + >>>>> net/bluetooth/hci_event.c | 272 +++++++++++++++++++++++++++++------- >>>>> 2 files changed, 229 insertions(+), 47 deletions(-) >>>>> >>>>> diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h >>>>> index ea4ae551c426..f1f505355e81 100644 >>>>> --- a/include/net/bluetooth/hci.h >>>>> +++ b/include/net/bluetooth/hci.h >>>>> @@ -1894,6 +1894,10 @@ struct hci_cp_le_reject_cis { >>>>> } __packed; >>>>> >>>>> /* ---- HCI Events ---- */ >>>>> +struct hci_ev_status { >>>>> + __u8 status; >>>>> +} __packed; >>>>> + >>>>> #define HCI_EV_INQUIRY_COMPLETE 0x01 >>>>> >>>>> #define HCI_EV_INQUIRY_RESULT 0x02 >>>>> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c >>>>> index 5e99968939ce..077541fcba41 100644 >>>>> --- a/net/bluetooth/hci_event.c >>>>> +++ b/net/bluetooth/hci_event.c >>>>> @@ -42,6 +42,30 @@ >>>>> >>>>> /* Handle HCI Event packets */ >>>>> >>>>> +static void *hci_skb_pull(struct sk_buff *skb, size_t len) >>>>> +{ >>>>> + void *data = skb->data; >>>>> + >>>>> + if (skb->len < len) >>>>> + return NULL; >>>>> + >>>>> + skb_pull(skb, len); >>>>> + >>>>> + return data; >>>>> +} >>>>> + >>>>> +static void *hci_ev_skb_pull(struct hci_dev *hdev, struct sk_buff *skb, >>>>> + u8 ev, size_t len) >>>>> +{ >>>>> + void *data; >>>>> + >>>>> + data = hci_skb_pull(skb, len); >>>>> + if (!data) >>>>> + bt_dev_err(hdev, "Malformed Event: 0x%2.2x", ev); >>>>> + >>>>> + return data; >>>>> +} >>>>> + >>>> >>>> so if you do it in one function, this will look like this: >>>> >>>> static void *hci_ev_skb_pull(..) >>>> { >>>> void *data = skb->data; >>>> >>>> if (skb->len < len) { >>>> bt_dev_err(hdev, “Malformed ..”); >>>> return NULL; >>>> } >>>> >>>> skb_pull(skb, len); >>>> return data; >>>> } >>>> >>>> static void *hci_cc_skb_pull(..) >>>> { >>>> void *data = skb->data; >>>> >>>> if (skb->len < len) { >>>> bt_dev_err(..); >>>> return NULL; >>>> } >>>> >>>> skb_pull(..); >>>> return data; >>>> } >>>> >>>> I realize that you want to optimize the code with hci_skb_pull, but I don’t see how that makes it simpler or cleaner. In the end you just have spaghetti code and don’t win anything in size reduction or complexity. >>> >>> Right, I can either do that or perhaps bite the bullet and convert the >>> whole hci_event.c to use a function table: >>> >>> #define HCI_EVENT(_op, _len, _func)... >>> >>> struct hci_event { >>> __u8 op; >>> __u16 len; >>> func... >>> } ev_table[] = { >>> HCI_EVENT(...), >>> } >>> >>> But that would pack a lot more changes since we would need to convert >>> the whole switch to a for loop or alternatively if we don't want do a >>> lookup we could omit the op and access the table by index if we want >>> to trade speed over code size, with that we can have just one call to >>> the likes of hci_ev_skb_pull. >> >> looping through a table is not ideal. There are too many events that you can receive and if we end up looping for every LE advertising report it would be rather silly. And of course a static table is possible since event numbers are assigned in order, but it also means some sort of overhead since we don’t parse each event. >> >> In addition to that dilemma, you have the problem that not all events are fixed size. So you end up indicating that similar to how we do it in btmon which will increase the table size again. Maybe that is actually ok since two giant switch statements also take time and code size. >> >> So our currently max event code is 0x57 for Authenticated Payload Timeout and the max LE event code is 0x3e for BIG Info Advertising Report. Meaning table one would have 87 entries and table would have two 63 entries. If we do min_len,max_len as uint8 then we have 2 octets and a function pointer. Maybe that is not too bad since that is all static const data. > > Yep, even if we have to have NOP for those event we don't handle I > don't think it is such a big deal and accessing by index should be > comparable in terms of speed to a switch statement, that said we may > still need to do some checks on the callbacks for those events that > have variable size I was only intending to do minimal size checks but > perhaps you are saying it might be better to have a bool/flag saying > that the event has variable size which matters when we are checking > the length to either use == or <. I actually meant min_len + max_len. So you have for example HCI_EVENT(..) that sets min_len = x, max_len = x. HCI_EVENT_VAR(..) that sets min_len = x and max_len = 253. No need for extra flags then. Regards Marcel