Revision b64ec4e4

b/block.c
328 328
    return NULL;
329 329
}
330 330

  
331
static int bdrv_is_whitelisted(BlockDriver *drv)
331
static int bdrv_is_whitelisted(BlockDriver *drv, bool read_only)
332 332
{
333
    static const char *whitelist[] = {
334
        CONFIG_BDRV_WHITELIST
333
    static const char *whitelist_rw[] = {
334
        CONFIG_BDRV_RW_WHITELIST
335
    };
336
    static const char *whitelist_ro[] = {
337
        CONFIG_BDRV_RO_WHITELIST
335 338
    };
336 339
    const char **p;
337 340

  
338
    if (!whitelist[0])
341
    if (!whitelist_rw[0] && !whitelist_ro[0]) {
339 342
        return 1;               /* no whitelist, anything goes */
343
    }
340 344

  
341
    for (p = whitelist; *p; p++) {
345
    for (p = whitelist_rw; *p; p++) {
342 346
        if (!strcmp(drv->format_name, *p)) {
343 347
            return 1;
344 348
        }
345 349
    }
350
    if (read_only) {
351
        for (p = whitelist_ro; *p; p++) {
352
            if (!strcmp(drv->format_name, *p)) {
353
                return 1;
354
            }
355
        }
356
    }
346 357
    return 0;
347 358
}
348 359

  
349
BlockDriver *bdrv_find_whitelisted_format(const char *format_name)
360
BlockDriver *bdrv_find_whitelisted_format(const char *format_name,
361
                                          bool read_only)
350 362
{
351 363
    BlockDriver *drv = bdrv_find_format(format_name);
352
    return drv && bdrv_is_whitelisted(drv) ? drv : NULL;
364
    return drv && bdrv_is_whitelisted(drv, read_only) ? drv : NULL;
353 365
}
354 366

  
355 367
typedef struct CreateCo {
......
684 696

  
685 697
    trace_bdrv_open_common(bs, filename ?: "", flags, drv->format_name);
686 698

  
687
    if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv)) {
688
        return -ENOTSUP;
689
    }
690

  
691 699
    /* bdrv_open() with directly using a protocol as drv. This layer is already
692 700
     * opened, so assign it to bs (while file becomes a closed BlockDriverState)
693 701
     * and return immediately. */
......
698 706

  
699 707
    bs->open_flags = flags;
700 708
    bs->buffer_alignment = 512;
709
    open_flags = bdrv_open_flags(bs, flags);
710
    bs->read_only = !(open_flags & BDRV_O_RDWR);
711

  
712
    if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv, bs->read_only)) {
713
        return -ENOTSUP;
714
    }
701 715

  
702 716
    assert(bs->copy_on_read == 0); /* bdrv_new() and bdrv_close() make it so */
703
    if ((flags & BDRV_O_RDWR) && (flags & BDRV_O_COPY_ON_READ)) {
717
    if (!bs->read_only && (flags & BDRV_O_COPY_ON_READ)) {
704 718
        bdrv_enable_copy_on_read(bs);
705 719
    }
706 720

  
......
714 728
    bs->opaque = g_malloc0(drv->instance_size);
715 729

  
716 730
    bs->enable_write_cache = !!(flags & BDRV_O_CACHE_WB);
717
    open_flags = bdrv_open_flags(bs, flags);
718

  
719
    bs->read_only = !(open_flags & BDRV_O_RDWR);
720 731

  
721 732
    /* Open the image, either directly or using a protocol */
722 733
    if (drv->bdrv_file_open) {
......
801 812
    /* Find the right block driver */
802 813
    drvname = qdict_get_try_str(options, "driver");
803 814
    if (drvname) {
804
        drv = bdrv_find_whitelisted_format(drvname);
815
        drv = bdrv_find_whitelisted_format(drvname, !(flags & BDRV_O_RDWR));
805 816
        qdict_del(options, "driver");
806 817
    } else if (filename) {
807 818
        drv = bdrv_find_protocol(filename);
b/blockdev.c
477 477
            error_printf("\n");
478 478
            return NULL;
479 479
        }
480
        drv = bdrv_find_whitelisted_format(buf);
480
        drv = bdrv_find_whitelisted_format(buf, ro);
481 481
        if (!drv) {
482 482
            error_report("'%s' invalid format", buf);
483 483
            return NULL;
......
1096 1096
    }
1097 1097

  
1098 1098
    if (format) {
1099
        drv = bdrv_find_whitelisted_format(format);
1099
        drv = bdrv_find_whitelisted_format(format, bs->read_only);
1100 1100
        if (!drv) {
1101 1101
            error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
1102 1102
            return;
b/configure
123 123
static="no"
124 124
cross_prefix=""
125 125
audio_drv_list=""
126
block_drv_whitelist=""
126
block_drv_rw_whitelist=""
127
block_drv_ro_whitelist=""
127 128
host_cc="cc"
128 129
libs_softmmu=""
129 130
libs_tools=""
......
708 709
  ;;
709 710
  --audio-drv-list=*) audio_drv_list="$optarg"
710 711
  ;;
711
  --block-drv-whitelist=*) block_drv_whitelist=`echo "$optarg" | sed -e 's/,/ /g'`
712
  --block-drv-rw-whitelist=*|--block-drv-whitelist=*) block_drv_rw_whitelist=`echo "$optarg" | sed -e 's/,/ /g'`
713
  ;;
714
  --block-drv-ro-whitelist=*) block_drv_ro_whitelist=`echo "$optarg" | sed -e 's/,/ /g'`
