qemu-block
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]