linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH] driver core: Stop driver bind on NOTIFY_BAD
@ 2017-06-26 19:35 Alex Williamson
  2017-06-27  7:00 ` Greg KH
  0 siblings, 1 reply; 3+ messages in thread
From: Alex Williamson @ 2017-06-26 19:35 UTC (permalink / raw)
  To: gregkh, linux-kernel; +Cc: linux, kvm

Allow participants in the BUS_NOTIFY_BIND_DRIVER to prevent driver
binding with a NOTIFY_BAD.  An example case where this might be useful
is when we're dealing with IOMMU groups and userspace drivers.  We've
defined that devices within the same IOMMU group are not necessarily
DMA isolated from one another and therefore allowing those devices to
be split between host and user drivers may compromise the kernel.  The
vfio driver currently handles this with a BUG_ON when such a condition
occurs.  A better solution is to prevent the case from occurring,
which this change enables.

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Suggested-by: Russell King <linux@armlinux.org.uk>
---
 drivers/base/dd.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

For due diligence, none of the current notifier blocks registered with
bus_register_notifier() return anything other than { 0, NOTIFY_OK,
NOTIFY_DONE } except for the case of BUS_NOTIFY_ADD_DEVICE, where
NOTIFY_BAD is possible for NULL data in keystone_platform_notifier()
and an errno return is possible from tce_iommu_bus_notifier() and
i2cdev_notifier_call().  device_add() also ignores the call chain
return value, so these three cases are all ineffective at preventing
anything.

If this is acceptable, I'll re-spin https://lkml.org/lkml/2017/6/20/681
dropping the last 3 patches, instead using the patch below, plumbing
the IOMMU group notifier to percolate notifier block returns, and
simply return NOTIFY_BAD from vfio rather than mucking with
driver_override.  Thanks

Alex 

diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 4882f06d12df..32c1d841e8d9 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -265,9 +265,11 @@ static int driver_sysfs_add(struct device *dev)
 {
 	int ret;
 
-	if (dev->bus)
-		blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
-					     BUS_NOTIFY_BIND_DRIVER, dev);
+	if (dev->bus) {
+		if (blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
+				BUS_NOTIFY_BIND_DRIVER, dev) == NOTIFY_BAD)
+			return -EINVAL;
+	}
 
 	ret = sysfs_create_link(&dev->driver->p->kobj, &dev->kobj,
 			  kobject_name(&dev->kobj));

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [RFC PATCH] driver core: Stop driver bind on NOTIFY_BAD
  2017-06-26 19:35 [RFC PATCH] driver core: Stop driver bind on NOTIFY_BAD Alex Williamson
@ 2017-06-27  7:00 ` Greg KH
  2017-06-27 20:18   ` Alex Williamson
  0 siblings, 1 reply; 3+ messages in thread
From: Greg KH @ 2017-06-27  7:00 UTC (permalink / raw)
  To: Alex Williamson; +Cc: linux-kernel, linux, kvm

On Mon, Jun 26, 2017 at 01:35:50PM -0600, Alex Williamson wrote:
> Allow participants in the BUS_NOTIFY_BIND_DRIVER to prevent driver
> binding with a NOTIFY_BAD.  An example case where this might be useful
> is when we're dealing with IOMMU groups and userspace drivers.  We've
> defined that devices within the same IOMMU group are not necessarily
> DMA isolated from one another and therefore allowing those devices to
> be split between host and user drivers may compromise the kernel.  The
> vfio driver currently handles this with a BUG_ON when such a condition
> occurs.  A better solution is to prevent the case from occurring,
> which this change enables.
> 
> Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
> Suggested-by: Russell King <linux@armlinux.org.uk>
> ---
>  drivers/base/dd.c |    8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> For due diligence, none of the current notifier blocks registered with
> bus_register_notifier() return anything other than { 0, NOTIFY_OK,
> NOTIFY_DONE } except for the case of BUS_NOTIFY_ADD_DEVICE, where
> NOTIFY_BAD is possible for NULL data in keystone_platform_notifier()
> and an errno return is possible from tce_iommu_bus_notifier() and
> i2cdev_notifier_call().  device_add() also ignores the call chain
> return value, so these three cases are all ineffective at preventing
> anything.
> 
> If this is acceptable, I'll re-spin https://lkml.org/lkml/2017/6/20/681
> dropping the last 3 patches, instead using the patch below, plumbing
> the IOMMU group notifier to percolate notifier block returns, and
> simply return NOTIFY_BAD from vfio rather than mucking with
> driver_override.  Thanks
> 
> Alex 
> 
> diff --git a/drivers/base/dd.c b/drivers/base/dd.c
> index 4882f06d12df..32c1d841e8d9 100644
> --- a/drivers/base/dd.c
> +++ b/drivers/base/dd.c
> @@ -265,9 +265,11 @@ static int driver_sysfs_add(struct device *dev)
>  {
>  	int ret;
>  
> -	if (dev->bus)
> -		blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
> -					     BUS_NOTIFY_BIND_DRIVER, dev);
> +	if (dev->bus) {
> +		if (blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
> +				BUS_NOTIFY_BIND_DRIVER, dev) == NOTIFY_BAD)
> +			return -EINVAL;
> +	}

Ick, this seems really hacky.  Right now we do not do anything on any of
the bus notifiers, so why start doing it now?

How is this ever being called anyway?  Your driver should have rejected
being bound to the device at all, much earlier in your probe function.

Or are you somehow trying to keep userspace from manually binding the
driver to the device?  If so, why not just disable that functionality
for it (there is a bit somewhere for that...)

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [RFC PATCH] driver core: Stop driver bind on NOTIFY_BAD
  2017-06-27  7:00 ` Greg KH
