All of lore.kernel.org
 help / color / mirror / Atom feed
From: Janne Grunau via B4 Relay <devnull+j.jannau.net@kernel.org>
To: Bin Meng <bmeng.cn@gmail.com>, Marek Vasut <marex@denx.de>,
	 Tom Rini <trini@konsulko.com>, Simon Glass <sjg@chromium.org>,
	 Joe Hershberger <joe.hershberger@ni.com>
Cc: u-boot@lists.denx.de, asahi@lists.linux.dev,
	 Janne Grunau <j@jannau.net>
Subject: [PATCH v2 4/6] usb: Add environment based device blocklist
Date: Sun, 17 Mar 2024 12:07:06 +0100	[thread overview]
Message-ID: <20240317-asahi-keyboards-v2-4-d3f4b8384f68@jannau.net> (raw)
In-Reply-To: <20240317-asahi-keyboards-v2-0-d3f4b8384f68@jannau.net>

From: Janne Grunau <j@jannau.net>

Add the environment variable "usb_blocklist" to prevent USB devices
listed in it from being used. This allows to ignore devices which
trigger bugs in u-boot's USB stack or are undesirable for other reasons.
Devices emulating keyboards are one example. U-boot currently supports
only one USB keyboard device. Most commonly, people run into this with
Yubikeys, so let's ignore those in the default environment.

Based on previous USB keyboard specific patches for the same purpose.

Link: https://lore.kernel.org/u-boot/7ab604fb-0fec-4f5e-8708-7a3a7e2cb568@denx.de/
Signed-off-by: Janne Grunau <j@jannau.net>
---
 common/usb.c              | 56 +++++++++++++++++++++++++++++++++++++++++++++++
 doc/usage/environment.rst | 12 ++++++++++
 include/env_default.h     | 11 ++++++++++
 3 files changed, 79 insertions(+)

diff --git a/common/usb.c b/common/usb.c
index 836506dcd9..73af5be066 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -1084,6 +1084,57 @@ static int usb_prepare_device(struct usb_device *dev, int addr, bool do_read,
 	return 0;
 }
 
