summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--block.c38
-rw-r--r--block.h2
-rwxr-xr-xconfigure7
-rwxr-xr-xcreate_config7
-rw-r--r--hw/xen_disk.c3
-rw-r--r--monitor.c2
-rw-r--r--vl.c4
7 files changed, 58 insertions, 5 deletions
diff --git a/block.c b/block.c
index 05c83115b3..1e49bc05cc 100644
--- a/block.c
+++ b/block.c
@@ -61,6 +61,9 @@ BlockDriverState *bdrv_first;
 
 static BlockDriver *first_drv;
 
+/* If non-zero, use only whitelisted block drivers */
+static int use_bdrv_whitelist;
+
 int path_is_absolute(const char *path)
 {
     const char *p;
@@ -171,6 +174,30 @@ BlockDriver *bdrv_find_format(const char *format_name)
     return NULL;
 }
 
+static int bdrv_is_whitelisted(BlockDriver *drv)
+{
+    static const char *whitelist[] = {
+        CONFIG_BDRV_WHITELIST
+    };
+    const char **p;
+
+    if (!whitelist[0])
+        return 1;               /* no whitelist, anything goes */
+
+    for (p = whitelist; *p; p++) {
+        if (!strcmp(drv->format_name, *p)) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+BlockDriver *bdrv_find_whitelisted_format(const char *format_name)
+{
+    BlockDriver *drv = bdrv_find_format(format_name);
+    return drv && bdrv_is_whitelisted(drv) ? drv : NULL;
+}
+
 int bdrv_create(BlockDriver *drv, const char* filename,
     QEMUOptionParameter *options)
 {
@@ -427,7 +454,10 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
             (flags & (BDRV_O_CACHE_MASK|BDRV_O_NATIVE_AIO));
     else
         open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
-    ret = drv->bdrv_open(bs, filename, open_flags);
+    if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv))
+        ret = -ENOTSUP;
+    else
+        ret = drv->bdrv_open(bs, filename, open_flags);
     if ((ret == -EACCES || ret == -EPERM) && !(flags & BDRV_O_FILE)) {
         ret = drv->bdrv_open(bs, filename, open_flags & ~BDRV_O_RDWR);
         bs->read_only = 1;
@@ -1764,6 +1794,12 @@ void bdrv_init(void)
     module_call_init(MODULE_INIT_BLOCK);
 }
 
+void bdrv_init_with_whitelist(void)
+{
+    use_bdrv_whitelist = 1;
+    bdrv_init();
+}
+
 void *qemu_aio_get(AIOPool *pool, BlockDriverState *bs,
                    BlockDriverCompletionFunc *cb, void *opaque)
 {
diff --git a/block.h b/block.h
index 302010d953..6b0146f7cf 100644
--- a/block.h
+++ b/block.h
@@ -45,7 +45,9 @@ void bdrv_info(Monitor *mon);
 void bdrv_info_stats(Monitor *mon);
 
 void bdrv_init(void);
+void bdrv_init_with_whitelist(void);
 BlockDriver *bdrv_find_format(const char *format_name);
+BlockDriver *bdrv_find_whitelisted_format(const char *format_name);
 int bdrv_create(BlockDriver *drv, const char* filename,
     QEMUOptionParameter *options);
 int bdrv_create2(BlockDriver *drv,
diff --git a/configure b/configure
index aa2cc43227..fb66246a74 100755
--- a/configure
+++ b/configure
@@ -38,6 +38,7 @@ cc="gcc"
 audio_drv_list=""
 audio_card_list="ac97 es1370 sb16"
 audio_possible_cards="ac97 es1370 sb16 cs4231a adlib gus"
+block_drv_whitelist=""
 host_cc="gcc"
 ar="ar"
 make="make"
@@ -430,6 +431,8 @@ for opt do
   ;;
   --audio-drv-list=*) audio_drv_list="$optarg"
   ;;
+  --block-drv-whitelist=*) block_drv_whitelist=`echo "$optarg" | sed -e 's/,/ /g'`
+  ;;
   --enable-debug-tcg) debug_tcg="yes"
   ;;
   --disable-debug-tcg) debug_tcg="no"
