All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Eric W. Biederman" <ebiederm@xmission.com>
To: Bastien Nocera <hadess@hadess.net>
Cc: linux-usb@vger.kernel.org, bpf@vger.kernel.org,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Alan Stern <stern@rowland.harvard.edu>,
	Benjamin Tissoires <benjamin.tissoires@redhat.com>,
	Peter Hutterer <peter.hutterer@who-t.net>,
	Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Andrii Nakryiko <andrii@kernel.org>
Subject: Re: [PATCH 2/2] usb: Implement usb_revoke() BPF function
Date: Tue, 09 Aug 2022 12:22:19 -0500	[thread overview]
Message-ID: <87bkst2uyc.fsf@email.froward.int.ebiederm.org> (raw)
In-Reply-To: <20220809094300.83116-3-hadess@hadess.net> (Bastien Nocera's message of "Tue, 9 Aug 2022 11:43:00 +0200")

Bastien Nocera <hadess@hadess.net> writes:

> 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.

Revoking access to hardware devices when switching users is entirely
reasonable.

I really think a system call or possibly and ioctl would be more
appropriate than having to load a bpf program to perform the work of a
system call.

Making it so that logind can't run in any kind of container seems like a
very unfortunate design choice.

The tty subsystem has something like this with the vhangup system
call, and the bsd have revoke(2).  So there is definitely precedent for
doing something like this.

I suspect what you want to pass is an O_PATH file descriptor to the
appropriate device node.   That should allow races to be eliminated,
or at the very least seriously reduced.

Eric



>
> Signed-off-by: Bastien Nocera <hadess@hadess.net>
> ---
>  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 <linux/workqueue.h>
>  #include <linux/debugfs.h>
>  #include <linux/usb/of.h>
> +#include <linux/btf.h>
> +#include <linux/btf_ids.h>
>  
>  #include <asm/io.h>
>  #include <linux/scatterlist.h>
> @@ -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();

  parent reply	other threads:[~2022-08-09 17:22 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-09  9:42 [PATCH 0/2] USB: core: add a way to revoke access to open USB devices Bastien Nocera
2022-08-09  9:42 ` [PATCH 1/2] " Bastien Nocera
2022-08-09 10:32   ` Greg Kroah-Hartman
2022-08-09 11:15     ` Bastien Nocera
2022-08-09 11:30       ` Greg Kroah-Hartman
2022-08-09 11:53         ` Bastien Nocera
2022-08-09 10:35   ` Greg Kroah-Hartman
2022-08-09 11:18     ` Bastien Nocera
2022-08-09 12:52       ` Greg Kroah-Hartman
2022-08-09 13:27         ` Bastien Nocera
2022-08-09 16:31           ` Greg Kroah-Hartman
2022-08-09 17:16             ` Bastien Nocera
2022-08-09 19:43           ` Alan Stern
2022-08-09 16:46   ` Eric W. Biederman
2022-08-09 17:08     ` Bastien Nocera
2022-08-10 17:18   ` kernel test robot
2022-08-10 17:28   ` kernel test robot
2022-08-09  9:43 ` [PATCH 2/2] usb: Implement usb_revoke() BPF function Bastien Nocera
2022-08-09 10:38   ` Greg Kroah-Hartman
2022-08-09 11:18     ` Bastien Nocera
2022-08-09 12:49       ` Greg Kroah-Hartman
2022-08-09 13:27         ` Bastien Nocera
2022-08-09 14:31     ` Bastien Nocera
2022-08-09 16:33       ` Greg Kroah-Hartman
2022-08-09 17:27         ` Bastien Nocera
2022-08-18 15:08           ` Greg Kroah-Hartman
2022-08-30 14:44             ` Bastien Nocera
2022-08-30 15:10               ` Greg Kroah-Hartman
2022-08-30 16:28                 ` Bastien Nocera
2022-08-09 17:22   ` Eric W. Biederman [this message]
2022-08-10 17:59   ` kernel test robot
2022-10-26 15:00   ` Bastien Nocera
2022-10-26 15:22     ` Greg Kroah-Hartman
2022-08-09 10:31 ` [PATCH 0/2] USB: core: add a way to revoke access to open USB devices Greg Kroah-Hartman
2022-08-09 11:15   ` Bastien Nocera
2022-08-09 11:29     ` Greg Kroah-Hartman
2022-08-09 17:25 ` Eric W. Biederman

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=87bkst2uyc.fsf@email.froward.int.ebiederm.org \
    --to=ebiederm@xmission.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=benjamin.tissoires@redhat.com \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=hadess@hadess.net \
    --cc=linux-usb@vger.kernel.org \
    --cc=peter.hutterer@who-t.net \
    --cc=stern@rowland.harvard.edu \
    /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.