Skip to content

Commit

Permalink
Configurable block format whitelist
Browse files Browse the repository at this point in the history
We have code for a quite a few block formats.  While I trust that all
of these formats are useful at least for some people in some
circumstances, some of them are of a kind that friends don't let
friends use in production.

This patch provides an optional block format whitelist, default off.
If a whitelist is configured with --block-drv-whitelist, QEMU proper
can use only whitelisted formats.  Other programs, like qemu-img, are
not affected.

Drivers for formats off the whitelist still participate in format
probing, to ensure all programs probe exactly the same.  Without that,
QEMU proper would be prone to treat images with a format off the
whitelist as raw when the image's format is probed.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
  • Loading branch information
Markus Armbruster authored and Anthony Liguori committed Nov 9, 2009
1 parent 39a51df commit eb85201
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 5 deletions.
38 changes: 37 additions & 1 deletion block.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand Down
2 changes: 2 additions & 0 deletions block.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
7 changes: 7 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions create_config
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
3 changes: 2 additions & 1 deletion hw/xen_disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions vl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit eb85201

Please sign in to comment.