Message ID | 20221102212336.380257-1-W_Armin@gmx.de |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp151699wru; Wed, 2 Nov 2022 14:28:18 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4jiZ0B/FtGGZuN9Y19L2IhprICTjtoDsz1+3g/ijgqPope7fu1L2v+MQINANzg147gocKX X-Received: by 2002:a17:903:494:b0:186:a227:436f with SMTP id jj20-20020a170903049400b00186a227436fmr26729946plb.133.1667424498401; Wed, 02 Nov 2022 14:28:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1667424498; cv=none; d=google.com; s=arc-20160816; b=gBnsyo6wau1Bpd1rjYZzbf0XWzLY4jnLW+eDDzy9qP44BFsoYv+RMIy6wRDoBJ6NfI zHWA4KZXZ88dMokNYBUeZuZ8JjURN9K9qmeYojHVinOe1Nq/m2NXWi8wKZT66bzvcvab ptB7a6zgtlztJG8u7VLe2KL7a9AlKf9Pk56sexNOXzhtndwFqg3kieneKQp6w443S12J RCCvKQAlZWNppuYAFjZ4e1boS0BGwCQp9PqlHi5/7mOM5K5lOaRW/qkwe5bcCDacC2AT U2mL2RfYvur4HsTACfhBQqZaQdNxMPZ9Tdsj1bjay0PSRpmvqbbTsQcVj0UYd6S+SVHD Wsbw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:ui-outboundreport:content-transfer-encoding :mime-version:message-id:date:subject:cc:to:from:dkim-signature; bh=KWmt3H67NLvEofFFtviCv6baaPNqHR+8RsusTPtOuRU=; b=Kfc61mS1R8Z3CSDUxuCJl6w/sQSGsxjCN4ae3NKXhjwc9L9AP2NRZjit3VSrAf8MMb HrdB/39AkXIAY6Z99VQbsxLArvGYFBZ4miR1NshQBlxLfzAiJ4gC0Jt6aruTLPBdp27k 8rQkD0hZOHZDKaFzYlI6Qo3RNl+z5e+4oayrbeU+tCzWfLfNgW0qOn3iG0BwTXCqjdOb /Fbl8onYbx0PinpASoLfkrtrjN3m6RLhyrJOOd9jCzKq3znxQHk0dCb0t2+54nPQg3ht rLgvcu0QcuHzZT2gEN7R9I2k09GzskiUSaEPzM787zdXgvWuKgsP9jmx7FR1bX6kEgAD UjAA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmx.de header.s=s31663417 header.b=kZtXtH+N; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gmx.de Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id ob9-20020a17090b390900b001fb706e96afsi4056867pjb.182.2022.11.02.14.28.05; Wed, 02 Nov 2022 14:28:18 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmx.de header.s=s31663417 header.b=kZtXtH+N; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gmx.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230427AbiKBVXv (ORCPT <rfc822;yves.mi.zy@gmail.com> + 99 others); Wed, 2 Nov 2022 17:23:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59402 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229523AbiKBVXt (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 2 Nov 2022 17:23:49 -0400 Received: from mout.gmx.net (mout.gmx.net [212.227.15.19]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 372B1386; Wed, 2 Nov 2022 14:23:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.de; s=s31663417; t=1667424219; bh=aampEa/W6j9d6+DzK+wvXKve8YoufcAeq3lEwB+0Uao=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date; b=kZtXtH+N4DsT7bPMIy0s4JioiFGeG85GG3Nx5zRynB6hk+UFkXbXhCZElOHkeOtF4 1IxbPeI/LPAHQF6T6RAEi14uZbTSZYoMibmp4mTwCITfJxvb/QuktN1JtRQhZ9ss9G a8r7gYz/nYNYusTYwwqY211t2zNAEnIm8RbAQnPrGXhg0p9vynPvIQemYI3Om6Jwoc xw1jExnitpzbd+Jdzv0fJz2ETY7Eh0vK9aDMUXQCbDTJcVC0szDHAOO9RbRlBX8kOJ +yhE9pE5LrhhYH6zfr7k2zEKGxHZkJRwyYDdipo/B8Zh6OoVa1yGBZpO4TDTIImjg/ f12+yxCMOAqUA== X-UI-Sender-Class: 724b4f7f-cbec-4199-ad4e-598c01a50d3a Received: from esprimo-mx.users.agdsn.de ([141.30.226.129]) by mail.gmx.net (mrgmx004 [212.227.17.190]) with ESMTPSA (Nemesis) id 1MMGN2-1oZDUy4C50-00JIEH; Wed, 02 Nov 2022 22:23:39 +0100 From: Armin Wolf <W_Armin@gmx.de> To: hdegoede@redhat.com, markgross@kernel.org Cc: platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/2] platform/x86: dell-ddv: Improve buffer handling Date: Wed, 2 Nov 2022 22:23:35 +0100 Message-Id: <20221102212336.380257-1-W_Armin@gmx.de> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Provags-ID: V03:K1:Nr9KeNWdY7WLGxN05P9csXuYDmA/r2Qe4xbNDZlNmjJ+fC8e95q XBS9UT7JG1cpeC8H68zLCPZ9wI2GNEvWLyB6PruNFrJpXdw4/Ft6WCiMhDRBkm7fudmWMX3 rylZJdtavVPnrY62EumARp+M2vEpJgVpaDHxZDrq60qKLsN3zlsEkIFJcOHG5C4Z2m23tLS L1XolCjM5XFcxElNIxqRQ== UI-OutboundReport: notjunk:1;M01:P0:9uLHvllaT/A=;ZithkZVRqNPOK2V8hjiT5neSuNo cz4HCWUs6YlIDEIj1q11gYFMa7sdja+NrDRs+i/vkbsfLJ0pp4IIZ/E6L+6U9d45BB7kGiDgC 3XvzC7BuChN0vI8VoHLkvocrYEA6J5MhbBPgkT9pqPAhGq5Y5O3IKW1cDWCz4ZXXxiV7wDZTt jTA0EiQDG2pv2JbZnfFnfb+TA/ugtZCmVanHbnBH6PDG8bzsVUmyiX3sucwv5/Ey6SSRdWUCI xw9dra48IzB+2v/MehxSJCGBammZLWdlhKTpIH8EhYydgkJ5ZftnOr0eVxNHZ2GDY1ohLhglA YjnV3OxwK3nS5muK5uIBFghJ5/jFniqoGTLWhB1LmzdZRS+hzCJ13oUPZ1Pyfy1VQOo1/K/BD /ZWezwPJvFktb9tA54fi/3TtWg3AFRxu3N6DMg+cK1DMWcK9cRKRIRj+sP/9eeT1g29afiEPR HGC2ctpcH87MKB4SpSATgxw5wVc396SZsJKq2hKkMg270z4kG3Qxdib0ZJXhBlfbFXLpYYaAL CG+otK9MUabBNxDtwXdEvLUx1DqHOwlVj/CJuCD1expdXQYy+UuiU2+S7gKXHsdhg+HcGbvNS fWMPVv9y/wHiHAYg5knK+uvvDmkaoVDxr/b34iCP5szRRB2B5rU6yrKKp7EjIgEyle6zbQu/+ FuCktFX1OTiJEQKGM9FuWfv0wFrSCzwEO13eA/ShcTYNPQ2B2nNsJ/Fci0FFTn/hrxU5aaqKf Cdx2rfdnjzlvoJOvbajoSvQw+/aPQCTc83Ay74OjohPd2LtiswDNGkvgxQZwnz1DKqyCZm3Rh U0YiMlz8BV8cWIkHskJZ9ACoGcbR4L7TyPY8pg1Wst+327R9GE1tfs0OEN69jTbMVsd15qnO/ KGdNfwXTIyWkxYj5e+o+UddEIMn5sUPGl6voWkS/ylTuS+K+Ph1pMKKmaHhdYV7eHF/s/29sN pCvruSvEtcHZB0IPLNYmd+USnxA= X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1748421311049305855?= X-GMAIL-MSGID: =?utf-8?q?1748421311049305855?= |
Series |
[1/2] platform/x86: dell-ddv: Improve buffer handling
|
|
Commit Message
Armin Wolf
Nov. 2, 2022, 9:23 p.m. UTC
When the DDV interface returns a buffer, it actually
returns a acpi buffer containing an integer (buffer size)
and another acpi buffer (buffer content).
The size of the buffer may be smaller than the size of
the buffer content, which is perfectly valid and should not
be treated as an error.
Also use the buffer size instead of the buffer content size
when accessing the buffer to prevent accessing bogus data.
Tested on a Dell Inspiron 3505.
Signed-off-by: Armin Wolf <W_Armin@gmx.de>
---
drivers/platform/x86/dell/dell-wmi-ddv.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
--
2.30.2
Comments
Hi, On 11/2/22 22:23, Armin Wolf wrote: > When the DDV interface returns a buffer, it actually > returns a acpi buffer containing an integer (buffer size) > and another acpi buffer (buffer content). > The size of the buffer may be smaller than the size of > the buffer content, which is perfectly valid and should not > be treated as an error. > Also use the buffer size instead of the buffer content size > when accessing the buffer to prevent accessing bogus data. > > Tested on a Dell Inspiron 3505. > > Signed-off-by: Armin Wolf <W_Armin@gmx.de> Thank you for your patch-series, I've applied the series to my review-hans branch: https://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git/log/?h=review-hans Note it will show up in my review-hans branch once I've pushed my local branch there, which might take a while. Once I've run some tests on this branch the patches there will be added to the platform-drivers-x86/for-next branch and eventually will be included in the pdx86 pull-request to Linus for the next merge-window. Regards, Hans > --- > drivers/platform/x86/dell/dell-wmi-ddv.c | 12 +++++++----- > 1 file changed, 7 insertions(+), 5 deletions(-) > > diff --git a/drivers/platform/x86/dell/dell-wmi-ddv.c b/drivers/platform/x86/dell/dell-wmi-ddv.c > index 699feae3c435..1a001296e8c6 100644 > --- a/drivers/platform/x86/dell/dell-wmi-ddv.c > +++ b/drivers/platform/x86/dell/dell-wmi-ddv.c > @@ -129,9 +129,9 @@ static int dell_wmi_ddv_query_buffer(struct wmi_device *wdev, enum dell_ddv_meth > if (obj->package.elements[1].type != ACPI_TYPE_BUFFER) > goto err_free; > > - if (buffer_size != obj->package.elements[1].buffer.length) { > + if (buffer_size > obj->package.elements[1].buffer.length) { > dev_warn(&wdev->dev, > - FW_WARN "ACPI buffer size (%llu) does not match WMI buffer size (%d)\n", > + FW_WARN "WMI buffer size (%llu) exceeds ACPI buffer size (%d)\n", > buffer_size, obj->package.elements[1].buffer.length); > > goto err_free; > @@ -271,15 +271,17 @@ static int dell_wmi_ddv_buffer_read(struct seq_file *seq, enum dell_ddv_method m > struct device *dev = seq->private; > struct dell_wmi_ddv_data *data = dev_get_drvdata(dev); > union acpi_object *obj; > - union acpi_object buf; > + u64 size; > + u8 *buf; > int ret; > > ret = dell_wmi_ddv_query_buffer(data->wdev, method, 0, &obj); > if (ret < 0) > return ret; > > - buf = obj->package.elements[1]; > - ret = seq_write(seq, buf.buffer.pointer, buf.buffer.length); > + size = obj->package.elements[0].integer.value; > + buf = obj->package.elements[1].buffer.pointer; > + ret = seq_write(seq, buf, size); > kfree(obj); > > return ret; > -- > 2.30.2 >
On Wed, 2022-11-02 at 22:23 +0100, Armin Wolf wrote: > When the DDV interface returns a buffer, it actually > returns a acpi buffer containing an integer (buffer size) > and another acpi buffer (buffer content). > The size of the buffer may be smaller than the size of > the buffer content, which is perfectly valid and should not > be treated as an error. Is there documentation for this that you can refer to? > Also use the buffer size instead of the buffer content size > when accessing the buffer to prevent accessing bogus data. > > Tested on a Dell Inspiron 3505. > > Signed-off-by: Armin Wolf <W_Armin@gmx.de> > --- > drivers/platform/x86/dell/dell-wmi-ddv.c | 12 +++++++----- > 1 file changed, 7 insertions(+), 5 deletions(-) > > diff --git a/drivers/platform/x86/dell/dell-wmi-ddv.c > b/drivers/platform/x86/dell/dell-wmi-ddv.c > index 699feae3c435..1a001296e8c6 100644 > --- a/drivers/platform/x86/dell/dell-wmi-ddv.c > +++ b/drivers/platform/x86/dell/dell-wmi-ddv.c > @@ -129,9 +129,9 @@ static int dell_wmi_ddv_query_buffer(struct wmi_device > *wdev, enum dell_ddv_meth > if (obj->package.elements[1].type != ACPI_TYPE_BUFFER) > goto err_free; > > - if (buffer_size != obj->package.elements[1].buffer.length) { > + if (buffer_size > obj->package.elements[1].buffer.length) { > dev_warn(&wdev->dev, > - FW_WARN "ACPI buffer size (%llu) does not match WMI > buffer size (%d)\n", > + FW_WARN "WMI buffer size (%llu) exceeds ACPI buffer > size (%d)\n", > buffer_size, obj->package.elements[1].buffer.length); > > goto err_free; > @@ -271,15 +271,17 @@ static int dell_wmi_ddv_buffer_read(struct seq_file > *seq, enum dell_ddv_method m > struct device *dev = seq->private; > struct dell_wmi_ddv_data *data = dev_get_drvdata(dev); > union acpi_object *obj; > - union acpi_object buf; > + u64 size; > + u8 *buf; > int ret; > > ret = dell_wmi_ddv_query_buffer(data->wdev, method, 0, &obj); > if (ret < 0) > return ret; > > - buf = obj->package.elements[1]; > - ret = seq_write(seq, buf.buffer.pointer, buf.buffer.length); > + size = obj->package.elements[0].integer.value; > + buf = obj->package.elements[1].buffer.pointer; > + ret = seq_write(seq, buf, size); Okay, so the buffer may provide more space than what should actually be used according to the size field. This looks like a bug that should have a fixes tag on the original commit. David > kfree(obj); > > return ret; > -- > 2.30.2 >
Hi, On 11/7/22 19:54, David E. Box wrote: > On Wed, 2022-11-02 at 22:23 +0100, Armin Wolf wrote: >> When the DDV interface returns a buffer, it actually >> returns a acpi buffer containing an integer (buffer size) >> and another acpi buffer (buffer content). >> The size of the buffer may be smaller than the size of >> the buffer content, which is perfectly valid and should not >> be treated as an error. > > Is there documentation for this that you can refer to? > >> Also use the buffer size instead of the buffer content size >> when accessing the buffer to prevent accessing bogus data. >> >> Tested on a Dell Inspiron 3505. >> >> Signed-off-by: Armin Wolf <W_Armin@gmx.de> >> --- >> drivers/platform/x86/dell/dell-wmi-ddv.c | 12 +++++++----- >> 1 file changed, 7 insertions(+), 5 deletions(-) >> >> diff --git a/drivers/platform/x86/dell/dell-wmi-ddv.c >> b/drivers/platform/x86/dell/dell-wmi-ddv.c >> index 699feae3c435..1a001296e8c6 100644 >> --- a/drivers/platform/x86/dell/dell-wmi-ddv.c >> +++ b/drivers/platform/x86/dell/dell-wmi-ddv.c >> @@ -129,9 +129,9 @@ static int dell_wmi_ddv_query_buffer(struct wmi_device >> *wdev, enum dell_ddv_meth >> if (obj->package.elements[1].type != ACPI_TYPE_BUFFER) >> goto err_free; >> >> - if (buffer_size != obj->package.elements[1].buffer.length) { >> + if (buffer_size > obj->package.elements[1].buffer.length) { >> dev_warn(&wdev->dev, >> - FW_WARN "ACPI buffer size (%llu) does not match WMI >> buffer size (%d)\n", >> + FW_WARN "WMI buffer size (%llu) exceeds ACPI buffer >> size (%d)\n", >> buffer_size, obj->package.elements[1].buffer.length); >> >> goto err_free; >> @@ -271,15 +271,17 @@ static int dell_wmi_ddv_buffer_read(struct seq_file >> *seq, enum dell_ddv_method m >> struct device *dev = seq->private; >> struct dell_wmi_ddv_data *data = dev_get_drvdata(dev); >> union acpi_object *obj; >> - union acpi_object buf; >> + u64 size; >> + u8 *buf; >> int ret; >> >> ret = dell_wmi_ddv_query_buffer(data->wdev, method, 0, &obj); >> if (ret < 0) >> return ret; >> >> - buf = obj->package.elements[1]; >> - ret = seq_write(seq, buf.buffer.pointer, buf.buffer.length); >> + size = obj->package.elements[0].integer.value; >> + buf = obj->package.elements[1].buffer.pointer; >> + ret = seq_write(seq, buf, size); > > Okay, so the buffer may provide more space than what should actually be used > according to the size field. This looks like a bug that should have a fixes tag > on the original commit. I have already merged this and both the original commit as well as this fix will land in 6.2, so I don't think a Fixes commit is really necessary in this case. Also the old code checked that the 2 sizes matched, so it was more strict and as such running only the original patch should not lead to buffer overruns or anything like that. Regards, Hans
Am 07.11.22 um 20:49 schrieb Hans de Goede: > Hi, > > On 11/7/22 19:54, David E. Box wrote: >> On Wed, 2022-11-02 at 22:23 +0100, Armin Wolf wrote: >>> When the DDV interface returns a buffer, it actually >>> returns a acpi buffer containing an integer (buffer size) >>> and another acpi buffer (buffer content). >>> The size of the buffer may be smaller than the size of >>> the buffer content, which is perfectly valid and should not >>> be treated as an error. >> Is there documentation for this that you can refer to? Yes and no. With the bmf2mof tool, i was able to extract the following MOF-description of the WMI interface: [WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x409"), Description("WMI Function"), guid("{8A42EA14-4F2A-FD45-6422-0087F7A7E608}")] class DDVWmiMethodFunction { [key, read] string InstanceName; [read] boolean Active; [WmiMethodId(1), Implemented, read, write, Description("Return Battery Design Capacity.")] void BatteryDesignCapacity([in] uint32 arg2, [out] uint32 argr); [WmiMethodId(2), Implemented, read, write, Description("Return Battery Full Charge Capacity.")] void BatteryFullChargeCapacity([in] uint32 arg2, [out] uint32 argr); [WmiMethodId(3), Implemented, read, write, Description("Return Battery Manufacture Name.")] void BatteryManufactureName([in] uint32 arg2, [out] string argr); [WmiMethodId(4), Implemented, read, write, Description("Return Battery Manufacture Date.")] void BatteryManufactureDate([in] uint32 arg2, [out] uint32 argr); [WmiMethodId(5), Implemented, read, write, Description("Return Battery Serial Number.")] void BatterySerialNumber([in] uint32 arg2, [out] uint32 argr); [WmiMethodId(6), Implemented, read, write, Description("Return Battery Chemistry Value.")] void BatteryChemistryValue([in] uint32 arg2, [out] string argr); [WmiMethodId(7), Implemented, read, write, Description("Return Battery Temperature.")] void BatteryTemperature([in] uint32 arg2, [out] uint32 argr); [WmiMethodId(8), Implemented, read, write, Description("Return Battery Current.")] void BatteryCurrent([in] uint32 arg2, [out] uint32 argr); [WmiMethodId(9), Implemented, read, write, Description("Return Battery Voltage.")] void BatteryVoltage([in] uint32 arg2, [out] uint32 argr); [WmiMethodId(10), Implemented, read, write, Description("Return Battery Manufacture Access(MA code).")] void BatteryManufactureAceess([in] uint32 arg2, [out] uint32 argr); [WmiMethodId(11), Implemented, read, write, Description("Return Battery Relative State-Of-Charge.")] void BatteryRelativeStateOfCharge([in] uint32 arg2, [out] uint32 argr); [WmiMethodId(12), Implemented, read, write, Description("Return Battery Cycle Count")] void BatteryCycleCount([in] uint32 arg2, [out] uint32 argr); [WmiMethodId(13), Implemented, read, write, Description("Return Battery ePPID")] void BatteryePPID([in] uint32 arg2, [out] string argr); [WmiMethodId(14), Implemented, read, write, Description("Return Battery Raw Analytics Start")] void BatteryeRawAnalyticsStart([in] uint32 arg2, [out] uint32 argr); [WmiMethodId(15), Implemented, read, write, Description("Return Battery Raw Analytics")] void BatteryeRawAnalytics([in] uint32 arg2, [out] uint32 RawSize, [out, WmiSizeIs("RawSize") : ToInstance] uint8 RawData[]); [WmiMethodId(16), Implemented, read, write, Description("Return Battery Design Voltage.")] void BatteryDesignVoltage([in] uint32 arg2, [out] uint32 argr); [WmiMethodId(18), Implemented, read, write, Description("Return Version.")] void ReturnVersion([in] uint32 arg2, [out] uint32 argr); [WmiMethodId(32), Implemented, read, write, Description("Return Fan Sensor Information")] void FanSensorInformation([in] uint32 arg2, [out] uint32 RawSize, [out, WmiSizeIs("RawSize") : ToInstance] uint8 RawData[]); [WmiMethodId(34), Implemented, read, write, Description("Return Thermal Sensor Information")] void ThermalSensorInformation([in] uint32 arg2, [out] uint32 RawSize, [out, WmiSizeIs("RawSize") : ToInstance] uint8 RawData[]); }; I also found out that an "empty" fan sensor information buffer still has a content buffer length of 1, but a size integer of 0. >>> Also use the buffer size instead of the buffer content size >>> when accessing the buffer to prevent accessing bogus data. >>> >>> Tested on a Dell Inspiron 3505. >>> >>> Signed-off-by: Armin Wolf <W_Armin@gmx.de> >>> --- >>> drivers/platform/x86/dell/dell-wmi-ddv.c | 12 +++++++----- >>> 1 file changed, 7 insertions(+), 5 deletions(-) >>> >>> diff --git a/drivers/platform/x86/dell/dell-wmi-ddv.c >>> b/drivers/platform/x86/dell/dell-wmi-ddv.c >>> index 699feae3c435..1a001296e8c6 100644 >>> --- a/drivers/platform/x86/dell/dell-wmi-ddv.c >>> +++ b/drivers/platform/x86/dell/dell-wmi-ddv.c >>> @@ -129,9 +129,9 @@ static int dell_wmi_ddv_query_buffer(struct wmi_device >>> *wdev, enum dell_ddv_meth >>> if (obj->package.elements[1].type != ACPI_TYPE_BUFFER) >>> goto err_free; >>> >>> - if (buffer_size != obj->package.elements[1].buffer.length) { >>> + if (buffer_size > obj->package.elements[1].buffer.length) { >>> dev_warn(&wdev->dev, >>> - FW_WARN "ACPI buffer size (%llu) does not match WMI >>> buffer size (%d)\n", >>> + FW_WARN "WMI buffer size (%llu) exceeds ACPI buffer >>> size (%d)\n", >>> buffer_size, obj->package.elements[1].buffer.length); >>> >>> goto err_free; >>> @@ -271,15 +271,17 @@ static int dell_wmi_ddv_buffer_read(struct seq_file >>> *seq, enum dell_ddv_method m >>> struct device *dev = seq->private; >>> struct dell_wmi_ddv_data *data = dev_get_drvdata(dev); >>> union acpi_object *obj; >>> - union acpi_object buf; >>> + u64 size; >>> + u8 *buf; >>> int ret; >>> >>> ret = dell_wmi_ddv_query_buffer(data->wdev, method, 0, &obj); >>> if (ret < 0) >>> return ret; >>> >>> - buf = obj->package.elements[1]; >>> - ret = seq_write(seq, buf.buffer.pointer, buf.buffer.length); >>> + size = obj->package.elements[0].integer.value; >>> + buf = obj->package.elements[1].buffer.pointer; >>> + ret = seq_write(seq, buf, size); >> Okay, so the buffer may provide more space than what should actually be used >> according to the size field. This looks like a bug that should have a fixes tag >> on the original commit. > I have already merged this and both the original commit as well as > this fix will land in 6.2, so I don't think a Fixes commit is > really necessary in this case. > > Also the old code checked that the 2 sizes matched, so it was more > strict and as such running only the original patch should not lead > to buffer overruns or anything like that. > > Regards, > > Hans > >
diff --git a/drivers/platform/x86/dell/dell-wmi-ddv.c b/drivers/platform/x86/dell/dell-wmi-ddv.c index 699feae3c435..1a001296e8c6 100644 --- a/drivers/platform/x86/dell/dell-wmi-ddv.c +++ b/drivers/platform/x86/dell/dell-wmi-ddv.c @@ -129,9 +129,9 @@ static int dell_wmi_ddv_query_buffer(struct wmi_device *wdev, enum dell_ddv_meth if (obj->package.elements[1].type != ACPI_TYPE_BUFFER) goto err_free; - if (buffer_size != obj->package.elements[1].buffer.length) { + if (buffer_size > obj->package.elements[1].buffer.length) { dev_warn(&wdev->dev, - FW_WARN "ACPI buffer size (%llu) does not match WMI buffer size (%d)\n", + FW_WARN "WMI buffer size (%llu) exceeds ACPI buffer size (%d)\n", buffer_size, obj->package.elements[1].buffer.length); goto err_free; @@ -271,15 +271,17 @@ static int dell_wmi_ddv_buffer_read(struct seq_file *seq, enum dell_ddv_method m struct device *dev = seq->private; struct dell_wmi_ddv_data *data = dev_get_drvdata(dev); union acpi_object *obj; - union acpi_object buf; + u64 size; + u8 *buf; int ret; ret = dell_wmi_ddv_query_buffer(data->wdev, method, 0, &obj); if (ret < 0) return ret; - buf = obj->package.elements[1]; - ret = seq_write(seq, buf.buffer.pointer, buf.buffer.length); + size = obj->package.elements[0].integer.value; + buf = obj->package.elements[1].buffer.pointer; + ret = seq_write(seq, buf, size); kfree(obj); return ret;