lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250711-usb_authentication-v2-4-2878690e6b6d@ssi.gouv.fr>
Date: Fri, 11 Jul 2025 10:41:25 +0200
From: nicolas.bouchinet@....cyber.gouv.fr
To: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Cc: Luc Bonnafoux <luc.bonnafoux@....gouv.fr>, 
 Alan Stern <stern@...land.harvard.edu>, Kannappan R <r.kannappan@...el.com>, 
 Sabyrzhan Tasbolatov <snovitoll@...il.com>, 
 Krzysztof Kozlowski <krzysztof.kozlowski@...aro.org>, 
 Stefan Eichenberger <stefan.eichenberger@...adex.com>, 
 Thomas Gleixner <tglx@...utronix.de>, Pawel Laszczak <pawell@...ence.com>, 
 Ma Ke <make_ruc2021@....com>, Jeff Johnson <jeff.johnson@....qualcomm.com>, 
 Luc Bonnafoux <luc.bonnafoux@....cyber.gouv.fr>, 
 Nicolas Bouchinet <nicolas.bouchinet@....gouv.fr>, 
 linux-kernel@...r.kernel.org, linux-usb@...r.kernel.org
Subject: [RFC PATCH v2 4/4] usb: core: Add sysctl to configure
 authentication timeouts

From: Nicolas Bouchinet <nicolas.bouchinet@....gouv.fr>

The kernel.usb.authent_engine_register_timeout let a user configure in
seconds the time the kernel will wait for a userspace usb authentication
policy engine to register itself.

The kernel.usb.authent_engine_response_timeout let a user configure in
seconds the time the kernel will wait for the registered userspace usb
authentication policy engine to reply to messages.

Co-developed-by: Luc Bonnafoux <luc.bonnafoux@....gouv.fr>
Signed-off-by: Luc Bonnafoux <luc.bonnafoux@....gouv.fr>
Signed-off-by: Nicolas Bouchinet <nicolas.bouchinet@....gouv.fr>
---
 drivers/usb/core/Makefile          |  1 +
 drivers/usb/core/authent.h         | 14 ++++++++++
 drivers/usb/core/authent_netlink.c | 26 +++++++++++-------
 drivers/usb/core/sysctl.c          | 55 ++++++++++++++++++++++++++++++++++++++
 drivers/usb/core/usb.c             |  8 ++++++
 include/linux/usb.h                |  9 +++++++
 6 files changed, 104 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
index 7ba1a89cf3de7a398889eee1820f2bfbbc4280f5..2ec59764fe5ade682368890b4cd30bb3cdad7746 100644
--- a/drivers/usb/core/Makefile
+++ b/drivers/usb/core/Makefile
@@ -15,6 +15,7 @@ endif
 usbcore-$(CONFIG_OF)		+= of.o
 usbcore-$(CONFIG_USB_PCI)		+= hcd-pci.o
 usbcore-$(CONFIG_ACPI)		+= usb-acpi.o
+usbcore-$(CONFIG_SYSCTL)	+= sysctl.o
 
 ifdef CONFIG_USB_ONBOARD_DEV
 usbcore-y			+= ../misc/onboard_usb_dev_pdevs.o
diff --git a/drivers/usb/core/authent.h b/drivers/usb/core/authent.h
index 2cf6d577131084a97f5c30fadaace1eac7e83c11..7c3264793c6ab5d44fa453b3b70c41882c96ff0d 100644
--- a/drivers/usb/core/authent.h
+++ b/drivers/usb/core/authent.h
@@ -169,6 +169,20 @@ struct usb_authent_error_resp_hd {
 	__u8 errorData;
 } __packed;
 
+extern uint usb_auth_wait_userspace_timeout;
+extern uint usb_auth_wait_response_timeout;
+
+#define DEFAULT_USB_AUTHENT_WAIT_USERSPACE_TIMEOUT 30
+#define DEFAULT_USB_AUTHENT_WAIT_RESPONSE_TIMEOUT 300
+
+#ifdef CONFIG_SYSCTL
+extern int usb_register_sysctl(void);
+extern void usb_unregister_sysctl(void);
+#else
+# define usb_auth_init_sysctl() (0)
+# define usb_auth_exit_sysctl() do { } while (0)
+#endif
+
 #ifdef CONFIG_USB_AUTHENTICATION
 int usb_authenticate_device(struct usb_device *dev);
 #else
diff --git a/drivers/usb/core/authent_netlink.c b/drivers/usb/core/authent_netlink.c
index 9848f219e0e4807563f0f0432a0f1108cd6a0454..731ecadee934ae712735dae5932c0e595720245d 100644
--- a/drivers/usb/core/authent_netlink.c
+++ b/drivers/usb/core/authent_netlink.c
@@ -21,11 +21,15 @@
 #include <uapi/linux/usb/usb_auth_netlink.h>
 #include "authent.h"
 #include "authent_netlink.h"
