diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2014-12-11 12:36:32 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2014-12-11 12:36:32 +0000 |
commit | 7c3843332db39c2f27405b882a505144d62b3664 (patch) | |
tree | daac220f4cb19a2fec8457c00f2c4aeae1092824 /block/raw_bsd.c | |
parent | a09f2d16f6b9f5bcdedb4d116bb54da86e9a3f6e (diff) | |
parent | d899d2e248b900c53dd9081bde9f110e05747433 (diff) |
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block patches for 2.3
# gpg: Signature made Wed 10 Dec 2014 09:31:53 GMT using RSA key ID C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"
* remotes/kevin/tags/for-upstream: (73 commits)
vmdk: Set errp on failures in vmdk_open_vmdk4
vmdk: Remove unnecessary initialization
vmdk: Check descriptor file length when reading it
vmdk: Clean up descriptor file reading
vmdk: Fix comment to match code of extent lines
vmdk: Use g_random_int to generate CID
block: Use g_new0() for a bit of extra type checking
block: remove BLOCK_OPT_NOCOW from vpc_create_opts
block: remove BLOCK_OPT_NOCOW from vdi_create_opts
qemu-iotests: Skip 099 for VMDK subformats with desc file
block/raw-posix: Fix ret in raw_open_common()
qcow2: Respect bdrv_truncate() error
qcow2: Flushing the caches in qcow2_close may fail
qcow2: Prevent numerical overflow
iotests: Add test for unsupported image creation
iotests: Only kill NBD server if it runs
qemu-img: Check create_opts before image amendment
qemu-img: Check create_opts before image creation
block: Check create_opts before image creation
block/nfs: Add create_opts
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'block/raw_bsd.c')
-rw-r--r-- | block/raw_bsd.c | 66 |
1 files changed, 64 insertions, 2 deletions
diff --git a/block/raw_bsd.c b/block/raw_bsd.c index 401b967e85..05b02c76d4 100644 --- a/block/raw_bsd.c +++ b/block/raw_bsd.c @@ -58,8 +58,58 @@ static int coroutine_fn raw_co_readv(BlockDriverState *bs, int64_t sector_num, static int coroutine_fn raw_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) { + void *buf = NULL; + BlockDriver *drv; + QEMUIOVector local_qiov; + int ret; + + if (bs->probed && sector_num == 0) { + /* As long as these conditions are true, we can't get partial writes to + * the probe buffer and can just directly check the request. */ + QEMU_BUILD_BUG_ON(BLOCK_PROBE_BUF_SIZE != 512); + QEMU_BUILD_BUG_ON(BDRV_SECTOR_SIZE != 512); + + if (nb_sectors == 0) { + /* qemu_iovec_to_buf() would fail, but we want to return success + * instead of -EINVAL in this case. */ + return 0; + } + + buf = qemu_try_blockalign(bs->file, 512); + if (!buf) { + ret = -ENOMEM; + goto fail; + } + + ret = qemu_iovec_to_buf(qiov, 0, buf, 512); + if (ret != 512) { + ret = -EINVAL; + goto fail; + } + + drv = bdrv_probe_all(buf, 512, NULL); + if (drv != bs->drv) { + ret = -EPERM; + goto fail; + } + + /* Use the checked buffer, a malicious guest might be overwriting its + * original buffer in the background. */ + qemu_iovec_init(&local_qiov, qiov->niov + 1); + qemu_iovec_add(&local_qiov, buf, 512); + qemu_iovec_concat(&local_qiov, qiov, 512, qiov->size - 512); + qiov = &local_qiov; + } + BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); - return bdrv_co_writev(bs->file, sector_num, nb_sectors, qiov); + ret = bdrv_co_writev(bs->file, sector_num, nb_sectors, qiov); + +fail: + if (qiov == &local_qiov) { + qemu_iovec_destroy(&local_qiov); + } + qemu_vfree(buf); + return ret; } static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs, @@ -158,6 +208,18 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { bs->sg = bs->file->sg; + + if (bs->probed && !bdrv_is_read_only(bs)) { + fprintf(stderr, + "WARNING: Image format was not specified for '%s' and probing " + "guessed raw.\n" + " Automatically detecting the format is dangerous for " + "raw images, write operations on block 0 will be restricted.\n" + " Specify the 'raw' format explicitly to remove the " + "restrictions.\n", + bs->file->filename); + } + return 0; } @@ -173,7 +235,7 @@ static int raw_probe(const uint8_t *buf, int buf_size, const char *filename) return 1; } -static BlockDriver bdrv_raw = { +BlockDriver bdrv_raw = { .format_name = "raw", .bdrv_probe = &raw_probe, .bdrv_reopen_prepare = &raw_reopen_prepare, |