From patchwork Tue Aug 9 09:43:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bastien Nocera X-Patchwork-Id: 12939497 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 365F1C19F2D for ; Tue, 9 Aug 2022 09:43:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237793AbiHIJnY (ORCPT ); Tue, 9 Aug 2022 05:43:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37310 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238495AbiHIJnR (ORCPT ); Tue, 9 Aug 2022 05:43:17 -0400 Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F100B23171; Tue, 9 Aug 2022 02:43:10 -0700 (PDT) Received: (Authenticated sender: hadess@hadess.net) by mail.gandi.net (Postfix) with ESMTPSA id F11A8FF80F; Tue, 9 Aug 2022 09:43:06 +0000 (UTC) From: Bastien Nocera To: linux-usb@vger.kernel.org, bpf@vger.kernel.org Cc: Greg Kroah-Hartman , Alan Stern , Benjamin Tissoires , Peter Hutterer , "Eric W . Biederman" , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Bastien Nocera Subject: [PATCH 2/2] usb: Implement usb_revoke() BPF function Date: Tue, 9 Aug 2022 11:43:00 +0200 Message-Id: <20220809094300.83116-3-hadess@hadess.net> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20220809094300.83116-1-hadess@hadess.net> References: <20220809094300.83116-1-hadess@hadess.net> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org This functionality allows a sufficiently privileged user-space process to upload a BPF programme that will call to usb_revoke_device() as if it were a kernel API. This functionality will be used by logind to revoke access to devices on fast user-switching to start with. logind, and other session management software, does not have access to the file descriptor used by the application so other identifiers are used. Signed-off-by: Bastien Nocera Reported-by: kernel test robot --- drivers/usb/core/usb.c | 51 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 2f71636af6e1..ca394848a51e 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -38,6 +38,8 @@ #include #include #include +#include +#include #include #include @@ -438,6 +440,41 @@ static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env) return 0; } +struct usb_revoke_match { + int busnum, devnum; /* -1 to match all devices */ + int euid; /* -1 to match all users */ +}; + +static int +__usb_revoke(struct usb_device *udev, void *data) +{ + struct usb_revoke_match *match = data; + + if (match->devnum >= 0 && match->busnum >= 0) { + if (match->busnum != udev->bus->busnum || + match->devnum != udev->devnum) { + return 0; + } + } + + usb_revoke_for_euid(udev, match->euid); + return 0; +} + +noinline int +usb_revoke_device(int busnum, int devnum, unsigned int euid) +{ + struct usb_revoke_match match; + + match.busnum = busnum; + match.devnum = devnum; + match.euid = euid; + + usb_for_each_dev(&match, __usb_revoke); + + return 0; +} + #ifdef CONFIG_PM /* USB device Power-Management thunks. @@ -1004,6 +1041,15 @@ static void usb_debugfs_cleanup(void) /* * Init */ +BTF_SET_START(usbdev_kfunc_ids) +BTF_ID(func, usb_revoke_device) +BTF_SET_END(usbdev_kfunc_ids) + +static const struct btf_kfunc_id_set usbdev_kfunc_set = { + .owner = THIS_MODULE, + .check_set = &usbdev_kfunc_ids, +}; + static int __init usb_init(void) { int retval; @@ -1035,9 +1081,14 @@ static int __init usb_init(void) if (retval) goto hub_init_failed; retval = usb_register_device_driver(&usb_generic_driver, THIS_MODULE); + if (retval) + goto register_failed; + retval = register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &usbdev_kfunc_set); if (!retval) goto out; + usb_deregister_device_driver(&usb_generic_driver); +register_failed: usb_hub_cleanup(); hub_init_failed: usb_devio_cleanup();