yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone
ae23c9
From 2e757d702c366a1eb58abe33ed39331253bfa851 Mon Sep 17 00:00:00 2001
ae23c9
From: Kevin Wolf <kwolf@redhat.com>
ae23c9
Date: Fri, 13 Jul 2018 14:50:01 +0200
ae23c9
Subject: [PATCH 217/268] file-posix: specify expected filetypes
ae23c9
ae23c9
RH-Author: Kevin Wolf <kwolf@redhat.com>
ae23c9
Message-id: <20180713145002.20953-2-kwolf@redhat.com>
ae23c9
Patchwork-id: 81350
ae23c9
O-Subject: [RHV-7.6 qemu-kvm-rhev PATCH 1/2] file-posix: specify expected filetypes
ae23c9
Bugzilla: 1525829
ae23c9
RH-Acked-by: John Snow <jsnow@redhat.com>
ae23c9
RH-Acked-by: Max Reitz <mreitz@redhat.com>
ae23c9
RH-Acked-by: Fam Zheng <famz@redhat.com>
ae23c9
ae23c9
From: John Snow <jsnow@redhat.com>
ae23c9
ae23c9
Adjust each caller of raw_open_common to specify if they are expecting
ae23c9
host and character devices or not. Tighten expectations of file types upon
ae23c9
open in the common code and refuse types that are not expected.
ae23c9
ae23c9
This has two effects:
ae23c9
ae23c9
(1) Character and block devices are now considered deprecated for the
ae23c9
    'file' driver, which expects only S_IFREG, and
ae23c9
(2) no file-posix driver (file, host_cdrom, or host_device) can open
ae23c9
    directories now.
ae23c9
ae23c9
I don't think there's a legitimate reason to open directories as if
ae23c9
they were files. This prevents QEMU from opening and attempting to probe
ae23c9
a directory inode, which can break in exciting ways. One of those ways
ae23c9
is lseek on ext4/xfs, which will return 0x7fffffffffffffff as the file
ae23c9
size instead of EISDIR. This can coax QEMU into responding with a
ae23c9
confusing "file too big" instead of "Hey, that's not a file".
ae23c9
ae23c9
See: https://bugs.launchpad.net/qemu/+bug/1739304/
ae23c9
Signed-off-by: John Snow <jsnow@redhat.com>
ae23c9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
ae23c9
(cherry picked from commit 230ff73904e72dde2d7718c2da407786a1c72e57)
ae23c9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
ae23c9
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
ae23c9
---
ae23c9
 block/file-posix.c | 39 +++++++++++++++++++++++++++++++--------
ae23c9
 qemu-doc.texi      |  6 ++++++
ae23c9
 2 files changed, 37 insertions(+), 8 deletions(-)
ae23c9
ae23c9
diff --git a/block/file-posix.c b/block/file-posix.c
ae23c9
index 24c2367..06ec67d 100644
ae23c9
--- a/block/file-posix.c
ae23c9
+++ b/block/file-posix.c
ae23c9
@@ -431,7 +431,8 @@ static QemuOptsList raw_runtime_opts = {
ae23c9
 };
ae23c9
 
ae23c9
 static int raw_open_common(BlockDriverState *bs, QDict *options,
ae23c9
-                           int bdrv_flags, int open_flags, Error **errp)
ae23c9
+                           int bdrv_flags, int open_flags,
ae23c9
+                           bool device, Error **errp)
ae23c9
 {
ae23c9
     BDRVRawState *s = bs->opaque;
ae23c9
     QemuOpts *opts;
ae23c9
@@ -569,10 +570,32 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
ae23c9
         error_setg_errno(errp, errno, "Could not stat file");
ae23c9
         goto fail;
ae23c9
     }
