[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH-for-8.1] hw/sd/sdcard: Allow users to bypass the power-of-2 size
From: |
Philippe Mathieu-Daudé |
Subject: |
[PATCH-for-8.1] hw/sd/sdcard: Allow users to bypass the power-of-2 size check |
Date: |
Mon, 17 Jul 2023 17:53:16 +0200 |
Since we committed a9bcedd15a ("hw/sd/sdcard: Do not allow invalid
SD card sizes") to preclude some guests to access beyond the size
of the card (leading to security issues such CVE-2020-13253), various
users complained this prevent them to run guests potencially well
behaving with non-power-of-2 card sizes. In order to allow them to
experiment with such guests, add a property to disable the pow2
check.
Resolves: https://bugs.launchpad.net/qemu/+bug/1910586
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/297
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1754
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/sd/sd.c | 31 ++++++++++++++++++++++++++++---
1 file changed, 28 insertions(+), 3 deletions(-)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 77a717d355..feada6607a 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -108,6 +108,7 @@ struct SDState {
uint8_t spec_version;
BlockBackend *blk;
bool spi;
+ bool bypass_pow2_size_check;
/* Runtime changeables */
@@ -2126,6 +2127,9 @@ static void sd_instance_finalize(Object *obj)
timer_free(sd->ocr_power_timer);
}
+#define PROP_NAME_BYPASS_POW2_SIZE_CHECK \
+ "allow-unsafe-unsupported-not-power-of-2-size"
+
static void sd_realize(DeviceState *dev, Error **errp)
{
SDState *sd = SD_CARD(dev);
@@ -2151,7 +2155,13 @@ static void sd_realize(DeviceState *dev, Error **errp)
}
blk_size = blk_getlength(sd->blk);
- if (blk_size > 0 && !is_power_of_2(blk_size)) {
+ if (sd->bypass_pow2_size_check) {
+ warn_report_once("Unsupported property '%s' enabled: some guests"
+ " might trigger data corruption and/or crash"
+ " (thus this process is vulnerable to"
+ " CVE-2020-13253).",
+ PROP_NAME_BYPASS_POW2_SIZE_CHECK);
+ } else if (blk_size > 0 && !is_power_of_2(blk_size)) {
int64_t blk_size_aligned = pow2ceil(blk_size);
char *blk_size_str;
@@ -2161,11 +2171,15 @@ static void sd_realize(DeviceState *dev, Error **errp)
blk_size_str = size_to_str(blk_size_aligned);
error_append_hint(errp,
- "SD card size has to be a power of 2, e.g. %s.\n"
+ "SD card size should be a power of 2, e.g. %s.\n"
"You can resize disk images with"
" 'qemu-img resize <imagefile> <new-size>'\n"
"(note that this will lose data if you make the"
- " image smaller than it currently is).\n",
+ " image smaller than it currently is).\n"
+ "Note: you can disable this check by setting"
+ " the '" PROP_NAME_BYPASS_POW2_SIZE_CHECK "'"
+ " global property but this is DANGEROUS"
+ " and unsupported.\n",
blk_size_str);
g_free(blk_size_str);
@@ -2190,6 +2204,17 @@ static Property sd_properties[] = {
* board to ensure that ssi transfers only occur when the chip select
* is asserted. */
DEFINE_PROP_BOOL("spi", SDState, spi, false),
+ /*
+ * Some guests (at least Linux) consider sizes that are not a power
+ * of 2 as a firmware bug and round the card size up to the next
+ * power of 2. For simplicity and security (see CVE-2020-13253) we
+ * only model guest access to the full drive, so we only accept drives
+ * having a power-of-2 size. That said, some guests might behave
+ * correctly with non-power-of-2 cards. Users want to experiment
+ * booting such guests so we provide a way to disable the check.
+ */
+ DEFINE_PROP_BOOL(PROP_NAME_BYPASS_POW2_SIZE_CHECK,
+ SDState, bypass_pow2_size_check, false),
DEFINE_PROP_END_OF_LIST()
};
--
2.38.1
- [PATCH-for-8.1] hw/sd/sdcard: Allow users to bypass the power-of-2 size check,
Philippe Mathieu-Daudé <=