From 03ac0570642b15d46f4a8349adcb2f0ec94b925e Mon Sep 17 00:00:00 2001 From: "Huawei Technologies Co., Ltd" Date: Mon, 8 Feb 2021 17:14:21 +0800 Subject: [PATCH] sd: sdhci: assert data_count is within fifo_buffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix CVE-2020-17380 While doing multi block SDMA, transfer block size may exceed the 's->fifo_buffer[s->buf_maxsz]' size. It may leave the current element pointer 's->data_count' pointing out of bounds. Leading the subsequent DMA r/w operation to OOB access issue. Assert that 's->data_count' is within fifo_buffer. -> https://ruhr-uni-bochum.sciebo.de/s/NNWP2GfwzYKeKwE?path=%2Fsdhci_oob_write1 ==1459837==ERROR: AddressSanitizer: heap-buffer-overflow WRITE of size 54722048 at 0x61500001e280 thread T3 #0 __interceptor_memcpy (/lib64/libasan.so.6+0x3a71d) #1 flatview_read_continue ../exec.c:3245 #2 flatview_read ../exec.c:3278 #3 address_space_read_full ../exec.c:3291 #4 address_space_rw ../exec.c:3319 #5 dma_memory_rw_relaxed ../include/sysemu/dma.h:87 #6 dma_memory_rw ../include/sysemu/dma.h:110 #7 dma_memory_read ../include/sysemu/dma.h:116 #8 sdhci_sdma_transfer_multi_blocks ../hw/sd/sdhci.c:629 #9 sdhci_write ../hw/sd/sdhci.c:1097 #10 memory_region_write_accessor ../softmmu/memory.c:483 ... Reported-by: Ruhr-University Suggested-by: Philippe Mathieu-Daudé Signed-off-by: Prasad J Pandit patch link: https://lists.nongnu.org/archive/html/qemu-devel/2020-09/msg01175.html Signed-off-by: Jiajie Li --- ...ert-data_count-is-within-fifo_buffer.patch | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 sd-sdhci-assert-data_count-is-within-fifo_buffer.patch diff --git a/sd-sdhci-assert-data_count-is-within-fifo_buffer.patch b/sd-sdhci-assert-data_count-is-within-fifo_buffer.patch new file mode 100644 index 0000000..e38bfaa --- /dev/null +++ b/sd-sdhci-assert-data_count-is-within-fifo_buffer.patch @@ -0,0 +1,65 @@ +From e8d2655821caa2b8efce429c0036a93342b8383d Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Mon, 8 Feb 2021 17:14:21 +0800 +Subject: [PATCH] sd: sdhci: assert data_count is within fifo_buffer +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fix CVE-2020-17380 + +While doing multi block SDMA, transfer block size may exceed +the 's->fifo_buffer[s->buf_maxsz]' size. It may leave the +current element pointer 's->data_count' pointing out of bounds. +Leading the subsequent DMA r/w operation to OOB access issue. +Assert that 's->data_count' is within fifo_buffer. + + -> https://ruhr-uni-bochum.sciebo.de/s/NNWP2GfwzYKeKwE?path=%2Fsdhci_oob_write1 + ==1459837==ERROR: AddressSanitizer: heap-buffer-overflow + WRITE of size 54722048 at 0x61500001e280 thread T3 + #0 __interceptor_memcpy (/lib64/libasan.so.6+0x3a71d) + #1 flatview_read_continue ../exec.c:3245 + #2 flatview_read ../exec.c:3278 + #3 address_space_read_full ../exec.c:3291 + #4 address_space_rw ../exec.c:3319 + #5 dma_memory_rw_relaxed ../include/sysemu/dma.h:87 + #6 dma_memory_rw ../include/sysemu/dma.h:110 + #7 dma_memory_read ../include/sysemu/dma.h:116 + #8 sdhci_sdma_transfer_multi_blocks ../hw/sd/sdhci.c:629 + #9 sdhci_write ../hw/sd/sdhci.c:1097 + #10 memory_region_write_accessor ../softmmu/memory.c:483 + ... + +Reported-by: Ruhr-University +Suggested-by: Philippe Mathieu-Daudé +Signed-off-by: Prasad J Pandit + +patch link: https://lists.nongnu.org/archive/html/qemu-devel/2020-09/msg01175.html +Signed-off-by: Jiajie Li +--- + hw/sd/sdhci.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c +index 7b80b1d93f..e51573fe3c 100644 +--- a/hw/sd/sdhci.c ++++ b/hw/sd/sdhci.c +@@ -613,6 +613,7 @@ static void sdhci_sdma_transfer_multi_blocks(SDHCIState *s) + s->blkcnt--; + } + } ++ assert(s->data_count <= s->buf_maxsz && s->data_count > begin); + dma_memory_write(s->dma_as, s->sdmasysad, + &s->fifo_buffer[begin], s->data_count - begin); + s->sdmasysad += s->data_count - begin; +@@ -635,6 +636,7 @@ static void sdhci_sdma_transfer_multi_blocks(SDHCIState *s) + s->data_count = block_size; + boundary_count -= block_size - begin; + } ++ assert(s->data_count <= s->buf_maxsz && s->data_count > begin); + dma_memory_read(s->dma_as, s->sdmasysad, + &s->fifo_buffer[begin], s->data_count - begin); + s->sdmasysad += s->data_count - begin; +-- +2.27.0 +