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