1. 17 7月, 2020 1 次提交
    • K
      block: Require aligned image size to avoid assertion failure · 9c60a5d1
      Kevin Wolf 提交于
      Unaligned requests will automatically be aligned to bl.request_alignment
      and we can't extend write requests to access space beyond the end of the
      image without resizing the image, so if we have the WRITE permission,
      but not the RESIZE one, it's required that the image size is aligned.
      
      Failing to meet this requirement could cause assertion failures like
      this if RESIZE permissions weren't requested:
      
      qemu-img: block/io.c:1910: bdrv_co_write_req_prepare: Assertion `end_sector <= bs->total_sectors || child->perm & BLK_PERM_RESIZE' failed.
      
      This was e.g. triggered by qemu-img converting to a target image with 4k
      request alignment when the image was only aligned to 512 bytes, but not
      to 4k.
      
      Turn this into a graceful error in bdrv_check_perm() so that WRITE
      without RESIZE can only be taken if the image size is aligned. If a user
      holds both permissions and drops only RESIZE, the function will return
      an error, but bdrv_child_try_set_perm() will ignore the failure silently
      if permissions are only requested to be relaxed and just keep both
      permissions while returning success.
      Signed-off-by: NKevin Wolf <kwolf@redhat.com>
      Message-Id: <20200716142601.111237-2-kwolf@redhat.com>
      Reviewed-by: NMax Reitz <mreitz@redhat.com>
      Signed-off-by: NKevin Wolf <kwolf@redhat.com>
      9c60a5d1
  2. 14 7月, 2020 4 次提交
    • E
      qemu-img: Deprecate use of -b without -F · d9f059aa
      Eric Blake 提交于
      Creating an image that requires format probing of the backing image is
      potentially unsafe (we've had several CVEs over the years based on
      probes leaking information to the guest on a subsequent boot, although
      these days tools like libvirt are aware of the issue enough to prevent
      the worst effects).  For example, if our probing algorithm ever
      changes, or if other tools like libvirt determine a different probe
      result than we do, then subsequent use of that backing file under a
      different format will present corrupted data to the guest.
      Fortunately, the worst effects occur only when the backing image is
      originally raw, and we at least prevent commit into a probed raw
      backing file that would change its probed type.
      
      Still, it is worth starting a deprecation clock so that future
      qemu-img can refuse to create backing chains that would rely on
      probing, to encourage clients to avoid unsafe practices.  Most
      warnings are intentionally emitted from bdrv_img_create() in the block
      layer, but qemu-img convert uses bdrv_create() which cannot emit its
      own warning without causing spurious warnings on other code paths.  In
      the end, all command-line image creation or backing file rewriting now
      performs a check.
      
      Furthermore, if we probe a backing file as non-raw, then it is safe to
      explicitly record that result (rather than relying on future probes);
      only where we probe a raw image do we care about further warnings to
      the user when using such an image (for example, commits into a
      probed-raw backing file are prevented), to help them improve their
      tooling.  But whether or not we make the probe results explicit, we
      still warn the user to remind them to upgrade their workflow to supply
      -F always.
      
      iotest 114 specifically wants to create an unsafe image for later
      amendment rather than defaulting to our new default of recording a
      probed format, so it needs an update.  While touching it, expand it to
      cover all of the various warnings enabled by this patch.  iotest 301
      also shows a change to qcow messages.
      Signed-off-by: NEric Blake <eblake@redhat.com>
      Message-Id: <20200706203954.341758-11-eblake@redhat.com>
      Signed-off-by: NKevin Wolf <kwolf@redhat.com>
      d9f059aa
    • E
      block: Add support to warn on backing file change without format · e54ee1b3
      Eric Blake 提交于
      For now, this is a mechanical addition; all callers pass false. But
      the next patch will use it to improve 'qemu-img rebase -u' when
      selecting a backing file with no format.
      Signed-off-by: NEric Blake <eblake@redhat.com>
      Reviewed-by: NPeter Krempa <pkrempa@redhat.com>
      Reviewed-by: NJán Tomko <jtomko@redhat.com>
      Message-Id: <20200706203954.341758-10-eblake@redhat.com>
      Signed-off-by: NKevin Wolf <kwolf@redhat.com>
      e54ee1b3
    • E
      block: Error if backing file fails during creation without -u · add8200d
      Eric Blake 提交于
      Back in commit 6e6e55f5 (Jul 2017, v2.10), we tweaked the code to warn
      if the backing file could not be opened but the user gave a size,
      unless the user also passes the -u option to bypass the open of the
      backing file.  As one common reason for failure to open the backing
      file is when there is mismatch in the requested backing format in
      relation to what the backing file actually contains, we actually want
      to open the backing file and ensure that it has the right format in as
      many cases as possible.  iotest 301 for qcow demonstrates how
      detecting explicit format mismatch is useful to prevent the creation
      of an image that would probe differently than the user requested.  Now
      is the time to finally turn the warning an error, as promised.
      
      Note that the original warning was added prior to our documentation of
      an official deprecation policy (eb22aeca, also Jul 2017), and because
      the warning didn't mention the word "deprecated", we never actually
      remembered to document it as such.  But the warning has been around
      long enough that I don't see prolonging it another two releases.
      Signed-off-by: NEric Blake <eblake@redhat.com>
      Message-Id: <20200706203954.341758-7-eblake@redhat.com>
      Signed-off-by: NKevin Wolf <kwolf@redhat.com>
      add8200d
    • E
      qemu-img: Flush stdout before before potential stderr messages · 4e2f4418
      Eric Blake 提交于
      During 'qemu-img create ... 2>&1', if --quiet is not in force, we can
      end up with buffered I/O in stdout that was produced before failure,
      but which appears in output after failure.  This is confusing; the fix
      is to flush stdout prior to attempting anything that might produce an
      error message.  Several iotests demonstrate the resulting ordering
      change now that the merged outputs now reflect chronology.  (An even
      better fix would be to avoid printf from within block.c altogether,
      but that's much more invasive...)
      Signed-off-by: NEric Blake <eblake@redhat.com>
      Message-Id: <20200706203954.341758-2-eblake@redhat.com>
      Signed-off-by: NKevin Wolf <kwolf@redhat.com>
      4e2f4418
  3. 10 7月, 2020 5 次提交
    • M
      error: Reduce unnecessary error propagation · a5f9b9df
      Markus Armbruster 提交于
      When all we do with an Error we receive into a local variable is
      propagating to somewhere else, we can just as well receive it there
      right away, even when we need to keep error_propagate() for other
      error paths.
      Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
      Reviewed-by: NEric Blake <eblake@redhat.com>
      Message-Id: <20200707160613.848843-38-armbru@redhat.com>
      a5f9b9df
    • M
      error: Eliminate error_propagate() with Coccinelle, part 2 · af175e85
      Markus Armbruster 提交于
      When all we do with an Error we receive into a local variable is
      propagating to somewhere else, we can just as well receive it there
      right away.  The previous commit did that with a Coccinelle script I
      consider fairly trustworthy.  This commit uses the same script with
      the matching of return taken out, i.e. we convert
      
          if (!foo(..., &err)) {
              ...
              error_propagate(errp, err);
              ...
          }
      
      to
      
          if (!foo(..., errp)) {
              ...
              ...
          }
      
      This is unsound: @err could still be read between afterwards.  I don't
      know how to express "no read of @err without an intervening write" in
      Coccinelle.  Instead, I manually double-checked for uses of @err.
      
      Suboptimal line breaks tweaked manually.  qdev_realize() simplified
      further to placate scripts/checkpatch.pl.
      Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
      Reviewed-by: NEric Blake <eblake@redhat.com>
      Message-Id: <20200707160613.848843-36-armbru@redhat.com>
      af175e85
    • M
      error: Eliminate error_propagate() with Coccinelle, part 1 · 668f62ec
      Markus Armbruster 提交于
      When all we do with an Error we receive into a local variable is
      propagating to somewhere else, we can just as well receive it there
      right away.  Convert
      
          if (!foo(..., &err)) {
              ...
              error_propagate(errp, err);
              ...
              return ...
          }
      
      to
      
          if (!foo(..., errp)) {
              ...
              ...
              return ...
          }
      
      where nothing else needs @err.  Coccinelle script:
      
          @rule1 forall@
          identifier fun, err, errp, lbl;
          expression list args, args2;
          binary operator op;
          constant c1, c2;
          symbol false;
          @@
               if (
          (
          -        fun(args, &err, args2)
          +        fun(args, errp, args2)
          |
          -        !fun(args, &err, args2)
          +        !fun(args, errp, args2)
          |
          -        fun(args, &err, args2) op c1
          +        fun(args, errp, args2) op c1
          )
                  )
               {
                   ... when != err
                       when != lbl:
                       when strict
          -        error_propagate(errp, err);
                   ... when != err
          (
                   return;
          |
                   return c2;
          |
                   return false;
          )
               }
      
          @rule2 forall@
          identifier fun, err, errp, lbl;
          expression list args, args2;
          expression var;
          binary operator op;
          constant c1, c2;
          symbol false;
          @@
          -    var = fun(args, &err, args2);
          +    var = fun(args, errp, args2);
               ... when != err
               if (
          (
                   var
          |
                   !var
          |
                   var op c1
          )
                  )
               {
                   ... when != err
                       when != lbl:
                       when strict
          -        error_propagate(errp, err);
                   ... when != err
          (
                   return;
          |
                   return c2;
          |
                   return false;
          |
                   return var;
          )
               }
      
          @depends on rule1 || rule2@
          identifier err;
          @@
          -    Error *err = NULL;
               ... when != err
      
      Not exactly elegant, I'm afraid.
      
      The "when != lbl:" is necessary to avoid transforming
      
               if (fun(args, &err)) {
                   goto out
               }
               ...
           out:
               error_propagate(errp, err);
      
      even though other paths to label out still need the error_propagate().
      For an actual example, see sclp_realize().
      
      Without the "when strict", Coccinelle transforms vfio_msix_setup(),
      incorrectly.  I don't know what exactly "when strict" does, only that
      it helps here.
      
      The match of return is narrower than what I want, but I can't figure
      out how to express "return where the operand doesn't use @err".  For
      an example where it's too narrow, see vfio_intx_enable().
      
      Silently fails to convert hw/arm/armsse.c, because Coccinelle gets
      confused by ARMSSE being used both as typedef and function-like macro
      there.  Converted manually.
      
      Line breaks tidied up manually.  One nested declaration of @local_err
      deleted manually.  Preexisting unwanted blank line dropped in
      hw/riscv/sifive_e.c.
      Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
      Reviewed-by: NEric Blake <eblake@redhat.com>
      Message-Id: <20200707160613.848843-35-armbru@redhat.com>
      668f62ec
    • M
      block: Avoid error accumulation in bdrv_img_create() · 3882578b
      Markus Armbruster 提交于
      When creating an image fails because the format doesn't support option
      "backing_file" or "backing_fmt", bdrv_img_create() first has
      qemu_opt_set() put a generic error into @local_err, then puts the real
      error into @errp with error_setg(), and then propagates the former to
      the latter, which throws away the generic error.  A bit complicated,
      but works.
      
      Now that qemu_opt_set() returns a useful value, we can simply ignore
      the generic error instead.
      Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
      Reviewed-by: NEric Blake <eblake@redhat.com>
      Reviewed-by: NVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
      Message-Id: <20200707160613.848843-16-armbru@redhat.com>
      3882578b
    • M
      qemu-option: Use returned bool to check for failure · 235e59cf
      Markus Armbruster 提交于
      The previous commit enables conversion of
      
          foo(..., &err);
          if (err) {
              ...
          }
      
      to
      
          if (!foo(..., &err)) {
              ...
          }
      
      for QemuOpts functions that now return true / false on success /
      error.  Coccinelle script:
      
          @@
          identifier fun = {
              opts_do_parse, parse_option_bool, parse_option_number,
              parse_option_size, qemu_opt_parse, qemu_opt_rename, qemu_opt_set,
              qemu_opt_set_bool, qemu_opt_set_number, qemu_opts_absorb_qdict,
              qemu_opts_do_parse, qemu_opts_from_qdict_entry, qemu_opts_set,
              qemu_opts_validate
          };
          expression list args, args2;
          typedef Error;
          Error *err;
          @@
          -    fun(args, &err, args2);
          -    if (err)
          +    if (!fun(args, &err, args2))
               {
                   ...
               }
      
      A few line breaks tidied up manually.
      Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
      Reviewed-by: NEric Blake <eblake@redhat.com>
      Reviewed-by: NVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
      Message-Id: <20200707160613.848843-15-armbru@redhat.com>
      [Conflict with commit 0b6786a9 "block/amend: refactor qcow2 amend
      options" resolved by rerunning Coccinelle on master's version]
      235e59cf
  4. 06 7月, 2020 2 次提交
  5. 11 6月, 2020 1 次提交
    • E
      block: Call attention to truncation of long NBD exports · 5c86bdf1
      Eric Blake 提交于
      Commit 93676c88 relaxed our NBD client code to request export names up
      to the NBD protocol maximum of 4096 bytes without NUL terminator, even
      though the block layer can't store anything longer than 4096 bytes
      including NUL terminator for display to the user.  Since this means
      there are some export names where we have to truncate things, we can
      at least try to make the truncation a bit more obvious for the user.
      Note that in spite of the truncated display name, we can still
      communicate with an NBD server using such a long export name; this was
      deemed nicer than refusing to even connect to such a server (since the
      server may not be under our control, and since determining our actual
      length limits gets tricky when nbd://host:port/export and
      nbd+unix:///export?socket=/path are themselves variable-length
      expansions beyond the export name but count towards the block layer
      name length).
      Reported-by: NXueqiang Wei <xuwei@redhat.com>
      Fixes: https://bugzilla.redhat.com/1843684Signed-off-by: NEric Blake <eblake@redhat.com>
      Reviewed-by: NVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
      Message-Id: <20200610163741.3745251-3-eblake@redhat.com>
      5c86bdf1
  6. 19 5月, 2020 25 次提交
  7. 08 5月, 2020 1 次提交
    • E
      block: Drop unused .bdrv_has_zero_init_truncate · 47e0b38a
      Eric Blake 提交于
      Now that there are no clients of bdrv_has_zero_init_truncate, none of
      the drivers need to worry about providing it.
      
      What's more, this eliminates a source of some confusion: a literal
      reading of the documentation as written in ceaca56f and implemented in
      commit 1dcaf527 claims that a driver which returns 0 for
      bdrv_has_zero_init_truncate() must not return 1 for
      bdrv_has_zero_init(); this condition was violated for parallels, qcow,
      and sometimes for vdi, although in practice it did not matter since
      those drivers also lacked .bdrv_co_truncate.
      Signed-off-by: NEric Blake <eblake@redhat.com>
      Message-Id: <20200428202905.770727-10-eblake@redhat.com>
      Acked-by: NRichard W.M. Jones <rjones@redhat.com>
      Signed-off-by: NKevin Wolf <kwolf@redhat.com>
      47e0b38a
  8. 04 5月, 2020 1 次提交