diff mbox series

[v2,2/2] acpi/wmi: Warn if WMI GUIDs from the Windows driver samples are found

Message ID 20241011214009.28540-2-W_Armin@gmx.de
State Accepted
Headers show
Series [v2,1/2] lib: fwts_acpi_object_eval: Do not return FWTS_OK if method lookup fails | expand

Commit Message

Armin Wolf Oct. 11, 2024, 9:40 p.m. UTC
Some manufacturers like Uniwill just blindly copy the example code
from the Windows driver samples without generating new unique WMI GUIDs.

This prevents WMI drivers for those WMI GUIDs from being loaded
automatically since they cannot reliably identify if a WMI device
with such a GUID is actually supported by them.

Signed-off-by: Armin Wolf <W_Armin@gmx.de>
---
Changes since v1:
- use LOG_LEVEL_MEDIUM instead of LOG_LEVEL_CRITICAL
---
 src/acpi/wmi/wmi.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

--
2.39.5

Comments

Ivan Hu Oct. 17, 2024, 3:55 a.m. UTC | #1
Acked-by: Ivan Hu <ivan.hu@canonical.com>

On 2024/10/12 05:40, Armin Wolf wrote:
> Some manufacturers like Uniwill just blindly copy the example code
> from the Windows driver samples without generating new unique WMI GUIDs.
> 
> This prevents WMI drivers for those WMI GUIDs from being loaded
> automatically since they cannot reliably identify if a WMI device
> with such a GUID is actually supported by them.
> 
> Signed-off-by: Armin Wolf <W_Armin@gmx.de>
> ---
> Changes since v1:
> - use LOG_LEVEL_MEDIUM instead of LOG_LEVEL_CRITICAL
> ---
>   src/acpi/wmi/wmi.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 46 insertions(+)
> 
> diff --git a/src/acpi/wmi/wmi.c b/src/acpi/wmi/wmi.c
> index 7a746354..98a73d46 100644
> --- a/src/acpi/wmi/wmi.c
> +++ b/src/acpi/wmi/wmi.c
> @@ -129,6 +129,25 @@ static fwts_wmi_known_guid fwts_wmi_known_guids[] = {
>   	{ NULL, NULL, NULL }
>   };
> 
> +/*
> + *  List of WMI GUIDs used inside the Windows driver samples.
> + *
> + *  Some manufacturers just blindly copy those, which prevents their WMI drivers
> + *  from being loaded automatically since those GUIDs are not unique and cannot
> + *  be used for reliable WMI device identification.
> + */
> +static const char * const windows_example_wmi_guids[] = {
> +	"ABBC0F6A-8EA1-11D1-00A0-C90629100000",
> +	"ABBC0F6B-8EA1-11D1-00A0-C90629100000",
> +	"ABBC0F6C-8EA1-11D1-00A0-C90629100000",
> +	"ABBC0F6D-8EA1-11D1-00A0-C90629100000",
> +	"ABBC0F6E-8EA1-11D1-00A0-C90629100000",
> +	"ABBC0F6F-8EA1-11D1-00A0-C90629100000",
> +	"ABBC0F70-8EA1-11D1-00A0-C90629100000",
> +	"ABBC0F71-8EA1-11D1-00A0-C90629100000",
> +	"ABBC0F72-8EA1-11D1-00A0-C90629100000"
> +};
> +
>   /*
>    *  WMI flag to text mappings
>    */
> @@ -341,6 +360,31 @@ static void wmi_method_exist_count(
>   			guid_str, object_name, wm_name);
>   }
> 
> +/*
> + *  wmi_guid_copycat()
> + *	Warn if a WMI from the Windows driver samples was found. This usually means that
> + *	the manufacturer just blindly copied the example code without generating new
> + *	unique WMI GUIDs.
> + */
> +static void wmi_guid_copycat(
> +	fwts_framework *fw,
> +	const char *guid_str)
> +{
> +	int i;
> +
> +	for (i = 0; i < FWTS_ARRAY_SIZE(windows_example_wmi_guids); i++) {
> +		if (strcmp(guid_str, windows_example_wmi_guids[i]) == 0) {
> +			fwts_failed(fw, LOG_LEVEL_MEDIUM,
> +				"WMIExampleGUIDCopycat",
> +				"GUID %s has likely been copied from the Windows driver samples, "
> +				"this is a firmware bug that prevents WMI drivers from reliably "
> +				"detecting such WMI devices since their GUID is not unique.",
> +				guid_str);
> +			return;
> +		}
> +	}
> +}
> +
>   /*
>    *  wmi_no_known_driver()
>    *	grumble that the kernel does not have a known handler for this GUID
> @@ -462,6 +506,8 @@ static void wmi_parse_wdg_data(
>   			wmi_block_query_exist_count(fw, info, acpi_object_name, guid_str);
>   		}
> 
> +		wmi_guid_copycat(fw, guid_str);
> +
>   		if (info->instance == 0)
>   			fwts_failed(fw, LOG_LEVEL_LOW, "WMIZeroInstance",
>   				    "GUID %s has zero instances", guid_str);
> --
> 2.39.5
>
diff mbox series

Patch

diff --git a/src/acpi/wmi/wmi.c b/src/acpi/wmi/wmi.c
index 7a746354..98a73d46 100644
--- a/src/acpi/wmi/wmi.c
+++ b/src/acpi/wmi/wmi.c
@@ -129,6 +129,25 @@  static fwts_wmi_known_guid fwts_wmi_known_guids[] = {
 	{ NULL, NULL, NULL }
 };

+/*
+ *  List of WMI GUIDs used inside the Windows driver samples.
+ *
+ *  Some manufacturers just blindly copy those, which prevents their WMI drivers
+ *  from being loaded automatically since those GUIDs are not unique and cannot
+ *  be used for reliable WMI device identification.
+ */
+static const char * const windows_example_wmi_guids[] = {
+	"ABBC0F6A-8EA1-11D1-00A0-C90629100000",
+	"ABBC0F6B-8EA1-11D1-00A0-C90629100000",
+	"ABBC0F6C-8EA1-11D1-00A0-C90629100000",
+	"ABBC0F6D-8EA1-11D1-00A0-C90629100000",
+	"ABBC0F6E-8EA1-11D1-00A0-C90629100000",
+	"ABBC0F6F-8EA1-11D1-00A0-C90629100000",
+	"ABBC0F70-8EA1-11D1-00A0-C90629100000",
+	"ABBC0F71-8EA1-11D1-00A0-C90629100000",
+	"ABBC0F72-8EA1-11D1-00A0-C90629100000"
+};
+
 /*
  *  WMI flag to text mappings
  */
