From: Bin Meng Date: Tue, 16 Feb 2021 15:02:22 +0000 (+0800) Subject: hw/sd: sd: Skip write protect groups check in sd_erase() for high capacity cards X-Git-Tag: upstream/5.2.0~95 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=458b646456a9e7f1e14fba7cf18e5ff4a28f8a23;p=platform%2Fupstream%2Fqemu.git hw/sd: sd: Skip write protect groups check in sd_erase() for high capacity cards Git-commit: 2473dc4022458dcc05ec367ce97edbef29d7e50c References: bsc#1175144, CVE-2020-17380, bsc#1176681, CVE-2020-25085 References: bsc#1182282, CVE-2021-3409 High capacity cards don't support write protection hence we should not perform the write protect groups check in sd_erase() for them. Signed-off-by: Bin Meng Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20210216150225.27996-6-bmeng.cn@gmail.com> Signed-off-by: Philippe Mathieu-Daudé Signed-off-by: Bruce Rogers --- diff --git a/hw/sd/sd.c b/hw/sd/sd.c index ac48140..a4ea365 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -781,6 +781,7 @@ static void sd_erase(SDState *sd) int i; uint64_t erase_start = sd->erase_start; uint64_t erase_end = sd->erase_end; + bool sdsc = true; trace_sdcard_erase(sd->erase_start, sd->erase_end); if (sd->erase_start == INVALID_ADDRESS @@ -795,6 +796,7 @@ static void sd_erase(SDState *sd) /* High capacity memory card: erase units are 512 byte blocks */ erase_start *= 512; erase_end *= 512; + sdsc = false; } if (sd->erase_start > sd->size || sd->erase_end > sd->size) { @@ -804,16 +806,20 @@ static void sd_erase(SDState *sd) return; } - erase_start = sd_addr_to_wpnum(erase_start); - erase_end = sd_addr_to_wpnum(erase_end); sd->erase_start = INVALID_ADDRESS; sd->erase_end = INVALID_ADDRESS; sd->csd[14] |= 0x40; - for (i = erase_start; i <= erase_end; i++) { - assert(i < sd->wpgrps_size); - if (test_bit(i, sd->wp_groups)) { - sd->card_status |= WP_ERASE_SKIP; + /* Only SDSC cards support write protect groups */ + if (sdsc) { + erase_start = sd_addr_to_wpnum(erase_start); + erase_end = sd_addr_to_wpnum(erase_end); + + for (i = erase_start; i <= erase_end; i++) { + assert(i < sd->wpgrps_size); + if (test_bit(i, sd->wp_groups)) { + sd->card_status |= WP_ERASE_SKIP; + } } } }