Message ID | 20230621151155.78279-1-andriy.shevchenko@linux.intel.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp4469039vqr; Wed, 21 Jun 2023 09:00:51 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ77rgnqU8q81hd6+IR44yA8CjKTD3sBfbnZUx/sAJ73cgLxqaW7EV5WxAO3PidnSl6yKjha X-Received: by 2002:a17:90b:2398:b0:25b:e4ac:98ac with SMTP id mr24-20020a17090b239800b0025be4ac98acmr15547316pjb.17.1687363251095; Wed, 21 Jun 2023 09:00:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1687363251; cv=none; d=google.com; s=arc-20160816; b=R7fbYNjUuDFMZAKBcsO8WDAmOiRmlKyNNsK1XR0WRPXS8ZJcxusxYjnQMTsEDRuczN MvB4asPNaYnBXcaDmey+31JNYtw/yH+iPC0zSDzzFsCjDp4IPm6D/qG98BiBGV+TXntf oaVStAw0VSVT0O0Wn10rmj32+iSXkuuVlDJhLxcXi2rNWHDEmdhFUI/J+OWGF4nHiDeO m7/noL2YWDMcl4BaxE7x8Jp7x0WSzug/iWXBsp920R3jt6z1CiWUcUFt/0+tpyGcyZdH a2abVjOxuWtvxcPS1K5geO88dOQgahFvhy+B+OKHJYbYOmISrrTwOqw2OAXzDKnUKNV5 3r2w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=EqNnzcEt0dqsAgd8Wl90RBsdiYvQtN4rYXjhgoqqscE=; b=ibJOuuZZxRnITz5vTlcU69izRHrU0x9JOODWnoTak+uRStai/59Dh8u5eoy1YkzM2K i+j2ScJtryf/Zdbu/rhXp0EEqKwjXm90cVwbQNODXgBZBgf+LSIZ5ZbPra+smfUeEaVb 7NqRd5eXARtVK2NxlTMMEDRYuAZVH4LW7zEtVZKcSAKbCcdTxByRJSb7nfggknBVn6pM nA1j2a4QioRUVqVBL/imn3cOKobXK5QKBJJuc3WtVvhTZCUDbHVCqwH8TG3O+JqhhjJj Xh43mEym9AoNl23rIcj4ao5fs26Tz+omiiEpmyMpPbDh9rGnIAQVV2NZF6lL2dnYqQXN UhrQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=GFLP5JDI; 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=intel.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id m20-20020a17090b069400b0024e47fae466si544691pjz.180.2023.06.21.09.00.36; Wed, 21 Jun 2023 09:00:51 -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=@intel.com header.s=Intel header.b=GFLP5JDI; 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=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233218AbjFUPQa (ORCPT <rfc822;maxin.john@gmail.com> + 99 others); Wed, 21 Jun 2023 11:16:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56204 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233282AbjFUPQF (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 21 Jun 2023 11:16:05 -0400 Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2302B5254; Wed, 21 Jun 2023 08:11:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1687360312; x=1718896312; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=avPldn+bfrcBhDUfOYNR74bNnMBvVnz4MZjZ32hxuoE=; b=GFLP5JDI7/6kbhhGidyyOFWpiTV2k10kTnNZtqVcbVE/PtWR07jX406w tpuGjtJ64HwAzDs7Fc1McxzTsN7gIzuJZPl9vN+JKAcxeliBIS6hM7bBK h2siX21VObUav1gwF/I3OxY8/bVDnbPorGnXRVegzflqy001nQ1c34dZT FPkOTq8H4J2W4hNZTQvfCL2iEm6eoze2oLAMoc+triLEBbEFpctPUjclZ i2+0lcVKCXXyh+BycKBOksNGDZhGN80wrJ2Cvi5k7MxaArW7gfC0vaQrC eqi6lls0rKztIbaJvEpz3PVfyxoT9L9CBuHmxrJj01wCh0wPR8NwiwlkP A==; X-IronPort-AV: E=McAfee;i="6600,9927,10748"; a="344937863" X-IronPort-AV: E=Sophos;i="6.00,260,1681196400"; d="scan'208";a="344937863" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Jun 2023 08:11:50 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10748"; a="827489542" X-IronPort-AV: E=Sophos;i="6.00,260,1681196400"; d="scan'208";a="827489542" Received: from black.fi.intel.com ([10.237.72.28]) by fmsmga002.fm.intel.com with ESMTP; 21 Jun 2023 08:11:47 -0700 Received: by black.fi.intel.com (Postfix, from userid 1003) id 6E6291FD; Wed, 21 Jun 2023 18:11:58 +0300 (EEST) From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> To: Hans de Goede <hdegoede@redhat.com>, platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Mark Gross <markgross@kernel.org>, Andy Shevchenko <andriy.shevchenko@linux.intel.com> Subject: [PATCH v1 1/2] platform/x86: wmi: Break possible infinite loop when parsing GUID Date: Wed, 21 Jun 2023 18:11:54 +0300 Message-Id: <20230621151155.78279-1-andriy.shevchenko@linux.intel.com> X-Mailer: git-send-email 2.40.0.1.gaa8946217a0b MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,SPF_HELO_NONE,SPF_NONE, T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED 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?1769328608331032987?= X-GMAIL-MSGID: =?utf-8?q?1769328608331032987?= |
Series |
[v1,1/2] platform/x86: wmi: Break possible infinite loop when parsing GUID
|
|
Commit Message
Andy Shevchenko
June 21, 2023, 3:11 p.m. UTC
The while-loop may break on one of the two conditions, either ID string
is empty or GUID matches. The second one, may never be reached if the
parsed string is not correct GUID. In such a case the loop will never
advance to check the next ID.
Break possible infinite loop by factoring out guid_parse_and_compare()
helper which may be moved to the generic header for everyone later on
and preventing from similar mistake in the future.
Interestingly that firstly it appeared when WMI was turned into a bus
driver, but later when duplicated GUIDs were checked, the while-loop
has been replaced by for-loop and hence no mistake made again.
Fixes: a48e23385fcf ("platform/x86: wmi: add context pointer field to struct wmi_device_id")
Fixes: 844af950da94 ("platform/x86: wmi: Turn WMI into a bus driver")
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
drivers/platform/x86/wmi.c | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
Comments
Am 21.06.23 um 17:11 schrieb Andy Shevchenko: > The while-loop may break on one of the two conditions, either ID string > is empty or GUID matches. The second one, may never be reached if the > parsed string is not correct GUID. In such a case the loop will never > advance to check the next ID. > > Break possible infinite loop by factoring out guid_parse_and_compare() > helper which may be moved to the generic header for everyone later on > and preventing from similar mistake in the future. > > Interestingly that firstly it appeared when WMI was turned into a bus > driver, but later when duplicated GUIDs were checked, the while-loop > has been replaced by for-loop and hence no mistake made again. > > Fixes: a48e23385fcf ("platform/x86: wmi: add context pointer field to struct wmi_device_id") > Fixes: 844af950da94 ("platform/x86: wmi: Turn WMI into a bus driver") > Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> > --- > drivers/platform/x86/wmi.c | 22 ++++++++++++---------- > 1 file changed, 12 insertions(+), 10 deletions(-) > > diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c > index 5b95d7aa5c2f..098512a53170 100644 > --- a/drivers/platform/x86/wmi.c > +++ b/drivers/platform/x86/wmi.c > @@ -136,6 +136,16 @@ static acpi_status find_guid(const char *guid_string, struct wmi_block **out) > return AE_NOT_FOUND; > } > > +static bool guid_parse_and_compare(const char *string, const guid_t *guid) > +{ > + guid_t guid_input; > + > + if (guid_parse(string, &guid_input)) > + return false; > + > + return guid_equal(&guid_input, guid); > +} > + > static const void *find_guid_context(struct wmi_block *wblock, > struct wmi_driver *wdriver) > { > @@ -146,11 +156,7 @@ static const void *find_guid_context(struct wmi_block *wblock, > return NULL; > > while (*id->guid_string) { > - guid_t guid_input; > - > - if (guid_parse(id->guid_string, &guid_input)) > - continue; > - if (guid_equal(&wblock->gblock.guid, &guid_input)) > + if (guid_parse_and_compare(id->guid_string, &wblock->gblock.guid)) > return id->context; > id++; > } > @@ -895,11 +901,7 @@ static int wmi_dev_match(struct device *dev, struct device_driver *driver) > return 0; > > while (*id->guid_string) { > - guid_t driver_guid; > - > - if (WARN_ON(guid_parse(id->guid_string, &driver_guid))) Hi, just an idea: how about printing an error/debug message in case of an malformed GUID? This could be useful when searching for typos in GUIDs used by WMI drivers. > - continue; > - if (guid_equal(&driver_guid, &wblock->gblock.guid)) > + if (guid_parse_and_compare(id->guid_string, &wblock->gblock.guid)) > return 1; > > id++; Works on my Dell Inspiron 3505, so for this patch: Tested-by: Armin Wolf <W_Armin@gmx.de> Armin Wolf
Hi 2023. június 21., szerda 23:20 keltezéssel, Armin Wolf <W_Armin@gmx.de> írta: > [...] > > @@ -895,11 +901,7 @@ static int wmi_dev_match(struct device *dev, struct device_driver *driver) > > return 0; > > > > while (*id->guid_string) { > > - guid_t driver_guid; > > - > > - if (WARN_ON(guid_parse(id->guid_string, &driver_guid))) > > Hi, > > just an idea: how about printing an error/debug message in case of an malformed GUID? > This could be useful when searching for typos in GUIDs used by WMI drivers. > [...] Wouldn't it be better to change `__wmi_driver_register()` to check that? Regards, Barnabás Pőcze
Am 21.06.23 um 23:29 schrieb Barnabás Pőcze: > Hi > > > 2023. június 21., szerda 23:20 keltezéssel, Armin Wolf <W_Armin@gmx.de> írta: > >> [...] >>> @@ -895,11 +901,7 @@ static int wmi_dev_match(struct device *dev, struct device_driver *driver) >>> return 0; >>> >>> while (*id->guid_string) { >>> - guid_t driver_guid; >>> - >>> - if (WARN_ON(guid_parse(id->guid_string, &driver_guid))) >> Hi, >> >> just an idea: how about printing an error/debug message in case of an malformed GUID? >> This could be useful when searching for typos in GUIDs used by WMI drivers. >> [...] > Wouldn't it be better to change `__wmi_driver_register()` to check that? > > > Regards, > Barnabás Pőcze Good point, i guess we can just forget this idea. The original motivation for it was the WARN_ON() inside wmi_dev_match(), but your right that this is the wrong place to check the GUID formating. Armin Wolf
On Wed, Jun 21, 2023 at 11:50:51PM +0200, Armin Wolf wrote: > Am 21.06.23 um 23:29 schrieb Barnabás Pőcze: > > 2023. június 21., szerda 23:20 keltezéssel, Armin Wolf <W_Armin@gmx.de> írta: [...] > > > > - if (WARN_ON(guid_parse(id->guid_string, &driver_guid))) > > > > > > just an idea: how about printing an error/debug message in case of an > > > malformed GUID? This could be useful when searching for typos in GUIDs > > > used by WMI drivers. [...] > > Wouldn't it be better to change `__wmi_driver_register()` to check that? > > Good point, i guess we can just forget this idea. The original motivation for > it was the WARN_ON() inside wmi_dev_match(), but your right that this is the > wrong place to check the GUID formating. I'm not sure what do you want me to do since patches are tested already. I think that WARN_ON() is a bit bogus. First of all, it can be easily transformed to BUG()-equivalent with panic_on_oops and hence kill the entire system. If we need the message about wrong GUID format, it should be done elsewhere (modpost ?). I.o.w. we shan't expect that code, controlled by us, shoots to our foot.
On Wed, Jun 21, 2023 at 11:20:04PM +0200, Armin Wolf wrote: > Am 21.06.23 um 17:11 schrieb Andy Shevchenko: ... > > - if (WARN_ON(guid_parse(id->guid_string, &driver_guid))) > > just an idea: how about printing an error/debug message in case of an > malformed GUID? This could be useful when searching for typos in GUIDs used > by WMI drivers. Commented on that separately. ... > Works on my Dell Inspiron 3505, so for this patch: > Tested-by: Armin Wolf <W_Armin@gmx.de> Thank you for testing!
On Thu, Jun 22, 2023 at 11:43:20AM +0300, Andy Shevchenko wrote: > On Wed, Jun 21, 2023 at 11:50:51PM +0200, Armin Wolf wrote: ... > I think that WARN_ON() is a bit bogus. First of all, it can be easily > transformed to BUG()-equivalent with panic_on_oops and hence kill the > entire system. If we need the message about wrong GUID format, it should > be done elsewhere (modpost ?). I.o.w. we shan't expect that code, > controlled by us, shoots to our foot. Additional info. There will be another driver elsewhere that may use similar API and also needs GUID in device ID table. Looking into that implementation it seems that validation should be made in file2alias.c for WMI and reused by that driver. So, taking into account that we have no wrong IDs so far, I would drop WARN_ON() here and guarantee that file2alias.c will be changed to validate the GUID one way or the other. Would it work? Hans, what is your comment here?
Hi Andy, On 6/22/23 17:00, Andy Shevchenko wrote: > On Thu, Jun 22, 2023 at 11:43:20AM +0300, Andy Shevchenko wrote: >> On Wed, Jun 21, 2023 at 11:50:51PM +0200, Armin Wolf wrote: > > ... > >> I think that WARN_ON() is a bit bogus. First of all, it can be easily >> transformed to BUG()-equivalent with panic_on_oops and hence kill the >> entire system. If we need the message about wrong GUID format, it should >> be done elsewhere (modpost ?). I.o.w. we shan't expect that code, >> controlled by us, shoots to our foot. > > Additional info. There will be another driver elsewhere that may use similar > API and also needs GUID in device ID table. > > Looking into that implementation it seems that validation should be made in > file2alias.c for WMI and reused by that driver. > > So, taking into account that we have no wrong IDs so far, I would drop > WARN_ON() here and guarantee that file2alias.c will be changed to validate > the GUID one way or the other. > > Would it work? Hans, what is your comment here? I agree that warning on malformed GUIDs does not belong here and your patch already drops the WARN_ON while switching to the new guid_parse_and_compare() helper. So I'll go and merge this into my fixes branch once rc1 is out. Regards, Hans
On Tue, Jul 04, 2023 at 01:02:11PM +0200, Hans de Goede wrote: > On 6/22/23 17:00, Andy Shevchenko wrote: > > On Thu, Jun 22, 2023 at 11:43:20AM +0300, Andy Shevchenko wrote: > >> On Wed, Jun 21, 2023 at 11:50:51PM +0200, Armin Wolf wrote: ... > >> I think that WARN_ON() is a bit bogus. First of all, it can be easily > >> transformed to BUG()-equivalent with panic_on_oops and hence kill the > >> entire system. If we need the message about wrong GUID format, it should > >> be done elsewhere (modpost ?). I.o.w. we shan't expect that code, > >> controlled by us, shoots to our foot. > > > > Additional info. There will be another driver elsewhere that may use similar > > API and also needs GUID in device ID table. > > > > Looking into that implementation it seems that validation should be made in > > file2alias.c for WMI and reused by that driver. > > > > So, taking into account that we have no wrong IDs so far, I would drop > > WARN_ON() here and guarantee that file2alias.c will be changed to validate > > the GUID one way or the other. > > > > Would it work? Hans, what is your comment here? > > > I agree that warning on malformed GUIDs does not belong here and > your patch already drops the WARN_ON while switching to the new > guid_parse_and_compare() helper. > > So I'll go and merge this into my fixes branch once rc1 is out. Thank you!
Hi, On 6/21/23 17:11, Andy Shevchenko wrote: > The while-loop may break on one of the two conditions, either ID string > is empty or GUID matches. The second one, may never be reached if the > parsed string is not correct GUID. In such a case the loop will never > advance to check the next ID. > > Break possible infinite loop by factoring out guid_parse_and_compare() > helper which may be moved to the generic header for everyone later on > and preventing from similar mistake in the future. > > Interestingly that firstly it appeared when WMI was turned into a bus > driver, but later when duplicated GUIDs were checked, the while-loop > has been replaced by for-loop and hence no mistake made again. > > Fixes: a48e23385fcf ("platform/x86: wmi: add context pointer field to struct wmi_device_id") > Fixes: 844af950da94 ("platform/x86: wmi: Turn WMI into a bus driver") > Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Thank you for your series, I've applied this series to my fixes branch: https://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git/log/?h=fixes I will include this patch in my next fixes pull-req to Linus for the current kernel development cycle. Regards, Hans > --- > drivers/platform/x86/wmi.c | 22 ++++++++++++---------- > 1 file changed, 12 insertions(+), 10 deletions(-) > > diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c > index 5b95d7aa5c2f..098512a53170 100644 > --- a/drivers/platform/x86/wmi.c > +++ b/drivers/platform/x86/wmi.c > @@ -136,6 +136,16 @@ static acpi_status find_guid(const char *guid_string, struct wmi_block **out) > return AE_NOT_FOUND; > } > > +static bool guid_parse_and_compare(const char *string, const guid_t *guid) > +{ > + guid_t guid_input; > + > + if (guid_parse(string, &guid_input)) > + return false; > + > + return guid_equal(&guid_input, guid); > +} > + > static const void *find_guid_context(struct wmi_block *wblock, > struct wmi_driver *wdriver) > { > @@ -146,11 +156,7 @@ static const void *find_guid_context(struct wmi_block *wblock, > return NULL; > > while (*id->guid_string) { > - guid_t guid_input; > - > - if (guid_parse(id->guid_string, &guid_input)) > - continue; > - if (guid_equal(&wblock->gblock.guid, &guid_input)) > + if (guid_parse_and_compare(id->guid_string, &wblock->gblock.guid)) > return id->context; > id++; > } > @@ -895,11 +901,7 @@ static int wmi_dev_match(struct device *dev, struct device_driver *driver) > return 0; > > while (*id->guid_string) { > - guid_t driver_guid; > - > - if (WARN_ON(guid_parse(id->guid_string, &driver_guid))) > - continue; > - if (guid_equal(&driver_guid, &wblock->gblock.guid)) > + if (guid_parse_and_compare(id->guid_string, &wblock->gblock.guid)) > return 1; > > id++;
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 5b95d7aa5c2f..098512a53170 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -136,6 +136,16 @@ static acpi_status find_guid(const char *guid_string, struct wmi_block **out) return AE_NOT_FOUND; } +static bool guid_parse_and_compare(const char *string, const guid_t *guid) +{ + guid_t guid_input; + + if (guid_parse(string, &guid_input)) + return false; + + return guid_equal(&guid_input, guid); +} + static const void *find_guid_context(struct wmi_block *wblock, struct wmi_driver *wdriver) { @@ -146,11 +156,7 @@ static const void *find_guid_context(struct wmi_block *wblock, return NULL; while (*id->guid_string) { - guid_t guid_input; - - if (guid_parse(id->guid_string, &guid_input)) - continue; - if (guid_equal(&wblock->gblock.guid, &guid_input)) + if (guid_parse_and_compare(id->guid_string, &wblock->gblock.guid)) return id->context; id++; } @@ -895,11 +901,7 @@ static int wmi_dev_match(struct device *dev, struct device_driver *driver) return 0; while (*id->guid_string) { - guid_t driver_guid; - - if (WARN_ON(guid_parse(id->guid_string, &driver_guid))) - continue; - if (guid_equal(&driver_guid, &wblock->gblock.guid)) + if (guid_parse_and_compare(id->guid_string, &wblock->gblock.guid)) return 1; id++;