openeuler !302!305 e1000-fail-early-for-evil-descriptor.patch e1000-fix-tx-re-entrancy-problem.patch hw-sd-sdcard-Restrict-Class-6-commands-to-SCSD-cards.patch hw-sd-sdcard-Simplify-realize-a-bit.patch hw-sd-sdcard-Do-not-allow-invalid-SD-card-sizes.patch hw-sd-sdcard-Update-coding-style-to-make-checkpatch..patch hw-sd-sdcard-Do-not-switch-to-ReceivingData-if-addre.patch scsi-qemu-pr-helper-Fix-out-of-bounds-access-to-trnp.patch curses-Fixes-curses-compiling-errors.patch net-dump.c-Suppress-spurious-compiler-warning.patch tests-Replace-deprecated-ASN1-code.patch
132 lines
4.4 KiB
Diff
132 lines
4.4 KiB
Diff
From 8d920e44e5bd5e719aca03887e9bcc5a02787a2f Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <f4bug@amsat.org>
|
|
Date: Thu, 4 Jun 2020 19:22:29 +0200
|
|
Subject: [PATCH 7/7] hw/sd/sdcard: Do not switch to ReceivingData if address
|
|
is invalid
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Only move the state machine to ReceivingData if there is no
|
|
pending error. This avoids later OOB access while processing
|
|
commands queued.
|
|
|
|
"SD Specifications Part 1 Physical Layer Simplified Spec. v3.01"
|
|
|
|
4.3.3 Data Read
|
|
|
|
Read command is rejected if BLOCK_LEN_ERROR or ADDRESS_ERROR
|
|
occurred and no data transfer is performed.
|
|
|
|
4.3.4 Data Write
|
|
|
|
Write command is rejected if BLOCK_LEN_ERROR or ADDRESS_ERROR
|
|
occurred and no data transfer is performed.
|
|
|
|
WP_VIOLATION errors are not modified: the error bit is set, we
|
|
stay in receive-data state, wait for a stop command. All further
|
|
data transfer is ignored. See the check on sd->card_status at the
|
|
beginning of sd_read_data() and sd_write_data().
|
|
|
|
Fixes: CVE-2020-13253
|
|
Cc: qemu-stable@nongnu.org
|
|
Reported-by: Alexander Bulekov <alxndr@bu.edu>
|
|
Buglink: https://bugs.launchpad.net/qemu/+bug/1880822
|
|
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
|
|
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
|
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
|
|
Message-Id: <20200630133912.9428-6-f4bug@amsat.org>
|
|
---
|
|
hw/sd/sd.c | 38 ++++++++++++++++++++++++--------------
|
|
1 file changed, 24 insertions(+), 14 deletions(-)
|
|
|
|
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
|
|
index ed796fb41f..79d5f1a5b9 100644
|
|
--- a/hw/sd/sd.c
|
|
+++ b/hw/sd/sd.c
|
|
@@ -1156,13 +1156,15 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
|
|
case 17: /* CMD17: READ_SINGLE_BLOCK */
|
|
switch (sd->state) {
|
|
case sd_transfer_state:
|
|
- sd->state = sd_sendingdata_state;
|
|
- sd->data_start = addr;
|
|
- sd->data_offset = 0;
|
|
|
|
- if (sd->data_start + sd->blk_len > sd->size) {
|
|
+ if (addr + sd->blk_len > sd->size) {
|
|
sd->card_status |= ADDRESS_ERROR;
|
|
+ return sd_r1;
|
|
}
|
|
+
|
|
+ sd->state = sd_sendingdata_state;
|
|
+ sd->data_start = addr;
|
|
+ sd->data_offset = 0;
|
|
return sd_r1;
|
|
|
|
default:
|
|
@@ -1173,13 +1175,15 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
|
|
case 18: /* CMD18: READ_MULTIPLE_BLOCK */
|
|
switch (sd->state) {
|
|
case sd_transfer_state:
|
|
- sd->state = sd_sendingdata_state;
|
|
- sd->data_start = addr;
|
|
- sd->data_offset = 0;
|
|
|
|
- if (sd->data_start + sd->blk_len > sd->size) {
|
|
+ if (addr + sd->blk_len > sd->size) {
|
|
sd->card_status |= ADDRESS_ERROR;
|
|
+ return sd_r1;
|
|
}
|
|
+
|
|
+ sd->state = sd_sendingdata_state;
|
|
+ sd->data_start = addr;
|
|
+ sd->data_offset = 0;
|
|
return sd_r1;
|
|
|
|
default:
|
|
@@ -1219,14 +1223,17 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
|
|
/* Writing in SPI mode not implemented. */
|
|
if (sd->spi)
|
|
break;
|
|
+
|
|
+ if (addr + sd->blk_len > sd->size) {
|
|
+ sd->card_status |= ADDRESS_ERROR;
|
|
+ return sd_r1;
|
|
+ }
|
|
+
|
|
sd->state = sd_receivingdata_state;
|
|
sd->data_start = addr;
|
|
sd->data_offset = 0;
|
|
sd->blk_written = 0;
|
|
|
|
- if (sd->data_start + sd->blk_len > sd->size) {
|
|
- sd->card_status |= ADDRESS_ERROR;
|
|
- }
|
|
if (sd_wp_addr(sd, sd->data_start)) {
|
|
sd->card_status |= WP_VIOLATION;
|
|
}
|
|
@@ -1246,14 +1253,17 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
|
|
/* Writing in SPI mode not implemented. */
|
|
if (sd->spi)
|
|
break;
|
|
+
|
|
+ if (addr + sd->blk_len > sd->size) {
|
|
+ sd->card_status |= ADDRESS_ERROR;
|
|
+ return sd_r1;
|
|
+ }
|
|
+
|
|
sd->state = sd_receivingdata_state;
|
|
sd->data_start = addr;
|
|
sd->data_offset = 0;
|
|
sd->blk_written = 0;
|
|
|
|
- if (sd->data_start + sd->blk_len > sd->size) {
|
|
- sd->card_status |= ADDRESS_ERROR;
|
|
- }
|
|
if (sd_wp_addr(sd, sd->data_start)) {
|
|
sd->card_status |= WP_VIOLATION;
|
|
}
|
|
--
|
|
2.17.1
|
|
|