aboutsummaryrefslogtreecommitdiff
path: root/block/raw_bsd.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-12-11 12:36:32 +0000
committerPeter Maydell <peter.maydell@linaro.org>2014-12-11 12:36:32 +0000
commit7c3843332db39c2f27405b882a505144d62b3664 (patch)
treedaac220f4cb19a2fec8457c00f2c4aeae1092824 /block/raw_bsd.c
parenta09f2d16f6b9f5bcdedb4d116bb54da86e9a3f6e (diff)
parentd899d2e248b900c53dd9081bde9f110e05747433 (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.c66
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,