• Jiri Slaby's avatar
    mmc: sdhci: fix low memory corruption · 62a7f368
    Jiri Slaby authored
    When dma mapping (dma_map_sg) fails in sdhci_pre_dma_transfer, -EINVAL
    is returned. There are 3 callers of sdhci_pre_dma_transfer:
    * sdhci_pre_req and sdhci_adma_table_pre: handle negative return
    * sdhci_prepare_data: handles 0 (error) and "else" (good) only
    
    sdhci_prepare_data is therefore broken. When it receives -EINVAL from
    sdhci_pre_dma_transfer, it assumes 1 sg mapping was mapped. Later,
    this non-existent mapping with address 0 is kmap'ped and written to:
    Corrupted low memory at ffff880000001000 (1000 phys) = 22b7d67df2f6d1cf
    Corrupted low memory at ffff880000001008 (1008 phys) = 63848a5216b7dd95
    Corrupted low memory at ffff880000001010 (1010 phys) = 330eb7ddef39e427
    Corrupted low memory at ffff880000001018 (1018 phys) = 8017ac7295039bda
    Corrupted low memory at ffff880000001020 (1020 phys) = 8ce039eac119074f
    ...
    
    So teach sdhci_prepare_data to understand negative return values from
    sdhci_pre_dma_transfer and disable DMA in that case, as well as for
    zero.
    
    It was introduced in 348487cb (mmc:
    sdhci: use pipeline mmc requests to improve performance). The commit
    seems to be suspicious also by assigning host->sg_count both in
    sdhci_pre_dma_transfer and sdhci_adma_table_pre.
    Signed-off-by: default avatarJiri Slaby <jslaby@suse.cz>
    Cc: stable@vger.kernel.org # 4.0+
    Fixes: 348487cb
    Cc: Ulf Hansson <ulf.hansson@linaro.org>
    Cc: Haibo Chen <haibo.chen@freescale.com>
    Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
    62a7f368
sdhci.c 91 KB