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