712 715
  ;;
713 716
  --enable-debug-tcg) debug_tcg="yes"
714 717
  ;;
......
1049 1052
echo "  --enable-cocoa           enable Cocoa (default on Mac OS X)"
1050 1053
echo "  --audio-drv-list=LIST    set audio drivers list:"
1051 1054
echo "                           Available drivers: $audio_possible_drivers"
1052
echo "  --block-drv-whitelist=L  set block driver whitelist"
1055
echo "  --block-drv-whitelist=L  Same as --block-drv-rw-whitelist=L"
1056
echo "  --block-drv-rw-whitelist=L"
1057
echo "                           set block driver read-write whitelist"
1058
echo "                           (affects only QEMU, not qemu-img)"
1059
echo "  --block-drv-ro-whitelist=L"
1060
echo "                           set block driver read-only whitelist"
1053 1061
echo "                           (affects only QEMU, not qemu-img)"
1054 1062
echo "  --enable-mixemu          enable mixer emulation"
1055 1063
echo "  --disable-xen            disable xen backend driver support"
......
3481 3489
echo "curl support      $curl"
3482 3490
echo "mingw32 support   $mingw32"
3483 3491
echo "Audio drivers     $audio_drv_list"
3484
echo "Block whitelist   $block_drv_whitelist"
3492
echo "Block whitelist (rw) $block_drv_rw_whitelist"
3493
echo "Block whitelist (ro) $block_drv_ro_whitelist"
3485 3494
echo "Mixer emulation   $mixemu"
3486 3495
echo "VirtFS support    $virtfs"
3487 3496
echo "VNC support       $vnc"
......
3662 3671
if test "$audio_win_int" = "yes" ; then
3663 3672
  echo "CONFIG_AUDIO_WIN_INT=y" >> $config_host_mak
3664 3673
fi
3665
echo "CONFIG_BDRV_WHITELIST=$block_drv_whitelist" >> $config_host_mak
3674
echo "CONFIG_BDRV_RW_WHITELIST=$block_drv_rw_whitelist" >> $config_host_mak
3675
echo "CONFIG_BDRV_RO_WHITELIST=$block_drv_ro_whitelist" >> $config_host_mak
3666 3676
if test "$mixemu" = "yes" ; then
3667 3677
  echo "CONFIG_MIXEMU=y" >> $config_host_mak
3668 3678
fi
b/hw/block/xen_disk.c
780 780
{
781 781
    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
782 782
    int pers, index, qflags;
783
    bool readonly = true;
783 784

  
784 785
    /* read-only ? */
785 786
    qflags = BDRV_O_CACHE_WB | BDRV_O_NATIVE_AIO;
786 787
    if (strcmp(blkdev->mode, "w") == 0) {
787 788
        qflags |= BDRV_O_RDWR;
789
        readonly = false;
788 790
    }
789 791

  
790 792
    /* init qemu block driver */
......
795 797
        xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n");
796 798
        blkdev->bs = bdrv_new(blkdev->dev);
797 799
        if (blkdev->bs) {
798
            if (bdrv_open(blkdev->bs, blkdev->filename, NULL, qflags,
799
                        bdrv_find_whitelisted_format(blkdev->fileproto)) != 0) {
800
            BlockDriver *drv = bdrv_find_whitelisted_format(blkdev->fileproto,
801
                                                           readonly);
802
            if (bdrv_open(blkdev->bs,
803
                          blkdev->filename, NULL, qflags, drv) != 0) {
800 804
                bdrv_delete(blkdev->bs);
801 805
                blkdev->bs = NULL;
802 806
            }
b/include/block/block.h
124 124
void bdrv_init_with_whitelist(void);
125 125
BlockDriver *bdrv_find_protocol(const char *filename);
126 126
BlockDriver *bdrv_find_format(const char *format_name);
127
BlockDriver *bdrv_find_whitelisted_format(const char *format_name);
127
BlockDriver *bdrv_find_whitelisted_format(const char *format_name,
128
                                          bool readonly);
128 129
int bdrv_create(BlockDriver *drv, const char* filename,
129 130
    QEMUOptionParameter *options);
130 131
int bdrv_create_file(const char* filename, QEMUOptionParameter *options);
b/scripts/create_config
34 34
    done
35 35
    echo ""
36 36
    ;;
37
 CONFIG_BDRV_WHITELIST=*)
38
    echo "#define CONFIG_BDRV_WHITELIST \\"
37
 CONFIG_BDRV_RW_WHITELIST=*)
38
    echo "#define CONFIG_BDRV_RW_WHITELIST\\"
39
    for drv in ${line#*=}; do
40
      echo "    \"${drv}\",\\"
41
    done
42
    echo "    NULL"
43
    ;;
44
 CONFIG_BDRV_RO_WHITELIST=*)
45
    echo "#define CONFIG_BDRV_RO_WHITELIST\\"
39 46
    for drv in ${line#*=}; do
40 47
      echo "    \"${drv}\",\\"
41 48
    done

Also available in: Unified diff