• Jason Gunthorpe's avatar
    vfio: Fully lock struct vfio_group::container · e0e29bdb
    Jason Gunthorpe authored
    This is necessary to avoid various user triggerable races, for instance
    racing SET_CONTAINER/UNSET_CONTAINER:
    
                                      ioctl(VFIO_GROUP_SET_CONTAINER)
    ioctl(VFIO_GROUP_UNSET_CONTAINER)
     vfio_group_unset_container
        int users = atomic_cmpxchg(&group->container_users, 1, 0);
        // users == 1 container_users == 0
        __vfio_group_unset_container(group);
          container = group->container;
                                        vfio_group_set_container()
    	                              if (!atomic_read(&group->container_users))
    				        down_write(&container->group_lock);
    				        group->container = container;
    				        up_write(&container->group_lock);
    
          down_write(&container->group_lock);
          group->container = NULL;
          up_write(&container->group_lock);
          vfio_container_put(container);
          /* woops we lost/leaked the new container  */
    
    This can then go on to NULL pointer deref since container == 0 and
    container_users == 1.
    
    Wrap all touches of container, except those on a performance path with a
    known open device, with the group_rwsem.
    
    The only user of vfio_group_add_container_user() holds the user count for
    a simple operation, change it to just hold the group_lock over the
    operation and delete vfio_group_add_container_user(). Containers now only
    gain a user when a device FD is opened.
    Reviewed-by: default avatarKevin Tian <kevin.tian@intel.com>
    Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
    Tested-by: default avatarNicolin Chen <nicolinc@nvidia.com>
    Tested-by: default avatarMatthew Rosato <mjrosato@linux.ibm.com>
    Link: https://lore.kernel.org/r/4-v2-d035a1842d81+1bf-vfio_group_locking_jgg@nvidia.comSigned-off-by: default avatarAlex Williamson <alex.williamson@redhat.com>
    e0e29bdb
vfio.c 56.2 KB