Skip to content
Snippets Groups Projects
  1. Nov 17, 2020
  2. Nov 16, 2020
    • Eric Blake's avatar
      nbd: Silence Coverity false positive · c0b21f2e
      Eric Blake authored
      
      Coverity noticed (CID 1436125) that we check the return value of
      nbd_extent_array_add in most places, but not at the end of
      bitmap_to_extents().  The return value exists to break loops before a
      future iteration, so there is nothing to check if we are already done
      iterating.  Adding a cast to void, plus a comment why, pacifies
      Coverity.
      
      Signed-off-by: default avatarEric Blake <eblake@redhat.com>
      Message-Id: <20201111163510.713855-1-eblake@redhat.com>
      [eblake: Prefer cast to void over odd && usage]
      Reviewed-by: default avatarRichard Henderson <richard.henderson@linaro.org>
      c0b21f2e
  3. Oct 30, 2020
    • Eric Blake's avatar
      nbd: Add 'qemu-nbd -A' to expose allocation depth · dbc7b014
      Eric Blake authored
      
      Allow the server to expose an additional metacontext to be requested
      by savvy clients.  qemu-nbd adds a new option -A to expose the
      qemu:allocation-depth metacontext through NBD_CMD_BLOCK_STATUS; this
      can also be set via QMP when using block-export-add.
      
      qemu as client is hacked into viewing the key aspects of this new
      context by abusing the already-experimental x-dirty-bitmap option to
      collapse all depths greater than 2, which results in a tri-state value
      visible in the output of 'qemu-img map --output=json' (yes, that means
      x-dirty-bitmap is now a bit of a misnomer, but I didn't feel like
      renaming it as it would introduce a needless break of back-compat,
      even though we make no compat guarantees with x- members):
      
      unallocated (depth 0) => "zero":false, "data":true
      local (depth 1)       => "zero":false, "data":false
      backing (depth 2+)    => "zero":true,  "data":true
      
      libnbd as client is probably a nicer way to get at the information
      without having to decipher such hacks in qemu as client. ;)
      
      Signed-off-by: default avatarEric Blake <eblake@redhat.com>
      Message-Id: <20201027050556.269064-11-eblake@redhat.com>
      Reviewed-by: default avatarVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
      dbc7b014
    • Eric Blake's avatar
      nbd: Add new qemu:allocation-depth metadata context · 71719cd5
      Eric Blake authored
      
      'qemu-img map' provides a way to determine which extents of an image
      come from the top layer vs. inherited from a backing chain.  This is
      useful information worth exposing over NBD.  There is a proposal to
      add a QMP command block-dirty-bitmap-populate which can create a dirty
      bitmap that reflects allocation information, at which point the
      qemu:dirty-bitmap:NAME metadata context can expose that information
      via the creation of a temporary bitmap, but we can shorten the effort
      by adding a new qemu:allocation-depth metadata context that does the
      same thing without an intermediate bitmap (this patch does not
      eliminate the need for that proposal, as it will have other uses as
      well).
      
      While documenting things, remember that although the NBD protocol has
      NBD_OPT_SET_META_CONTEXT, the rest of its documentation refers to
      'metadata context', which is a more apt description of what is
      actually being used by NBD_CMD_BLOCK_STATUS: the user is requesting
      metadata by passing one or more context names.  So I also touched up
      some existing wording to prefer the term 'metadata context' where it
      makes sense.
      
      Note that this patch does not actually enable any way to request a
      server to enable this context; that will come in the next patch.
      
      Signed-off-by: default avatarEric Blake <eblake@redhat.com>
      Message-Id: <20201027050556.269064-10-eblake@redhat.com>
      Reviewed-by: default avatarVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
      71719cd5
    • Eric Blake's avatar
      nbd: Allow export of multiple bitmaps for one device · 3b1f244c
      Eric Blake authored
      
      With this, 'qemu-nbd -B b0 -B b1 -f qcow2 img.qcow2' can let you sniff
      out multiple bitmaps from one server.  qemu-img as client can still
      only read one bitmap per client connection, but other NBD clients
      (hello libnbd) can now read multiple bitmaps in a single pass.
      
      Signed-off-by: default avatarEric Blake <eblake@redhat.com>
      Reviewed-by: default avatarVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
      Message-Id: <20201027050556.269064-8-eblake@redhat.com>
      3b1f244c
    • Eric Blake's avatar
      nbd: Refactor counting of metadata contexts · 47ec485e
      Eric Blake authored
      
      Rather than open-code the count of negotiated contexts at several
      sites, embed it directly into the struct.  This will make it easier
      for upcoming commits to support even more simultaneous contexts.
      
      Signed-off-by: default avatarEric Blake <eblake@redhat.com>
      Message-Id: <20201027050556.269064-7-eblake@redhat.com>
      Reviewed-by: default avatarVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
      47ec485e
    • Eric Blake's avatar
      nbd: Simplify qemu bitmap context name · 02e87e3b
      Eric Blake authored
      
      Each dirty bitmap already knows its name; by reducing the scope of the
      places where we construct "qemu:dirty-bitmap:NAME" strings, tracking
      the name is more localized, and there are fewer per-export fields to
      worry about.  This in turn will make it easier for an upcoming patch
      to export more than one bitmap at once.
      
      Signed-off-by: default avatarEric Blake <eblake@redhat.com>
      Reviewed-by: default avatarVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
      Message-Id: <20201027050556.269064-6-eblake@redhat.com>
      02e87e3b
    • Eric Blake's avatar
      nbd: Update qapi to support exporting multiple bitmaps · cbad81ce
      Eric Blake authored
      
      Since 'block-export-add' is new to 5.2, we can still tweak the
      interface; there, allowing 'bitmaps':['str'] is nicer than
      'bitmap':'str'.  This wires up the qapi and qemu-nbd changes to permit
      passing multiple bitmaps as distinct metadata contexts that the NBD
      client may request, but the actual support for more than one will
      require a further patch to the server.
      
      Note that there are no changes made to the existing deprecated
      'nbd-server-add' command; this required splitting the QAPI type
      BlockExportOptionsNbd, which fortunately does not affect QMP
      introspection.
      
      Signed-off-by: default avatarEric Blake <eblake@redhat.com>
      Message-Id: <20201027050556.269064-5-eblake@redhat.com>
      Reviewed-by: default avatarVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
      Reviewed-by: default avatarPeter Krempa <pkrempa@redhat.com>
      cbad81ce
  4. Oct 23, 2020
    • Stefan Hajnoczi's avatar
      block/export: add iothread and fixed-iothread options · f51d23c8
      Stefan Hajnoczi authored
      
      Make it possible to specify the iothread where the export will run. By
      default the block node can be moved to other AioContexts later and the
      export will follow. The fixed-iothread option forces strict behavior
      that prevents changing AioContext while the export is active. See the
      QAPI docs for details.
      
      Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
      Message-id: 20200929125516.186715-5-stefanha@redhat.com
      [Fix stray '#' character in block-export.json and add missing "(since:
      5.2)" as suggested by Eric Blake.
      --Stefan]
      Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
      f51d23c8
    • Stefan Hajnoczi's avatar
      block: move block exports to libblockdev · cbc20bfb
      Stefan Hajnoczi authored
      
      Block exports are used by softmmu, qemu-storage-daemon, and qemu-nbd.
      They are not used by other programs and are not otherwise needed in
      libblock.
      
      Undo the recent move of blockdev-nbd.c from blockdev_ss into block_ss.
      Since bdrv_close_all() (libblock) calls blk_exp_close_all()
      (libblockdev) a stub function is required..
      
      Make qemu-nbd.c use signal handling utility functions instead of
      duplicating the code. This helps because os-posix.c is in libblockdev
      and it depends on a qemu_system_killed() symbol that qemu-nbd.c lacks.
      Once we use the signal handling utility functions we also end up
      providing the necessary symbol.
      
      Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
      Reviewed-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
      Reviewed-by: default avatarEric Blake <eblake@redhat.com>
      Message-id: 20200929125516.186715-4-stefanha@redhat.com
      [Fixed s/ndb/nbd/ typo in commit description as suggested by Eric Blake
      --Stefan]
      Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
      cbc20bfb
  5. Oct 09, 2020
    • Eric Blake's avatar
      nbd: Simplify meta-context parsing · ebd57062
      Eric Blake authored
      
      We had a premature optimization of trying to read as little from the
      wire as possible while handling NBD_OPT_SET_META_CONTEXT in phases.
      But in reality, we HAVE to read the entire string from the client
      before we can get to the next command, and it is easier to just read
      it all at once than it is to read it in pieces.  And once we do that,
      several functions end up no longer performing I/O, so they can drop
      length and errp parameters, and just return a bool instead of
      modifying through a pointer.
      
      Our iotests still pass; I also checked that libnbd's testsuite (which
      covers more corner cases of odd meta context requests) still passes.
      There are cases where the sequence of trace messages produced differs
      (for example, when no bitmap is exported, a query for "qemu:" now
      produces two trace lines instead of one), but trace points are for
      debug and have no effect on what the client sees.
      
      Signed-off-by: default avatarEric Blake <eblake@redhat.com>
      Message-Id: <20200930121105.667049-4-eblake@redhat.com>
      Reviewed-by: default avatarVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
      [eblake: enhance commit message]
      Signed-off-by: default avatarEric Blake <eblake@redhat.com>
      ebd57062
    • Eric Blake's avatar
      nbd/server: Reject embedded NUL in NBD strings · d1e2c3e7
      Eric Blake authored
      
      The NBD spec is clear that any string sent from the client must not
      contain embedded NUL characters.  If the client passes "a\0", we
      should reject that option request rather than act on "a".
      
      Testing this is not possible with a compliant client, but I was able
      to use gdb to coerce libnbd into temporarily behaving as such a
      client.
      
      Signed-off-by: default avatarEric Blake <eblake@redhat.com>
      Message-Id: <20200930121105.667049-3-eblake@redhat.com>
      Reviewed-by: default avatarVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
      Signed-off-by: default avatarEric Blake <eblake@redhat.com>
      d1e2c3e7
    • Christian Borntraeger's avatar
      nbd: silence maybe-uninitialized warnings · bbc35fc2
      Christian Borntraeger authored
      
      gcc 10 from Fedora 32 gives me:
      
      Compiling C object libblock.fa.p/nbd_server.c.o
      ../nbd/server.c: In function ‘nbd_co_client_start’:
      ../nbd/server.c:625:14: error: ‘namelen’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
        625 |         rc = nbd_negotiate_send_info(client, NBD_INFO_NAME, namelen, name,
            |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        626 |                                      errp);
            |                                      ~~~~~
      ../nbd/server.c:564:14: note: ‘namelen’ was declared here
        564 |     uint32_t namelen;
            |              ^~~~~~~
      cc1: all warnings being treated as errors
      
      As I cannot see how this can happen, let uns silence the warning.
      
      Signed-off-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
      Message-Id: <20200930155859.303148-3-borntraeger@de.ibm.com>
      Reviewed-by: default avatarEric Blake <eblake@redhat.com>
      Signed-off-by: default avatarEric Blake <eblake@redhat.com>
      bbc35fc2
  6. Oct 02, 2020
  7. Sep 07, 2020
  8. Aug 21, 2020
  9. Jul 28, 2020
    • Eric Blake's avatar
      nbd: Fix large trim/zero requests · 890cbccb
      Eric Blake authored
      Although qemu as NBD client limits requests to <2G, the NBD protocol
      allows clients to send requests almost all the way up to 4G.  But
      because our block layer is not yet 64-bit clean, we accidentally wrap
      such requests into a negative size, and fail with EIO instead of
      performing the intended operation.
      
      The bug is visible in modern systems with something as simple as:
      
      $ qemu-img create -f qcow2 /tmp/image.img 5G
      $ sudo qemu-nbd --connect=/dev/nbd0 /tmp/image.img
      $ sudo blkdiscard /dev/nbd0
      
      or with user-space only:
      
      $ truncate --size=3G file
      $ qemu-nbd -f raw file
      $ nbdsh -u nbd://localhost:10809 -c 'h.trim(3*1024*1024*1024,0)'
      
      Although both blk_co_pdiscard and blk_pwrite_zeroes currently return 0
      on success, this is also a good time to fix our code to a more robust
      paradigm that treats all non-negative values as success.
      
      Alas, our iotests do not currently make it easy to add external
      dependencies on blkdiscard or nbdsh, so we have to rely on manual
      testing for now.
      
      This patch can be reverted when we later improve the overall block
      layer to be 64-bit clean, but for now, a minimal fix was deemed less
      risky prior to release.
      
      CC: qemu-stable@nongnu.org
      Fixes: 1f4d6d18
      Fixes: 1c6c4bb7
      Fixes: https://github.com/systemd/systemd/issues/16242
      
      
      Signed-off-by: default avatarEric Blake <eblake@redhat.com>
      Message-Id: <20200722212231.535072-1-eblake@redhat.com>
      Reviewed-by: default avatarVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
      [eblake: rework success tests to use >=0]
      890cbccb
  10. Jul 17, 2020
    • Vladimir Sementsov-Ogievskiy's avatar
      nbd: make nbd_export_close_all() synchronous · 453cc6be
      Vladimir Sementsov-Ogievskiy authored
      
      Consider nbd_export_close_all(). The call-stack looks like this:
       nbd_export_close_all() -> nbd_export_close -> call client_close() for
      each client.
      
      client_close() doesn't guarantee that client is closed: nbd_trip()
      keeps reference to it. So, nbd_export_close_all() just reduce
      reference counter on export and removes it from the list, but doesn't
      guarantee that nbd_trip() finished neither export actually removed.
      
      Let's wait for all exports actually removed.
      
      Without this fix, the following crash is possible:
      
      - export bitmap through internal Qemu NBD server
      - connect a client
      - shutdown Qemu
      
      On shutdown nbd_export_close_all is called, but it actually don't wait
      for nbd_trip() to finish and to release its references. So, export is
      not release, and exported bitmap remains busy, and on try to remove the
      bitmap (which is part of bdrv_close()) the assertion fails:
      
      bdrv_release_dirty_bitmap_locked: Assertion `!bdrv_dirty_bitmap_busy(bitmap)' failed
      
      Signed-off-by: default avatarVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
      Reviewed-by: default avatarEric Blake <eblake@redhat.com>
      Message-Id: <20200714162234.13113-2-vsementsov@virtuozzo.com>
      Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
      453cc6be
  11. Jul 10, 2020
    • Vladimir Sementsov-Ogievskiy's avatar
      nbd: Use ERRP_GUARD() · 795d946d
      Vladimir Sementsov-Ogievskiy authored
      
      If we want to check error after errp-function call, we need to
      introduce local_err and then propagate it to errp. Instead, use
      the ERRP_GUARD() macro, benefits are:
      1. No need of explicit error_propagate call
      2. No need of explicit local_err variable: use errp directly
      3. ERRP_GUARD() leaves errp as is if it's not NULL or
         &error_fatal, this means that we don't break error_abort
         (we'll abort on error_set, not on error_propagate)
      
      If we want to add some info to errp (by error_prepend() or
      error_append_hint()), we must use the ERRP_GUARD() macro.
      Otherwise, this info will not be added when errp == &error_fatal
      (the program will exit prior to the error_append_hint() or
      error_prepend() call).  Fix several such cases, e.g. in nbd_read().
      
      This commit is generated by command
      
          sed -n '/^Network Block Device (NBD)$/,/^$/{s/^F: //p}' \
              MAINTAINERS | \
          xargs git ls-files | grep '\.[hc]$' | \
          xargs spatch \
              --sp-file scripts/coccinelle/errp-guard.cocci \
              --macro-file scripts/cocci-macro-file.h \
              --in-place --no-show-diff --max-width 80
      
      Reported-by: default avatarKevin Wolf <kwolf@redhat.com>
      Reported-by: default avatarGreg Kurz <groug@kaod.org>
      Signed-off-by: default avatarVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
      Reviewed-by: default avatarMarkus Armbruster <armbru@redhat.com>
      [Commit message tweaked]
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Message-Id: <20200707165037.1026246-8-armbru@redhat.com>
      Reviewed-by: default avatarEric Blake <eblake@redhat.com>
      [ERRP_AUTO_PROPAGATE() renamed to ERRP_GUARD(), and
      auto-propagated-errp.cocci to errp-guard.cocci.  Commit message
      tweaked again.]
      795d946d
  12. Jun 10, 2020
    • Eric Blake's avatar
      nbd/server: Avoid long error message assertions CVE-2020-10761 · 5c4fe018
      Eric Blake authored
      
      Ever since commit 36683283 (v2.8), the server code asserts that error
      strings sent to the client are well-formed per the protocol by not
      exceeding the maximum string length of 4096.  At the time the server
      first started sending error messages, the assertion could not be
      triggered, because messages were completely under our control.
      However, over the years, we have added latent scenarios where a client
      could trigger the server to attempt an error message that would
      include the client's information if it passed other checks first:
      
      - requesting NBD_OPT_INFO/GO on an export name that is not present
        (commit 0cfae925 in v2.12 echoes the name)
      
      - requesting NBD_OPT_LIST/SET_META_CONTEXT on an export name that is
        not present (commit e7b1948d in v2.12 echoes the name)
      
      At the time, those were still safe because we flagged names larger
      than 256 bytes with a different message; but that changed in commit
      93676c88 (v4.2) when we raised the name limit to 4096 to match the NBD
      string limit.  (That commit also failed to change the magic number
      4096 in nbd_negotiate_send_rep_err to the just-introduced named
      constant.)  So with that commit, long client names appended to server
      text can now trigger the assertion, and thus be used as a denial of
      service attack against a server.  As a mitigating factor, if the
      server requires TLS, the client cannot trigger the problematic paths
      unless it first supplies TLS credentials, and such trusted clients are
      less likely to try to intentionally crash the server.
      
      We may later want to further sanitize the user-supplied strings we
      place into our error messages, such as scrubbing out control
      characters, but that is less important to the CVE fix, so it can be a
      later patch to the new nbd_sanitize_name.
      
      Consideration was given to changing the assertion in
      nbd_negotiate_send_rep_verr to instead merely log a server error and
      truncate the message, to avoid leaving a latent path that could
      trigger a future CVE DoS on any new error message.  However, this
      merely complicates the code for something that is already (correctly)
      flagging coding errors, and now that we are aware of the long message
      pitfall, we are less likely to introduce such errors in the future,
      which would make such error handling dead code.
      
      Reported-by: default avatarXueqiang Wei <xuwei@redhat.com>
      CC: qemu-stable@nongnu.org
      Fixes: https://bugzilla.redhat.com/1843684
      
       CVE-2020-10761
      Fixes: 93676c88
      Signed-off-by: default avatarEric Blake <eblake@redhat.com>
      Message-Id: <20200610163741.3745251-2-eblake@redhat.com>
      Reviewed-by: default avatarVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
      5c4fe018
  13. Mar 18, 2020
  14. Feb 26, 2020
    • Eric Blake's avatar
      nbd: Fix regression with multiple meta contexts · 73e064cc
      Eric Blake authored
      
      Detected by a hang in the libnbd testsuite.  If a client requests
      multiple meta contexts (both base:allocation and qemu:dirty-bitmap:x)
      at the same time, our attempt to silence a false-positive warning
      about a potential uninitialized variable introduced botched logic: we
      were short-circuiting the second context, and never sending the
      NBD_REPLY_FLAG_DONE.  Combining two 'if' into one 'if/else' in
      bdf200a5 was wrong (I'm a bit embarrassed that such a change was my
      initial suggestion after the v1 patch, then I did not review the v2
      patch that actually got committed). Revert that, and instead silence
      the false positive warning by replacing 'return ret' with 'return 0'
      (the value it always has at that point in the code, even though it
      eluded the deduction abilities of the robot that reported the false
      positive).
      
      Fixes: bdf200a5
      Signed-off-by: default avatarEric Blake <eblake@redhat.com>
      Message-Id: <20200206173832.130004-1-eblake@redhat.com>
      Reviewed-by: default avatarLaurent Vivier <laurent@vivier.eu>
      73e064cc
Loading