ae23c9
-    if (S_ISREG(st.st_mode)) {
ae23c9
-        s->discard_zeroes = true;
ae23c9
-        s->has_fallocate = true;
ae23c9
+
ae23c9
+    if (!device) {
ae23c9
+        if (S_ISBLK(st.st_mode)) {
ae23c9
+            warn_report("Opening a block device as a file using the '%s' "
ae23c9
+                        "driver is deprecated", bs->drv->format_name);
ae23c9
+        } else if (S_ISCHR(st.st_mode)) {
ae23c9
+            warn_report("Opening a character device as a file using the '%s' "
ae23c9
+                        "driver is deprecated", bs->drv->format_name);
ae23c9
+        } else if (!S_ISREG(st.st_mode)) {
ae23c9
+            error_setg(errp, "A regular file was expected by the '%s' driver, "
ae23c9
+                       "but something else was given", bs->drv->format_name);
ae23c9
+            ret = -EINVAL;
ae23c9
+            goto fail;
ae23c9
+        } else {
ae23c9
+            s->discard_zeroes = true;
ae23c9
+            s->has_fallocate = true;
ae23c9
+        }
ae23c9
+    } else {
ae23c9
+        if (!(S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
ae23c9
+            error_setg(errp, "'%s' driver expects either "
ae23c9
+                       "a character or block device", bs->drv->format_name);
ae23c9
+            ret = -EINVAL;
ae23c9
+            goto fail;
ae23c9
+        }
ae23c9
     }
ae23c9
+
ae23c9
     if (S_ISBLK(st.st_mode)) {
ae23c9
 #ifdef BLKDISCARDZEROES
ae23c9
         unsigned int arg;
ae23c9
@@ -625,7 +648,7 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
ae23c9
     BDRVRawState *s = bs->opaque;
ae23c9
 
ae23c9
     s->type = FTYPE_FILE;
ae23c9
-    return raw_open_common(bs, options, flags, 0, errp);
ae23c9
+    return raw_open_common(bs, options, flags, 0, false, errp);
ae23c9
 }
ae23c9
 
ae23c9
 typedef enum {
ae23c9
@@ -2794,7 +2817,7 @@ hdev_open_Mac_error:
ae23c9
 
ae23c9
     s->type = FTYPE_FILE;
ae23c9
 
ae23c9
-    ret = raw_open_common(bs, options, flags, 0, &local_err);
ae23c9
+    ret = raw_open_common(bs, options, flags, 0, true, &local_err);
ae23c9
     if (ret < 0) {
ae23c9
         error_propagate(errp, local_err);
ae23c9
 #if defined(__APPLE__) && defined(__MACH__)
ae23c9
@@ -3023,7 +3046,7 @@ static int cdrom_open(BlockDriverState *bs, QDict *options, int flags,
ae23c9
     s->type = FTYPE_CD;
ae23c9
 
ae23c9
     /* open will not fail even if no CD is inserted, so add O_NONBLOCK */
ae23c9
-    return raw_open_common(bs, options, flags, O_NONBLOCK, errp);
ae23c9
+    return raw_open_common(bs, options, flags, O_NONBLOCK, true, errp);
ae23c9
 }
ae23c9
 
ae23c9
 static int cdrom_probe_device(const char *filename)
ae23c9
@@ -3136,7 +3159,7 @@ static int cdrom_open(BlockDriverState *bs, QDict *options, int flags,
ae23c9
 
ae23c9
     s->type = FTYPE_CD;
ae23c9
 
ae23c9
-    ret = raw_open_common(bs, options, flags, 0, &local_err);
ae23c9
+    ret = raw_open_common(bs, options, flags, 0, true, &local_err);
ae23c9
     if (ret) {
ae23c9
         error_propagate(errp, local_err);
ae23c9
         return ret;
ae23c9
diff --git a/qemu-doc.texi b/qemu-doc.texi
ae23c9
index de5097a..985e0f2 100644
ae23c9
--- a/qemu-doc.texi
ae23c9
+++ b/qemu-doc.texi
ae23c9
@@ -2938,6 +2938,12 @@ The @code{-startdate} option has been replaced by @code{-rtc base=@var{date}}.
ae23c9
 The ``convert -s snapshot_id_or_name'' argument is obsoleted
ae23c9
 by the ``convert -l snapshot_param'' argument instead.
ae23c9
 
ae23c9
+@subsection -drive file=json:@{...@{'driver':'file'@}@} (since 3.0)
ae23c9
+
ae23c9
+The 'file' driver for drives is no longer appropriate for character or host
ae23c9
+devices and will only accept regular files (S_IFREG). The correct driver
ae23c9
+for these file types is 'host_cdrom' or 'host_device' as appropriate.
ae23c9
+
ae23c9
 @section QEMU Machine Protocol (QMP) commands
ae23c9
 
ae23c9
 @subsection block-dirty-bitmap-add "autoload" parameter (since 2.12.0)
ae23c9
-- 
ae23c9
1.8.3.1
ae23c9