+static int usb_blocklist_parse_error(const char *blocklist, size_t pos)
+{
+	printf("usb_blocklist parse error at char %zu in \"%s\"\n", pos,
+	       blocklist);
+	return 0;
+}
+
+static int usb_device_is_blocked(u16 id_vendor, u16 id_product)
+{
+	ulong vid, pid;
+	char *end;
+	const char *block_str = env_get("usb_blocklist");
+	const char *cur = block_str;
+
+	/* parse "usb_blocklist" strictly */
+	while (cur && cur[0] != '\0') {
+		vid = simple_strtoul(cur, &end, 0);
+		if (cur == end || end[0] != ':')
+			return usb_blocklist_parse_error(block_str,
+							 cur - block_str);
+
+		cur = end + 1;
+		pid = simple_strtoul(cur, &end, 0);
+		if (cur == end && end[0] != '*')
+			return usb_blocklist_parse_error(block_str,
+							 cur - block_str);
+
+		if (end[0] == '*') {
+			/* use out of range idProduct as wildcard indication */
+			pid = U16_MAX + 1;
+			end++;
+		}
+		if (end[0] != ',' && end[0] != '\0')
+			return usb_blocklist_parse_error(block_str,
+							 cur - block_str);
+
+		if (id_vendor == vid && (pid > U16_MAX || id_product == pid)) {
+			printf("Ignoring USB device 0x%x:0x%x\n",id_vendor,
+			      id_product);
+			debug("Ignoring USB device 0x%x:0x%x\n",id_vendor,
+			      id_product);
+			return 1;
+		}
+		if (end[0] == '\0')
+			break;
+		cur = end + 1;
+	}
+
+	return 0;
+}
+
 int usb_select_config(struct usb_device *dev)
 {
 	unsigned char *tmpbuf = NULL;
@@ -1099,6 +1150,11 @@ int usb_select_config(struct usb_device *dev)
 	le16_to_cpus(&dev->descriptor.idProduct);
 	le16_to_cpus(&dev->descriptor.bcdDevice);
 
+	/* ignore devices from usb_blocklist */
+	if (usb_device_is_blocked(dev->descriptor.idVendor,
+				  dev->descriptor.idProduct))
+		return -ENODEV;
+
 	/*
 	 * Kingston DT Ultimate 32GB USB 3.0 seems to be extremely sensitive
 	 * about this first Get Descriptor request. If there are any other
diff --git a/doc/usage/environment.rst b/doc/usage/environment.rst
index ebf75fa948..e42702adb2 100644
--- a/doc/usage/environment.rst
+++ b/doc/usage/environment.rst
@@ -366,6 +366,18 @@ tftpwindowsize
     This means the count of blocks we can receive before
     sending ack to server.
 
+usb_blocklist
+    Block USB devices from being bound to an USB device driver. This can be used
+    to ignore devices which causes crashes in u-boot's USB stack or are
+    undesirable for other reasons.
+    The default environment blocks Yubico devices since they emulate USB
+    keyboards. U-boot currently supports only a single USB keyboard device and
+    it is undesirable that a Yubikey is used as keyboard.
+    Devices are matched by idVendor and idProduct. The variable contains a comma
+    separated list of idVendor:idProduct pairs as hexadecimal numbers joined
+    by a colon. '*' functions as a wildcard for idProduct to block all devices
+    with the specified idVendor.
+
 vlan
     When set to a value < 4095 the traffic over
     Ethernet is encapsulated/received over 802.1q
diff --git a/include/env_default.h b/include/env_default.h
index 2ca4a087d3..ba4c7516b4 100644
--- a/include/env_default.h
+++ b/include/env_default.h
@@ -99,6 +99,17 @@ const char default_environment[] = {
 #ifdef CONFIG_SYS_SOC
 	"soc="		CONFIG_SYS_SOC			"\0"
 #endif
+#ifdef CONFIG_USB_HOST
+	"usb_blocklist="
+#ifdef CONFIG_USB_KEYBOARD
+	/* Ignore Yubico devices. Currently only a single USB keyboard device is
+	 * supported and the emulated HID keyboard Yubikeys present is useless
+	 * as keyboard.
+	 */
+	"0x1050:*,"
+#endif
+	"\0"
+#endif
 #ifdef CONFIG_ENV_IMPORT_FDT
 	"env_fdt_path="	CONFIG_ENV_FDT_PATH		"\0"
 #endif

-- 
2.44.0


WARNING: multiple messages have this Message-ID (diff)
From: Janne Grunau <j@jannau.net>
To: Bin Meng <bmeng.cn@gmail.com>, Marek Vasut <marex@denx.de>,
	 Tom Rini <trini@konsulko.com>, Simon Glass <sjg@chromium.org>,
	 Joe Hershberger <joe.hershberger@ni.com>
Cc: u-boot@lists.denx.de, asahi@lists.linux.dev,
	 Janne Grunau <j@jannau.net>
Subject: [PATCH v2 4/6] usb: Add environment based device blocklist
Date: Sun, 17 Mar 2024 12:07:06 +0100	[thread overview]
Message-ID: <20240317-asahi-keyboards-v2-4-d3f4b8384f68@jannau.net> (raw)
In-Reply-To: <20240317-asahi-keyboards-v2-0-d3f4b8384f68@jannau.net>

Add the environment variable "usb_blocklist" to prevent USB devices
listed in it from being used. This allows to ignore devices which
trigger bugs in u-boot's USB stack or are undesirable for other reasons.
Devices emulating keyboards are one example. U-boot currently supports
only one USB keyboard device. Most commonly, people run into this with
Yubikeys, so let's ignore those in the default environment.

Based on previous USB keyboard specific patches for the same purpose.

Link: https://lore.kernel.org/u-boot/7ab604fb-0fec-4f5e-8708-7a3a7e2cb568@denx.de/
Signed-off-by: Janne Grunau <j@jannau.net>
---
 common/usb.c              | 56 +++++++++++++++++++++++++++++++++++++++++++++++
 doc/usage/environment.rst | 12 ++++++++++
 include/env_default.h     | 11 ++++++++++
 3 files changed, 79 insertions(+)

diff --git a/common/usb.c b/common/usb.c
index 836506dcd9..73af5be066 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -1084,6 +1084,57 @@ static int usb_prepare_device(struct usb_device *dev, int addr, bool do_read,
 	return 0;
 }
 
+static int usb_blocklist_parse_error(const char *blocklist, size_t pos)
+{
+	printf("usb_blocklist parse error at char %zu in \"%s\"\n", pos,
+	       blocklist);
+	return 0;
+}
+
+static int usb_device_is_blocked(u16 id_vendor, u16 id_product)
+{
+	ulong vid, pid;
+	char *end;
+	const char *block_str = env_get("usb_blocklist");
+	const char *cur = block_str;
+
+	/* parse "usb_blocklist" strictly */
+	while (cur && cur[0] != '\0') {
+		vid = simple_strtoul(cur, &end, 0);
+		if (cur == end || end[0] != ':')
+			return usb_blocklist_parse_error(block_str,
+							 cur - block_str);
+
+		cur = end + 1;
+		pid = simple_strtoul(cur, &end, 0);
+		if (cur == end && end[0] != '*')
+			return usb_blocklist_parse_error(block_str,
+							 cur - block_str);
+
+		if (end[0] == '*') {
+			/* use out of range idProduct as wildcard indication */
+			pid = U16_MAX + 1;
+			end++;
+		}
+		if (end[0] != ',' && end[0] != '\0')
+			return usb_blocklist_parse_error(block_str,
+							 cur - block_str);
+
+		if (id_vendor == vid && (pid > U16_MAX || id_product == pid)) {
+			printf("Ignoring USB device 0x%x:0x%x\n",id_vendor,
+			      id_product);
+			debug("Ignoring USB device 0x%x:0x%x\n",id_vendor,
+			      id_product);
+			return 1;
+		}
+		if (end[0] == '\0')
+			break;
+		cur = end + 1;
+	}
+
+	return 0;
+}
+
 int usb_select_config(struct usb_device *dev)
 {
 	unsigned char *tmpbuf = NULL;
@@ -1099,6 +1150,11 @@ int usb_select_config(struct usb_device *dev)
 	le16_to_cpus(&dev->descriptor.idProduct);
 	le16_to_cpus(&dev->descriptor.bcdDevice);
 
+	/* ignore devices from usb_blocklist */
+	if (usb_device_is_blocked(dev->descriptor.idVendor,
+				  dev->descriptor.idProduct))
+		return -ENODEV;
+
 	/*
 	 * Kingston DT Ultimate 32GB USB 3.0 seems to be extremely sensitive
 	 * about this first Get Descriptor request. If there are any other
diff --git a/doc/usage/environment.rst b/doc/usage/environment.rst
index ebf75fa948..e42702adb2 100644
--- a/doc/usage/environment.rst
+++ b/doc/usage/environment.rst
@@ -366,6 +366,18 @@ tftpwindowsize
     This means the count of blocks we can receive before
     sending ack to server.
 
+usb_blocklist
+    Block USB devices from being bound to an USB device driver. This can be used
+    to ignore devices which causes crashes in u-boot's USB stack or are
+    undesirable for other reasons.
+    The default environment blocks Yubico devices since they emulate USB
+    keyboards. U-boot currently supports only a single USB keyboard device and
+    it is undesirable that a Yubikey is used as keyboard.
+    Devices are matched by idVendor and idProduct. The variable contains a comma
+    separated list of idVendor:idProduct pairs as hexadecimal numbers joined
+    by a colon. '*' functions as a wildcard for idProduct to block all devices
+    with the specified idVendor.
+
 vlan
     When set to a value < 4095 the traffic over
     Ethernet is encapsulated/received over 802.1q
diff --git a/include/env_default.h b/include/env_default.h
index 2ca4a087d3..ba4c7516b4 100644
--- a/include/env_default.h
+++ b/include/env_default.h
@@ -99,6 +99,17 @@ const char default_environment[] = {
 #ifdef CONFIG_SYS_SOC
 	"soc="		CONFIG_SYS_SOC			"\0"
 #endif
+#ifdef CONFIG_USB_HOST
+	"usb_blocklist="
+#ifdef CONFIG_USB_KEYBOARD
+	/* Ignore Yubico devices. Currently only a single USB keyboard device is
+	 * supported and the emulated HID keyboard Yubikeys present is useless
+	 * as keyboard.
+	 */
+	"0x1050:*,"
+#endif
+	"\0"
+#endif
 #ifdef CONFIG_ENV_IMPORT_FDT
 	"env_fdt_path="	CONFIG_ENV_FDT_PATH		"\0"
 #endif

-- 
2.44.0


  parent reply	other threads:[~2024-03-17 11:07 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-17 11:07 [PATCH v2 0/6] USB keyboard improvements for asahi / desktop systems Janne Grunau via B4 Relay
2024-03-17 11:07 ` Janne Grunau
2024-03-17 11:07 ` [PATCH v2 1/6] usb: xhci: refactor xhci_set_configuration Janne Grunau via B4 Relay
2024-03-17 11:07   ` Janne Grunau
2024-03-17 11:07 ` [PATCH v2 2/6] usb: xhci: Set up endpoints for the first 2 interfaces Janne Grunau via B4 Relay
2024-03-17 11:07   ` Janne Grunau
2024-03-17 11:07 ` [PATCH v2 3/6] usb: xhci: Abort transfers with unallocated rings Janne Grunau via B4 Relay
2024-03-17 11:07   ` Janne Grunau
2024-03-17 16:06   ` Marek Vasut
2024-03-17 11:07 ` Janne Grunau via B4 Relay [this message]
2024-03-17 11:07   ` [PATCH v2 4/6] usb: Add environment based device blocklist Janne Grunau
2024-03-17 11:34   ` Janne Grunau
2024-03-17 16:07     ` Marek Vasut
2024-03-17 16:18   ` Marek Vasut
2024-03-17 18:15     ` Janne Grunau
2024-03-18  5:06       ` Marek Vasut
2024-03-18  7:33         ` Janne Grunau
2024-03-18 14:17           ` Marek Vasut
2024-03-19 21:17             ` Janne Grunau
2024-03-21 23:47               ` Marek Vasut
2024-03-17 21:39   ` E Shattow
2024-03-18  7:39     ` Janne Grunau
2024-03-17 11:07 ` [PATCH v2 5/6] usb: kbd: support Apple Magic Keyboards (2021) Janne Grunau via B4 Relay
2024-03-17 11:07   ` Janne Grunau
2024-03-17 16:20   ` Marek Vasut
2024-03-17 11:07 ` [PATCH v2 6/6] usb: kbd: Add probe quirk for Apple and Keychron keyboards Janne Grunau via B4 Relay
2024-03-17 11:07   ` Janne Grunau
2024-03-17 16:21   ` Marek Vasut
2024-03-17 11:26 ` [PATCH v2 0/6] USB keyboard improvements for asahi / desktop systems Neal Gompa

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240317-asahi-keyboards-v2-4-d3f4b8384f68@jannau.net \
    --to=devnull+j.jannau.net@kernel.org \
    --cc=asahi@lists.linux.dev \
    --cc=bmeng.cn@gmail.com \
    --cc=j@jannau.net \
    --cc=joe.hershberger@ni.com \
    --cc=marex@denx.de \
    --cc=sjg@chromium.org \
    --cc=trini@konsulko.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.