[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[qemu-xen stable-4.14] hw/sd/sdcard: Do not switch to ReceivingData if address is invalid



commit d7fab184e98bc0d482b0203fd3333da972b7ca5f
Author:     Philippe Mathieu-Daudé <f4bug@xxxxxxxxx>
AuthorDate: Thu Jun 4 19:22:29 2020 +0200
Commit:     Michael Roth <mdroth@xxxxxxxxxxxxxxxxxx>
CommitDate: Wed Sep 2 19:06:19 2020 -0500

    hw/sd/sdcard: Do not switch to ReceivingData if address is invalid
    
    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@xxxxxxxxxx
    Reported-by: Alexander Bulekov <alxndr@xxxxxx>
    Buglink: https://bugs.launchpad.net/qemu/+bug/1880822
    Reviewed-by: Peter Maydell <peter.maydell@xxxxxxxxxx>
    Signed-off-by: Philippe Mathieu-Daudé <f4bug@xxxxxxxxx>
    Reviewed-by: Alistair Francis <alistair.francis@xxxxxxx>
    Message-Id: <20200630133912.9428-6-f4bug@xxxxxxxxx>
    (cherry picked from commit 790762e5487114341cccc5bffcec4cb3c022c3cd)
    Signed-off-by: Michael Roth <mdroth@xxxxxxxxxxxxxxxxxx>
---
 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 b927f7966d..837fe9053d 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;
             }
--
generated by git-patchbot for /home/xen/git/qemu-xen.git#stable-4.14



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.