Skip to content
  • Qian Cai's avatar
    iommu: Fix use-after-free in iommu_release_device · 9ac85451
    Qian Cai authored
    In pci_disable_sriov(), i.e.,
    
     # echo 0 > /sys/class/net/enp11s0f1np1/device/sriov_numvfs
    
    iommu_release_device
      iommu_group_remove_device
        arm_smmu_domain_free
          kfree(smmu_domain)
    
    Later,
    
    iommu_release_device
      arm_smmu_release_device
        arm_smmu_detach_dev
          spin_lock_irqsave(&smmu_domain->devices_lock,
    
    would trigger an use-after-free. Fixed it by call
    arm_smmu_release_device() first before iommu_group_remove_device().
    
     BUG: KASAN: use-after-free in __lock_acquire+0x3458/0x4440
      __lock_acquire at kernel/locking/lockdep.c:4250
     Read of size 8 at addr ffff0089df1a6f68 by task bash/3356
    
     CPU: 5 PID: 3356 Comm: bash Not tainted 5.8.0-rc3-next-20200630 #2
     Hardware name: HPE Apollo 70             /C01_APACHE_MB         , BIOS L50_5.13_1.11 06/18/2019
     Call trace:
      dump_backtrace+0x0/0x398
      show_stack+0x14/0x20
      dump_stack+0x140/0x1b8
      print_address_description.isra.12+0x54/0x4a8
      kasan_report+0x134/0x1b8
      __asan_report_load8_noabort+0x2c/0x50
      __lock_acquire+0x3458/0x4440
      lock_acquire+0x204/0xf10
      _raw_spin_lock_irqsave+0xf8/0x180
      arm_smmu_detach_dev+0xd8/0x4a0
      arm_smmu_detach_dev at drivers/iommu/arm-smmu-v3.c:2776
      arm_smmu_release_device+0xb4/0x1c8
      arm_smmu_disable_pasid at drivers/iommu/arm-smmu-v3.c:2754
      (inlined by) arm_smmu_release_device at drivers/iommu/arm-smmu-v3.c:3000
      iommu_release_device+0xc0/0x178
      iommu_release_device at drivers/iommu/iommu.c:302
      iommu_bus_notifier+0x118/0x160
      notifier_call_chain+0xa4/0x128
      __blocking_notifier_call_chain+0x70/0xa8
      blocking_notifier_call_chain+0x14/0x20
      device_del+0x618/0xa00
      pci_remove_bus_device+0x108/0x2d8
      pci_stop_and_remove_bus_device+0x1c/0x28
      pci_iov_remove_virtfn+0x228/0x368
      sriov_disable+0x8c/0x348
      pci_disable_sriov+0x5c/0x70
      mlx5_core_sriov_configure+0xd8/0x260 [mlx5_core]
      sriov_numvfs_store+0x240/0x318
      dev_attr_store+0x38/0x68
      sysfs_kf_write+0xdc/0x128
      kernfs_fop_write+0x23c/0x448
      __vfs_write+0x54/0xe8
      vfs_write+0x124/0x3f0
      ksys_write+0xe8/0x1b8
      __arm64_sys_write+0x68/0x98
      do_el0_svc+0x124/0x220
      el0_sync_handler+0x260/0x408
      el0_sync+0x140/0x180
    
     Allocated by task 3356:
      save_stack+0x24/0x50
      __kasan_kmalloc.isra.13+0xc4/0xe0
      kasan_kmalloc+0xc/0x18
      kmem_cache_alloc_trace+0x1ec/0x318
      arm_smmu_domain_alloc+0x54/0x148
      iommu_group_alloc_default_domain+0xc0/0x440
      iommu_probe_device+0x1c0/0x308
      iort_iommu_configure+0x434/0x518
      acpi_dma_configure+0xf0/0x128
      pci_dma_configure+0x114/0x160
      really_probe+0x124/0x6d8
      driver_probe_device+0xc4/0x180
      __device_attach_driver+0x184/0x1e8
      bus_for_each_drv+0x114/0x1a0
      __device_attach+0x19c/0x2a8
      device_attach+0x10/0x18
      pci_bus_add_device+0x70/0xf8
      pci_iov_add_virtfn+0x7b4/0xb40
      sriov_enable+0x5c8/0xc30
      pci_enable_sriov+0x64/0x80
      mlx5_core_sriov_configure+0x58/0x260 [mlx5_core]
      sriov_numvfs_store+0x1c0/0x318
      dev_attr_store+0x38/0x68
      sysfs_kf_write+0xdc/0x128
      kernfs_fop_write+0x23c/0x448
      __vfs_write+0x54/0xe8
      vfs_write+0x124/0x3f0
      ksys_write+0xe8/0x1b8
      __arm64_sys_write+0x68/0x98
      do_el0_svc+0x124/0x220
      el0_sync_handler+0x260/0x408
      el0_sync+0x140/0x180
    
     Freed by task 3356:
      save_stack+0x24/0x50
      __kasan_slab_free+0x124/0x198
      kasan_slab_free+0x10/0x18
      slab_free_freelist_hook+0x110/0x298
      kfree+0x128/0x668
      arm_smmu_domain_free+0xf4/0x1a0
      iommu_group_release+0xec/0x160
      kobject_put+0xf4/0x238
      kobject_del+0x110/0x190
      kobject_put+0x1e4/0x238
      iommu_group_remove_device+0x394/0x938
      iommu_release_device+0x9c/0x178
      iommu_release_device at drivers/iommu/iommu.c:300
      iommu_bus_notifier+0x118/0x160
      notifier_call_chain+0xa4/0x128
      __blocking_notifier_call_chain+0x70/0xa8
      blocking_notifier_call_chain+0x14/0x20
      device_del+0x618/0xa00
      pci_remove_bus_device+0x108/0x2d8
      pci_stop_and_remove_bus_device+0x1c/0x28
      pci_iov_remove_virtfn+0x228/0x368
      sriov_disable+0x8c/0x348
      pci_disable_sriov+0x5c/0x70
      mlx5_core_sriov_configure+0xd8/0x260 [mlx5_core]
      sriov_numvfs_store+0x240/0x318
      dev_attr_store+0x38/0x68
      sysfs_kf_write+0xdc/0x128
      kernfs_fop_write+0x23c/0x448
      __vfs_write+0x54/0xe8
      vfs_write+0x124/0x3f0
      ksys_write+0xe8/0x1b8
      __arm64_sys_write+0x68/0x98
      do_el0_svc+0x124/0x220
      el0_sync_handler+0x260/0x408
      el0_sync+0x140/0x180
    
     The buggy address belongs to the object at ffff0089df1a6e00
      which belongs to the cache kmalloc-512 of size 512
     The buggy address is located 360 bytes inside of
      512-byte region [ffff0089df1a6e00, ffff0089df1a7000)
     The buggy address belongs to the page:
     page:ffffffe02257c680 refcount:1 mapcount:0 mapping:0000000000000000 index:0xffff0089df1a1400
     flags: 0x7ffff800000200(slab)
     raw: 007ffff800000200 ffffffe02246b8c8 ffffffe02257ff88 ffff000000320680
     raw: ffff0089df1a1400 00000000002a000e 00000001ffffffff ffff0089df1a5001
     page dumped because: kasan: bad access detected
     page->mem_cgroup:ffff0089df1a5001
    
     Memory state around the buggy address:
      ffff0089df1a6e00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
      ffff0089df1a6e80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
     >ffff0089df1a6f00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
                                                               ^
      ffff0089df1a6f80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
      ffff0089df1a7000: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
    
    Fixes: a6a4c7e2
    
     ("iommu: Add probe_device() and release_device() call-backs")
    Signed-off-by: default avatarQian Cai <cai@lca.pw>
    Link: https://lore.kernel.org/r/20200704001003.2303-1-cai@lca.pw
    
    
    Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
    9ac85451