@@ -661,6 +664,8 @@ echo "  --audio-drv-list=LIST    set audio drivers list:"
 echo "                           Available drivers: $audio_possible_drivers"
 echo "  --audio-card-list=LIST   set list of emulated audio cards [$audio_card_list]"
 echo "                           Available cards: $audio_possible_cards"
+echo "  --block-drv-whitelist=L  set block driver whitelist"
+echo "                           (affects only QEMU, not qemu-img)"
 echo "  --enable-mixemu          enable mixer emulation"
 echo "  --disable-xen            disable xen backend driver support"
 echo "  --enable-xen             enable xen backend driver support"
@@ -1826,6 +1831,7 @@ echo "check support     $check_utests"
 echo "mingw32 support   $mingw32"
 echo "Audio drivers     $audio_drv_list"
 echo "Extra audio cards $audio_card_list"
+echo "Block whitelist   $block_drv_whitelist"
 echo "Mixer emulation   $mixemu"
 echo "VNC TLS support   $vnc_tls"
 echo "VNC SASL support  $vnc_sasl"
@@ -1948,6 +1954,7 @@ fi
 if test "$audio_win_int" = "yes" ; then
   echo "CONFIG_AUDIO_WIN_INT=y" >> $config_host_mak
 fi
+echo "CONFIG_BDRV_WHITELIST=$block_drv_whitelist" >> $config_host_mak
 if test "$mixemu" = "yes" ; then
   echo "CONFIG_MIXEMU=y" >> $config_host_mak
 fi
diff --git a/create_config b/create_config
index 30d0487e24..2f052ae615 100755
--- a/create_config
+++ b/create_config
@@ -26,6 +26,13 @@ case $line in
     done
     echo ""
     ;;
+ CONFIG_BDRV_WHITELIST=*)
+    echo "#define CONFIG_BDRV_WHITELIST \\"
+    for drv in ${line#*=}; do
+      echo "    \"${drv}\",\\"
+    done
+    echo "    NULL"
+    ;;
  CONFIG_*=y) # configuration
     name=${line%=*}
     echo "#define $name 1"
diff --git a/hw/xen_disk.c b/hw/xen_disk.c
index 74cde80691..5c55251320 100644
--- a/hw/xen_disk.c
+++ b/hw/xen_disk.c
@@ -630,7 +630,8 @@ static int blk_init(struct XenDevice *xendev)
 	blkdev->bs = bdrv_new(blkdev->dev);
 	if (blkdev->bs) {
 	    if (bdrv_open2(blkdev->bs, blkdev->filename, qflags,
-                           bdrv_find_format(blkdev->fileproto)) != 0) {
+                           bdrv_find_whitelisted_format(blkdev->fileproto))
+                != 0) {
 		bdrv_delete(blkdev->bs);
 		blkdev->bs = NULL;
 	    }
diff --git a/monitor.c b/monitor.c
index 109ff5c448..132fb6e068 100644
--- a/monitor.c
+++ b/monitor.c
@@ -596,7 +596,7 @@ static void do_change_block(Monitor *mon, const char *device,
         return;
     }
     if (fmt) {
-        drv = bdrv_find_format(fmt);
+        drv = bdrv_find_whitelisted_format(fmt);
         if (!drv) {
             monitor_printf(mon, "invalid format %s\n", fmt);
             return;
diff --git a/vl.c b/vl.c
index 613cbdb63f..402e78d987 100644
--- a/vl.c
+++ b/vl.c
@@ -2156,7 +2156,7 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
             fprintf(stderr, "\n");
 	    return NULL;
         }
-        drv = bdrv_find_format(buf);
+        drv = bdrv_find_whitelisted_format(buf);
         if (!drv) {
             fprintf(stderr, "qemu: '%s' invalid format\n", buf);
             return NULL;
@@ -5522,7 +5522,7 @@ int main(int argc, char **argv, char **envp)
     /* init the dynamic translator */
     cpu_exec_init_all(tb_size * 1024 * 1024);
 
-    bdrv_init();
+    bdrv_init_with_whitelist();
 
     /* we always create the cdrom drive, even if no disk is there */
     drive_add(NULL, CDROM_ALIAS);