+#include "authent.h"
 
 #define WAIT_USERSPACE_TIMEOUT 30
 #define WAIT_RESPONSE_TIMEOUT 300
 #define USBAUTH_MAX_RESP_SIZE 128
 
+uint usb_auth_wait_userspace_timeout = DEFAULT_USB_AUTHENT_WAIT_USERSPACE_TIMEOUT;
+uint usb_auth_wait_response_timeout = DEFAULT_USB_AUTHENT_WAIT_RESPONSE_TIMEOUT;
+
 /**
  * struct usb_auth_req - Define an outstanding request between the kernel and userspace
  *
@@ -609,7 +613,8 @@ int usb_policy_engine_check_digest(const u32 route, const u8 *const digests,
 		return -EINVAL;
 	}
 
-	if (!wait_event_timeout(usb_req_wq, pol_eng_pid != 0, HZ * WAIT_USERSPACE_TIMEOUT)) {
+	if (!wait_event_timeout(usb_req_wq, pol_eng_pid != 0,
+				HZ * usb_auth_wait_userspace_timeout)) {
 		pr_err("%s: userspace not available\n", __func__);
 		return -ECOMM;
 	}
@@ -675,7 +680,7 @@ int usb_policy_engine_check_digest(const u32 route, const u8 *const digests,
 
 	if (!wait_event_timeout(usb_req_wq,
 				usb_auth_outstanding_reqs[index].done == 1,
-				HZ * WAIT_RESPONSE_TIMEOUT)) {
+				HZ * usb_auth_wait_response_timeout)) {
 		pr_err("%s: userspace response not available\n", __func__);
 		usb_auth_release_reqs_slot(index);
 		return -ECOMM;
@@ -740,7 +745,8 @@ int usb_policy_engine_check_cert_chain(const u32 route,
 		return -EINVAL;
 	}
 
-	if (!wait_event_timeout(usb_req_wq, pol_eng_pid != 0, HZ * WAIT_USERSPACE_TIMEOUT)) {
+	if (!wait_event_timeout(usb_req_wq, pol_eng_pid != 0,
+				HZ * usb_auth_wait_userspace_timeout)) {
 		pr_err("%s: userspace not available\n", __func__);
 		return -ECOMM;
 	}
@@ -814,7 +820,7 @@ int usb_policy_engine_check_cert_chain(const u32 route,
 
 	if (!wait_event_timeout(usb_req_wq,
 				usb_auth_outstanding_reqs[index].done == 1,
-				HZ * WAIT_RESPONSE_TIMEOUT)) {
+				HZ * usb_auth_wait_response_timeout)) {
 		pr_err("%s: userspace response not available\n", __func__);
 		usb_auth_release_reqs_slot(index);
 		return -ECOMM;
@@ -852,8 +858,8 @@ int usb_policy_engine_generate_challenge(const u32 id, u8 *nonce)
 	struct sk_buff *skb = NULL;
 	u32 index = 0;
 
-	/* Arbitrary 30s wait before giving up */
-	if (!wait_event_timeout(usb_req_wq, pol_eng_pid != 0, HZ * WAIT_USERSPACE_TIMEOUT)) {
+	if (!wait_event_timeout(usb_req_wq, pol_eng_pid != 0,
+				HZ * usb_auth_wait_userspace_timeout)) {
 		pr_err("%s: userspace not available\n", __func__);
 		return -ECOMM;
 	}
@@ -902,7 +908,7 @@ int usb_policy_engine_generate_challenge(const u32 id, u8 *nonce)
 
 	if (!wait_event_timeout(usb_req_wq,
 				usb_auth_outstanding_reqs[index].done == 1,
-				HZ * WAIT_RESPONSE_TIMEOUT)) {
+				HZ * usb_auth_wait_response_timeout)) {
 		pr_err("%s: userspace response not available\n", __func__);
 		usb_auth_release_reqs_slot(index);
 		return -ECOMM;
@@ -953,7 +959,8 @@ int usb_policy_engine_check_challenge(const u32 id,
 		return -EINVAL;
 	}
 
-	if (!wait_event_timeout(usb_req_wq, pol_eng_pid != 0, HZ * WAIT_USERSPACE_TIMEOUT)) {
+	if (!wait_event_timeout(usb_req_wq, pol_eng_pid != 0,
+				HZ * usb_auth_wait_userspace_timeout)) {
 		pr_err("%s: userspace not available\n", __func__);
 		return -ECOMM;
 	}
@@ -1016,9 +1023,10 @@ int usb_policy_engine_check_challenge(const u32 id,
 		       __func__, ret);
 		return -ECOMM;
 	}
+
 	if (!wait_event_timeout(usb_req_wq,
 				usb_auth_outstanding_reqs[index].done == 1,
-				HZ * WAIT_RESPONSE_TIMEOUT)) {
+				HZ * usb_auth_wait_response_timeout)) {
 		pr_err("%s: userspace response not available\n", __func__);
 		usb_auth_release_reqs_slot(index);
 		return -ECOMM;
diff --git a/drivers/usb/core/sysctl.c b/drivers/usb/core/sysctl.c
new file mode 100644
index 0000000000000000000000000000000000000000..a9f917e34e8e914cb60653a56fa90a4790bf6011
--- /dev/null
+++ b/drivers/usb/core/sysctl.c
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SPDX-FileCopyrightText: (C) 2025 ANSSI
+ *
+ * USB Authentication netlink interface
+ *
+ * Author: Luc Bonnafoux <luc.bonnafoux@....gouv.fr>
+ * Author: Nicolas Bouchinet <nicolas.bouchinet@....gouv.fr>
+ *
+ */
+
+#include <linux/sysctl.h>
+#include <linux/usb.h>
+#include "authent.h"
+
+static const unsigned long max_ms = 3600;
+
+static const struct ctl_table usb_sysctls[] = {
+#ifdef	CONFIG_USB_AUTHENTICATION
+	{
+		.procname	= "authent_engine_register_timeout",
+		.data		= &usb_auth_wait_userspace_timeout,
+		.maxlen		= sizeof(usb_auth_wait_userspace_timeout),
+		.mode		= 0644,
+		.proc_handler	= proc_douintvec_minmax,
+		.extra1		= SYSCTL_ZERO,
+		.extra2		= (void*)&max_ms,
+	},
+	{
+		.procname	= "authent_engine_response_timeout",
+		.data		= &usb_auth_wait_response_timeout,
+		.maxlen		= sizeof(usb_auth_wait_response_timeout),
+		.mode		= 0644,
+		.proc_handler	= proc_douintvec_minmax,
+		.extra1		= SYSCTL_ZERO,
+		.extra2		= (void*)&max_ms,
+	},
+#endif
+};
+
+static struct ctl_table_header *usb_sysctl_table;
+
+int __init usb_register_sysctl(void)
+{
+	usb_sysctl_table = register_sysctl("kernel/usb", usb_sysctls);
+	if (!usb_sysctl_table)
+		return -ENOMEM;
+	return 0;
+}
+
+void usb_unregister_sysctl(void)
+{
+	unregister_sysctl_table(usb_sysctl_table);
+	usb_sysctl_table = NULL;
+}
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 421cec9966912ccc62ce163733f46cab05503bd6..0d88a072146dc0ec88314733ae92c835585f722d 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -46,6 +46,7 @@
 #include <linux/dma-mapping.h>
 
 #include "hub.h"
+#include "authent.h"
 #include "authent_netlink.h"
 
 const char *usbcore_name = "usbcore";
@@ -1082,6 +1083,10 @@ static int __init usb_init(void)
 
 	usb_acpi_register();
 
+	retval = usb_register_sysctl();
+	if (retval)
+		goto sysctl_init_failed;
+
 #ifdef CONFIG_USB_AUTHENTICATION
 	retval = usb_auth_init_netlink();
 	if (retval)
@@ -1127,6 +1132,8 @@ static int __init usb_init(void)
 bus_notifier_failed:
 	bus_unregister(&usb_bus_type);
 bus_register_failed:
+	usb_unregister_sysctl();
+sysctl_init_failed:
 	usb_acpi_unregister();
 	usb_debugfs_cleanup();
 out:
@@ -1151,6 +1158,7 @@ static void __exit usb_exit(void)
 	class_unregister(&usbmisc_class);
 	bus_unregister_notifier(&usb_bus_type, &usb_bus_nb);
 	bus_unregister(&usb_bus_type);
+	usb_unregister_sysctl();
 	usb_acpi_unregister();
 	usb_debugfs_cleanup();
 	idr_destroy(&usb_bus_idr);
diff --git a/include/linux/usb.h b/include/linux/usb.h
index e9037c8120b43556f8610f9acb3ad4129e847b98..b616c0fb79be33aace2c052ea3ecd1dd0641a024 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -2062,6 +2062,15 @@ extern void usb_led_activity(enum usb_led_event ev);
 static inline void usb_led_activity(enum usb_led_event ev) {}
 #endif
 
+/* sysctl.c */
+#ifdef CONFIG_SYSCTL
+extern int usb_register_sysctl(void);
+extern void usb_unregister_sysctl(void);
+#else
+static inline int usb_register_sysctl(void) { return 0; }
+static inline void usb_unregister_sysctl(void) { }
+#endif /* CONFIG_SYSCTL */
+
 #endif  /* __KERNEL__ */
 
 #endif

-- 
2.50.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