@@ -341,6 +360,31 @@  static void wmi_method_exist_count(
 			guid_str, object_name, wm_name);
 }

+/*
+ *  wmi_guid_copycat()
+ *	Warn if a WMI from the Windows driver samples was found. This usually means that
+ *	the manufacturer just blindly copied the example code without generating new
+ *	unique WMI GUIDs.
+ */
+static void wmi_guid_copycat(
+	fwts_framework *fw,
+	const char *guid_str)
+{
+	int i;
+
+	for (i = 0; i < FWTS_ARRAY_SIZE(windows_example_wmi_guids); i++) {
+		if (strcmp(guid_str, windows_example_wmi_guids[i]) == 0) {
+			fwts_failed(fw, LOG_LEVEL_MEDIUM,
+				"WMIExampleGUIDCopycat",
+				"GUID %s has likely been copied from the Windows driver samples, "
+				"this is a firmware bug that prevents WMI drivers from reliably "
+				"detecting such WMI devices since their GUID is not unique.",
+				guid_str);
+			return;
+		}
+	}
+}
+
 /*
  *  wmi_no_known_driver()
  *	grumble that the kernel does not have a known handler for this GUID
@@ -462,6 +506,8 @@  static void wmi_parse_wdg_data(
 			wmi_block_query_exist_count(fw, info, acpi_object_name, guid_str);
 		}

+		wmi_guid_copycat(fw, guid_str);
+
 		if (info->instance == 0)
 			fwts_failed(fw, LOG_LEVEL_LOW, "WMIZeroInstance",
 				    "GUID %s has zero instances", guid_str);