@ 2017-06-27 20:18   ` Alex Williamson
  0 siblings, 0 replies; 3+ messages in thread
From: Alex Williamson @ 2017-06-27 20:18 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel, linux, kvm

On Tue, 27 Jun 2017 09:00:45 +0200
Greg KH <gregkh@linuxfoundation.org> wrote:

> On Mon, Jun 26, 2017 at 01:35:50PM -0600, Alex Williamson wrote:
> > Allow participants in the BUS_NOTIFY_BIND_DRIVER to prevent driver
> > binding with a NOTIFY_BAD.  An example case where this might be useful
> > is when we're dealing with IOMMU groups and userspace drivers.  We've
> > defined that devices within the same IOMMU group are not necessarily
> > DMA isolated from one another and therefore allowing those devices to
> > be split between host and user drivers may compromise the kernel.  The
> > vfio driver currently handles this with a BUG_ON when such a condition
> > occurs.  A better solution is to prevent the case from occurring,
> > which this change enables.
> > 
> > Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
> > Suggested-by: Russell King <linux@armlinux.org.uk>
> > ---
> >  drivers/base/dd.c |    8 +++++---
> >  1 file changed, 5 insertions(+), 3 deletions(-)
> > 
> > For due diligence, none of the current notifier blocks registered with
> > bus_register_notifier() return anything other than { 0, NOTIFY_OK,
> > NOTIFY_DONE } except for the case of BUS_NOTIFY_ADD_DEVICE, where
> > NOTIFY_BAD is possible for NULL data in keystone_platform_notifier()
> > and an errno return is possible from tce_iommu_bus_notifier() and
> > i2cdev_notifier_call().  device_add() also ignores the call chain
> > return value, so these three cases are all ineffective at preventing
> > anything.
> > 
> > If this is acceptable, I'll re-spin https://lkml.org/lkml/2017/6/20/681
> > dropping the last 3 patches, instead using the patch below, plumbing
> > the IOMMU group notifier to percolate notifier block returns, and
> > simply return NOTIFY_BAD from vfio rather than mucking with
> > driver_override.  Thanks
> > 
> > Alex 
> > 
> > diff --git a/drivers/base/dd.c b/drivers/base/dd.c
> > index 4882f06d12df..32c1d841e8d9 100644
> > --- a/drivers/base/dd.c
> > +++ b/drivers/base/dd.c
> > @@ -265,9 +265,11 @@ static int driver_sysfs_add(struct device *dev)
> >  {
> >  	int ret;
> >  
> > -	if (dev->bus)
> > -		blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
> > -					     BUS_NOTIFY_BIND_DRIVER, dev);
> > +	if (dev->bus) {
> > +		if (blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
> > +				BUS_NOTIFY_BIND_DRIVER, dev) == NOTIFY_BAD)
> > +			return -EINVAL;
> > +	}  
> 
> Ick, this seems really hacky.  Right now we do not do anything on any of
> the bus notifiers, so why start doing it now?
> 
> How is this ever being called anyway?  Your driver should have rejected
> being bound to the device at all, much earlier in your probe function.
> 
> Or are you somehow trying to keep userspace from manually binding the
> driver to the device?  If so, why not just disable that functionality
> for it (there is a bit somewhere for that...)

An example scenario is that we have an IOMMU group with multiple
devices.  We assume that devices within the same IOMMU group are not DMA
isolated from one another and therefore having host-owned and user-owned
devices within the same IOMMU group compromises the host integrity.
Therefore if a device within a group is in use by the user while
another device within the same group is unbound from its vfio driver
and bound to a host driver, what do we do?

The driver model doesn't support us returning an error from an unbind
request, the best we can do would be to block the unbind from the vfio
driver, but that has its own set of issues.  So our hand is forced to
allow the unbind, but then what?

Currently if the device is then bound to a host driver, vfio will
trigger a BUG_ON since we consider the system integrity compromised.
That's not good.  Unless we add some sort of IOMMU group smarts to the
other driver or the driver core, nobody else has visibility to this
issue, ie. the binding driver is any another driver, it's just a
bystander to this situation.  Disabling autoprobe doesn't really solve
anything, tools like libvirt can still put us in this situation
regardless of autoprobe and even if we think an admin user should be
able to shoot themselves in the foot, perhaps we shouldn't make it so
easy and non-obvious for them to do so.

The proposal here is that if we provide a mechanism for a participant
in the bus notifier chain to nak a driver bind, then we can prevent the
compromising scenario, which seems like an improvement from the current
response.  As I note above, we do already have instances where
participants in the notifier chain think they do have voting status and
I don't really see an issue with making that be true in cases where it
can improve the system behavior.  Thanks,

Alex

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2017-06-27 20:18 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-26 19:35 [RFC PATCH] driver core: Stop driver bind on NOTIFY_BAD Alex Williamson
2017-06-27  7:00 ` Greg KH
2017-06-27 20:18   ` Alex Williamson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).