Skip to content
  • Mika Westerberg's avatar
    thunderbolt: Do not enumerate more ports from DROM than the controller has · 1cd65d17
    Mika Westerberg authored
    
    
    Some Alpine Ridge LP DROMs (there might be others) erroneusly list more
    ports than the controller actually has. Most probably because DROM of
    the full Dual/Single port Thunderbolt controller was reused for LP
    version. The current DROM parser does not check the upper bound thus it
    leads to crash when sw->ports[] is accessed over bounds:
    
     BUG: unable to handle kernel NULL pointer dereference at 00000000000002ec
     IP: tb_drom_read+0x383/0x890 [thunderbolt]
     PGD 0
     P4D 0
     Oops: 0000 [#1] SMP
     CPU: 3 PID: 12248 Comm: systemd-udevd Not tainted 4.13.0-rc1-next-20170719 #1
     Hardware name: LENOVO 20HF000YGE/20HF000YGE, BIOS N1WET32W (1.11 ) 05/23/2017
     task: ffff8a293e4bcd80 task.stack: ffffa698027a8000
     RIP: 0010:tb_drom_read+0x383/0x890 [thunderbolt]
     RSP: 0018:ffffa698027ab990 EFLAGS: 00010246
     RAX: 0000000000000000 RBX: ffff8a2940af7800 RCX: 0000000000000000
     RDX: ffff8a2940ebb400 RSI: 0000000000000000 RDI: ffffa698027ab9a0
     RBP: ffffa698027ab9d0 R08: 0000000000000001 R09: 0000000000000002
     R10: ffff8a2940ebb5b0 R11: 0000000000000000 R12: ffff8a293bfa968c
     R13: 000000000000002c R14: 0000000000000056 R15: 0000000000000056
     FS:  00007f0a945a38c0(0000) GS:ffff8a2961580000(0000) knlGS:0000000000000000
     CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
     CR2: 00000000000002ec CR3: 000000043e785000 CR4: 00000000003606e0
     DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
     DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
     Call Trace:
      tb_switch_add+0x9d/0x730 [thunderbolt]
      ? tb_switch_alloc+0x3cd/0x4d0 [thunderbolt]
      icm_start+0x5a/0xa0 [thunderbolt]
      tb_domain_add+0xc3/0xf0 [thunderbolt]
      nhi_probe+0x19e/0x310 [thunderbolt]
      local_pci_probe+0x42/0xa0
      pci_device_probe+0x18d/0x1a0
      driver_probe_device+0x2ff/0x450
      __driver_attach+0xa4/0xe0
      ? driver_probe_device+0x450/0x450
      bus_for_each_dev+0x6e/0xb0
      driver_attach+0x1e/0x20
      bus_add_driver+0x1d0/0x270
      ? 0xffffffffc0bbb000
      driver_register+0x60/0xe0
      ? 0xffffffffc0bbb000
      __pci_register_driver+0x4c/0x50
      nhi_init+0x28/0x1000 [thunderbolt]
      do_one_initcall+0x50/0x190
      ? __vunmap+0x81/0xb0
      ? _cond_resched+0x1a/0x50
      ? kmem_cache_alloc_trace+0x15f/0x1c0
      ? do_init_module+0x27/0x1e9
      do_init_module+0x5f/0x1e9
      load_module+0x24e7/0x2a60
      ? vfs_read+0x115/0x130
      SYSC_finit_module+0xfc/0x120
      ? SYSC_finit_module+0xfc/0x120
      SyS_finit_module+0xe/0x10
      do_syscall_64+0x67/0x170
      entry_SYSCALL64_slow_path+0x25/0x25
    
    Fix this by making sure we only enumerate DROM port entries the hardware
    actually has.
    
    Reported-by: default avatarChristian Kellner <ckellner@redhat.com>
    Signed-off-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
    Reviewed-by: default avatarLukas Wunner <lukas@wunner.de>
    Tested-by: default avatarChristian Kellner <ckellner@redhat.com>
    Cc: stable <stable@vger.kernel.org>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    1cd65d17