1. 12 6月, 2021 1 次提交
    • P
      ath9k: Fix kernel NULL pointer dereference during ath_reset_internal() · fb312ac5
      Pali Rohár 提交于
      I got this crash more times during debugging of PCIe controller and crash
      happens somehow at the time when PCIe kernel code started link retraining (as
      part of ASPM code) when at the same time PCIe link went down and ath9k probably
      executed hw reset procedure.
      
      Currently I'm not able to reproduce this issue as it looks like to be
      some race condition between link training, ASPM, link down and reset
      path. And as always, race conditions which depends on more input
      parameters are hard to reproduce as it depends on precise timings.
      
      But it is clear that pointers are zero in this case and should be
      properly filled as same code pattern is used in ath9k_stop() function.
      Anyway I was able to reproduce this crash by manually triggering ath
      reset worker prior putting card up. I created simple patch to export
      reset functionality via debugfs and use it to "simulate" of triggering
      reset.    s proved that NULL-pointer dereference issue is there.
      
      Function ath9k_hw_reset() is dereferencing chan structure pointer, so it
      needs to be non-NULL pointer.
      
      Function ath9k_stop() already contains code which sets ah->curchan to valid
      non-NULL pointer prior calling ath9k_hw_reset() function.
      
      Add same code pattern also into ath_reset_internal() function to prevent
      kernel NULL pointer dereference in ath9k_hw_reset() function.
      
      This change fixes kernel NULL pointer dereference in ath9k_hw_reset() which
      is caused by calling ath9k_hw_reset() from ath_reset_internal() with NULL
      chan structure.
      
          [   45.334305] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000008
          [   45.344417] Mem abort info:
          [   45.347301]   ESR = 0x96000005
          [   45.350448]   EC = 0x25: DABT (current EL), IL = 32 bits
          [   45.356166]   SET = 0, FnV = 0
          [   45.359350]   EA = 0, S1PTW = 0
          [   45.362596] Data abort info:
          [   45.365756]   ISV = 0, ISS = 0x00000005
          [   45.369735]   CM = 0, WnR = 0
          [   45.372814] user pgtable: 4k pages, 39-bit VAs, pgdp=000000000685d000
          [   45.379663] [0000000000000008] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000
          [   45.388856] Internal error: Oops: 96000005 [#1] SMP
          [   45.393897] Modules linked in: ath9k ath9k_common ath9k_hw
          [   45.399574] CPU: 1 PID: 309 Comm: kworker/u4:2 Not tainted 5.12.0-rc2-dirty #785
          [   45.414746] Workqueue: phy0 ath_reset_work [ath9k]
          [   45.419713] pstate: 40000005 (nZcv daif -PAN -UAO -TCO BTYPE=--)
          [   45.425910] pc : ath9k_hw_reset+0xc4/0x1c48 [ath9k_hw]
          [   45.431234] lr : ath9k_hw_reset+0xc0/0x1c48 [ath9k_hw]
          [   45.436548] sp : ffffffc0118dbca0
          [   45.439961] x29: ffffffc0118dbca0 x28: 0000000000000000
          [   45.445442] x27: ffffff800dee4080 x26: 0000000000000000
          [   45.450923] x25: ffffff800df9b9d8 x24: 0000000000000000
          [   45.456404] x23: ffffffc0115f6000 x22: ffffffc008d0d408
          [   45.461885] x21: ffffff800dee5080 x20: ffffff800df9b9d8
          [   45.467366] x19: 0000000000000000 x18: 0000000000000000
          [   45.472846] x17: 0000000000000000 x16: 0000000000000000
          [   45.478326] x15: 0000000000000010 x14: ffffffffffffffff
          [   45.483807] x13: ffffffc0918db94f x12: ffffffc011498720
          [   45.489289] x11: 0000000000000003 x10: ffffffc0114806e0
          [   45.494770] x9 : ffffffc01014b2ec x8 : 0000000000017fe8
          [   45.500251] x7 : c0000000ffffefff x6 : 0000000000000001
          [   45.505733] x5 : 0000000000000000 x4 : 0000000000000000
          [   45.511213] x3 : 0000000000000000 x2 : ffffff801fece870
          [   45.516693] x1 : ffffffc00eded000 x0 : 000000000000003f
          [   45.522174] Call trace:
          [   45.524695]  ath9k_hw_reset+0xc4/0x1c48 [ath9k_hw]
          [   45.529653]  ath_reset_internal+0x1a8/0x2b8 [ath9k]
          [   45.534696]  ath_reset_work+0x2c/0x40 [ath9k]
          [   45.539198]  process_one_work+0x210/0x480
          [   45.543339]  worker_thread+0x5c/0x510
          [   45.547115]  kthread+0x12c/0x130
          [   45.550445]  ret_from_fork+0x10/0x1c
          [   45.554138] Code: 910922c2 9117e021 95ff0398 b4000294 (b9400a61)
          [   45.560430] ---[ end trace 566410ba90b50e8b ]---
          [   45.565193] Kernel panic - not syncing: Oops: Fatal exception in interrupt
          [   45.572282] SMP: stopping secondary CPUs
          [   45.576331] Kernel Offset: disabled
          [   45.579924] CPU features: 0x00040002,0000200c
          [   45.584416] Memory Limit: none
          [   45.587564] Rebooting in 3 seconds..
      Signed-off-by: NPali Rohár <pali@kernel.org>
      Cc: stable@vger.kernel.org
      Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
      Link: https://lore.kernel.org/r/20210402122653.24014-1-pali@kernel.org
      fb312ac5
  2. 30 5月, 2021 1 次提交
  3. 24 5月, 2021 1 次提交
  4. 14 5月, 2021 2 次提交
  5. 12 5月, 2021 8 次提交
  6. 22 4月, 2021 5 次提交
  7. 19 4月, 2021 2 次提交
  8. 18 4月, 2021 2 次提交
  9. 14 4月, 2021 1 次提交
    • M
      of: net: pass the dst buffer to of_get_mac_address() · 83216e39
      Michael Walle 提交于
      of_get_mac_address() returns a "const void*" pointer to a MAC address.
      Lately, support to fetch the MAC address by an NVMEM provider was added.
      But this will only work with platform devices. It will not work with
      PCI devices (e.g. of an integrated root complex) and esp. not with DSA
      ports.
      
      There is an of_* variant of the nvmem binding which works without
      devices. The returned data of a nvmem_cell_read() has to be freed after
      use. On the other hand the return of_get_mac_address() points to some
      static data without a lifetime. The trick for now, was to allocate a
      device resource managed buffer which is then returned. This will only
      work if we have an actual device.
      
      Change it, so that the caller of of_get_mac_address() has to supply a
      buffer where the MAC address is written to. Unfortunately, this will
      touch all drivers which use the of_get_mac_address().
      
      Usually the code looks like:
      
        const char *addr;
        addr = of_get_mac_address(np);
        if (!IS_ERR(addr))
          ether_addr_copy(ndev->dev_addr, addr);
      
      This can then be simply rewritten as:
      
        of_get_mac_address(np, ndev->dev_addr);
      
      Sometimes is_valid_ether_addr() is used to test the MAC address.
      of_get_mac_address() already makes sure, it just returns a valid MAC
      address. Thus we can just test its return code. But we have to be
      careful if there are still other sources for the MAC address before the
      of_get_mac_address(). In this case we have to keep the
      is_valid_ether_addr() call.
      
      The following coccinelle patch was used to convert common cases to the
      new style. Afterwards, I've manually gone over the drivers and fixed the
      return code variable: either used a new one or if one was already
      available use that. Mansour Moufid, thanks for that coccinelle patch!
      
      <spml>
      @a@
      identifier x;
      expression y, z;
      @@
      - x = of_get_mac_address(y);
      + x = of_get_mac_address(y, z);
        <...
      - ether_addr_copy(z, x);
        ...>
      
      @@
      identifier a.x;
      @@
      - if (<+... x ...+>) {}
      
      @@
      identifier a.x;
      @@
        if (<+... x ...+>) {
            ...
        }
      - else {}
      
      @@
      identifier a.x;
      expression e;
      @@
      - if (<+... x ...+>@e)
      -     {}
      - else
      + if (!(e))
            {...}
      
      @@
      expression x, y, z;
      @@
      - x = of_get_mac_address(y, z);
      + of_get_mac_address(y, z);
        ... when != x
      </spml>
      
      All drivers, except drivers/net/ethernet/aeroflex/greth.c, were
      compile-time tested.
      Suggested-by: NAndrew Lunn <andrew@lunn.ch>
      Signed-off-by: NMichael Walle <michael@walle.cc>
      Reviewed-by: NAndrew Lunn <andrew@lunn.ch>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      83216e39
  10. 18 3月, 2021 1 次提交
  11. 17 3月, 2021 1 次提交
  12. 09 3月, 2021 3 次提交
  13. 06 3月, 2021 1 次提交
  14. 24 2月, 2021 6 次提交
  15. 22 2月, 2021 2 次提交
    • S
      Revert "ath9k: fix ath_tx_process_buffer() potential null ptr dereference" · 14ebaeef
      Shuah Khan 提交于
      This reverts commit a56c14bb.
      
      ath_tx_process_buffer() doesn't dereference or check sta and passes it
      to ath_tx_complete_aggr() and ath_tx_complete_buf().
      
      ath_tx_complete_aggr() checks the pointer before use. No problem here.
      
      ath_tx_complete_buf() doesn't check or dereference sta and passes it on
      to ath_tx_complete(). ath_tx_complete() doesn't check or dereference sta,
      but assigns it to tx_info->status.status_driver_data[0]
      
      ath_tx_complete_buf() is called from ath_tx_complete_aggr() passing
      null ieee80211_sta pointer.
      
      There is a potential for dereference later on, if and when the
      tx_info->status.status_driver_data[0]is referenced. In addition, the
      rcu read lock might be released before referencing the contents.
      
      ath_tx_complete_buf() should be fixed to check sta perhaps? Worth
      looking into.
      
      Reverting this patch because it doesn't solve the problem and introduces
      memory leak by skipping buffer completion if the pointer (sta) is NULL.
      
      Fixes: a56c14bb ("ath9k: fix ath_tx_process_buffer() potential null ptr dereference")
      Signed-off-by: NShuah Khan <skhan@linuxfoundation.org>
      Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
      Link: https://lore.kernel.org/r/20210217211801.22540-1-skhan@linuxfoundation.org
      14ebaeef
    • K
      ath11k: print hardware name and version during initialisation · 6b7abacb
      Kalle Valo 提交于
      This way it's easy for the user to find what device is actually installed. This
      also helps reporting bugs.
      
      Screenshot:
      
      [  459.988812] ath11k_pci 0000:06:00.0: BAR 0: assigned [mem 0xdb000000-0xdbffffff 64bit]
      [  459.988867] ath11k_pci 0000:06:00.0: enabling device (0000 -> 0002)
      [  459.997048] ath11k_pci 0000:06:00.0: qca6390 hw2.0
      [  460.058093] mhi mhi0: Requested to power ON
      [  460.059741] mhi mhi0: Power on setup success
      [  460.476924] ath11k_pci 0000:06:00.0: chip_id 0x0 chip_family 0xb board_id 0xff soc_id 0xffffffff
      [  460.477032] ath11k_pci 0000:06:00.0: fw_version 0x101c06cc fw_build_timestamp 2020-06-24 19:50 fw_build_id
      
      Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
      Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
      Link: https://lore.kernel.org/r/1613589400-18891-1-git-send-email-kvalo@codeaurora.org
      6b7abacb
  16. 18 2月, 2021 3 次提交