Blame SOURCES/kvm-file-posix-specify-expected-filetypes.patch

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