1
0
Fork 0

Change allocation of ccw_io_region so that the usercopy hardening

code can figure out that everything is fine.
 -----BEGIN PGP SIGNATURE-----
 
 iQJGBAABCAAwFiEEw9DWbcNiT/aowBjO3s9rk8bwL68FAluyBzQSHGNvaHVja0By
 ZWRoYXQuY29tAAoJEN7Pa5PG8C+vf7EP/RTHbLKZ3mhFiKoUwpZLxVFGo2J3aa5A
 VgDoEn6eXXLgS+MEpDW36rA58iE0Jw+vk7AfRx4+5WGFd9irJdNEb/0LaJOc/Trp
 6Bhrj7RC5AL2C8TuJo+15WQ5dGLct6O1Gbl9qfGRFS96OhId8ejsAm3LhVTBmaR6
 Bn/8ziWWsD+oFtQ73veLz+6NEFQqx4r4pXA8cQS1paTWEyc4VfPK1X2hGbChY2IC
 offwFAmx5ikSmCM6pVw/ANskhMvp1ZQJNq2IxNtk/pT3ACEHu0cZ/TUjFZEHB5HX
 i/pV7Y165tBCfckcp4hKCicYt5j+JiZ3BWiMtGp0xm0Qe0b7taiLe5mkSqfVSdum
 imqIzFzWbGQGb7G5dL2KNL7R1qNHY9+Rv43wx6OstX35zPheDmMqB0EogO2iddhL
 P1Wftu+7wEubi35qHg3TnKzkB/tCakl5XEjyVyfQm2dKPs3vUFEMGaZDhm4fauh/
 vjjOdpoUckg3pwOJZFYt3Ri74OtsXUUxwCuDrvq6CBJck9ONyaduneEcxLLGe74k
 7B4Op8DcOhhoAG/G5wWA4mb7wGbaqa4VsuPHRMPD0HwoTW113fq1e/lwuHnRqDdC
 0yEW2ZfdMXAXVDkD4oqiNTBtmT3PuWKacMnWAk/W9H3KHcSqZ71TMnuF66dpA2zR
 /zZf9mKdD0SR
 =s+Lx
 -----END PGP SIGNATURE-----

Merge tag 'vfio-ccw-20181001' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/vfio-ccw into fixes

Pull vfio-ccw from Cornelia Huck with the following changes:

 - Change allocation of ccw_io_region so that the usercopy hardening
   code can figure out that everything is fine.
zero-colors
Martin Schwidefsky 2018-10-01 16:07:42 +02:00
commit c458dda3d0
4 changed files with 29 additions and 7 deletions

View File

@ -22,6 +22,7 @@
#include "vfio_ccw_private.h"
struct workqueue_struct *vfio_ccw_work_q;
struct kmem_cache *vfio_ccw_io_region;
/*
* Helpers
@ -79,7 +80,7 @@ static void vfio_ccw_sch_io_todo(struct work_struct *work)
cp_update_scsw(&private->cp, &irb->scsw);
cp_free(&private->cp);
}
memcpy(private->io_region.irb_area, irb, sizeof(*irb));
memcpy(private->io_region->irb_area, irb, sizeof(*irb));
if (private->io_trigger)
eventfd_signal(private->io_trigger, 1);
@ -114,6 +115,14 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)
private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA);
if (!private)
return -ENOMEM;
private->io_region = kmem_cache_zalloc(vfio_ccw_io_region,
GFP_KERNEL | GFP_DMA);
if (!private->io_region) {
kfree(private);
return -ENOMEM;
}
private->sch = sch;
dev_set_drvdata(&sch->dev, private);
@ -139,6 +148,7 @@ out_disable:
cio_disable_subchannel(sch);
out_free:
dev_set_drvdata(&sch->dev, NULL);
kmem_cache_free(vfio_ccw_io_region, private->io_region);
kfree(private);
return ret;
}
@ -153,6 +163,7 @@ static int vfio_ccw_sch_remove(struct subchannel *sch)
dev_set_drvdata(&sch->dev, NULL);
kmem_cache_free(vfio_ccw_io_region, private->io_region);
kfree(private);
return 0;
@ -232,10 +243,20 @@ static int __init vfio_ccw_sch_init(void)
if (!vfio_ccw_work_q)
return -ENOMEM;
vfio_ccw_io_region = kmem_cache_create_usercopy("vfio_ccw_io_region",
sizeof(struct ccw_io_region), 0,
SLAB_ACCOUNT, 0,
sizeof(struct ccw_io_region), NULL);
if (!vfio_ccw_io_region) {
destroy_workqueue(vfio_ccw_work_q);
return -ENOMEM;
}
isc_register(VFIO_CCW_ISC);
ret = css_driver_register(&vfio_ccw_sch_driver);
if (ret) {
isc_unregister(VFIO_CCW_ISC);
kmem_cache_destroy(vfio_ccw_io_region);
destroy_workqueue(vfio_ccw_work_q);
}
@ -246,6 +267,7 @@ static void __exit vfio_ccw_sch_exit(void)
{
css_driver_unregister(&vfio_ccw_sch_driver);
isc_unregister(VFIO_CCW_ISC);
kmem_cache_destroy(vfio_ccw_io_region);
destroy_workqueue(vfio_ccw_work_q);
}
module_init(vfio_ccw_sch_init);

View File

@ -93,13 +93,13 @@ static void fsm_io_error(struct vfio_ccw_private *private,
enum vfio_ccw_event event)
{
pr_err("vfio-ccw: FSM: I/O request from state:%d\n", private->state);
private->io_region.ret_code = -EIO;
private->io_region->ret_code = -EIO;
}
static void fsm_io_busy(struct vfio_ccw_private *private,
enum vfio_ccw_event event)
{
private->io_region.ret_code = -EBUSY;
private->io_region->ret_code = -EBUSY;
}
static void fsm_disabled_irq(struct vfio_ccw_private *private,
@ -126,7 +126,7 @@ static void fsm_io_request(struct vfio_ccw_private *private,
{
union orb *orb;
union scsw *scsw = &private->scsw;
struct ccw_io_region *io_region = &private->io_region;
struct ccw_io_region *io_region = private->io_region;
struct mdev_device *mdev = private->mdev;
char *errstr = "request";

View File

@ -174,7 +174,7 @@ static ssize_t vfio_ccw_mdev_read(struct mdev_device *mdev,
return -EINVAL;
private = dev_get_drvdata(mdev_parent_dev(mdev));
region = &private->io_region;
region = private->io_region;
if (copy_to_user(buf, (void *)region + *ppos, count))
return -EFAULT;
@ -196,7 +196,7 @@ static ssize_t vfio_ccw_mdev_write(struct mdev_device *mdev,
if (private->state != VFIO_CCW_STATE_IDLE)
return -EACCES;
region = &private->io_region;
region = private->io_region;
if (copy_from_user((void *)region + *ppos, buf, count))
return -EFAULT;

View File

@ -41,7 +41,7 @@ struct vfio_ccw_private {
atomic_t avail;
struct mdev_device *mdev;
struct notifier_block nb;
struct ccw_io_region io_region;
struct ccw_io_region *io_region;
struct channel_program cp;
struct irb irb;