qemu-patch-raspberry4/block
Eric Blake 72b6ffc766 nbd-client: Fix regression when server sends garbage
When we switched NBD to use coroutines for qemu 2.9 (in particular,
commit a12a712a), we introduced a regression: if a server sends us
garbage (such as a corrupted magic number), we quit the read loop
but do not stop sending further queued commands, resulting in the
client hanging when it never reads the response to those additional
commands.  In qemu 2.8, we properly detected that the server is no
longer reliable, and cancelled all existing pending commands with
EIO, then tore down the socket so that all further command attempts
get EPIPE.

Restore the proper behavior of quitting (almost) all communication
with a broken server: Once we know we are out of sync or otherwise
can't trust the server, we must assume that any further incoming
data is unreliable and therefore end all pending commands with EIO,
and quit trying to send any further commands.  As an exception, we
still (try to) send NBD_CMD_DISC to let the server know we are going
away (in part, because it is easier to do that than to further
refactor nbd_teardown_connection, and in part because it is the
only command where we do not have to wait for a reply).

Based on a patch by Vladimir Sementsov-Ogievskiy.

A malicious server can be created with the following hack,
followed by setting NBD_SERVER_DEBUG to a non-zero value in the
environment when running qemu-nbd:

| --- a/nbd/server.c
| +++ b/nbd/server.c
| @@ -919,6 +919,17 @@ static int nbd_send_reply(QIOChannel *ioc, NBDReply *reply, Error **errp)
|      stl_be_p(buf + 4, reply->error);
|      stq_be_p(buf + 8, reply->handle);
|
| +    static int debug;
| +    static int count;
| +    if (!count++) {
| +        const char *str = getenv("NBD_SERVER_DEBUG");
| +        if (str) {
| +            debug = atoi(str);
| +        }
| +    }
| +    if (debug && !(count % debug)) {
| +        buf[0] = 0;
| +    }
|      return nbd_write(ioc, buf, sizeof(buf), errp);
|  }

Reported-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20170814213426.24681-1-eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
2017-08-15 10:03:28 -05:00
..
accounting.c block: make accounting thread-safe 2017-06-16 07:55:00 +08:00
backup.c Convert error_report() to warn_report() 2017-07-13 13:49:58 +02:00
blkdebug.c block: Add PreallocMode to bdrv_truncate() 2017-07-11 17:45:01 +02:00
blkreplay.c block: change variable names in BlockDriverState 2017-06-26 14:54:46 +02:00
blkverify.c blkverify: Catch bs->exact_filename overflow 2017-06-26 14:54:46 +02:00
block-backend.c block-backend: Defer shared_perm tightening migration completion 2017-08-15 10:03:28 -05:00
bochs.c block: do not set BDS read_only if copy_on_read enabled 2017-04-24 15:09:33 -04:00
cloop.c block: do not set BDS read_only if copy_on_read enabled 2017-04-24 15:09:33 -04:00
commit.c block: Skip implicit nodes in query-block/blockstats 2017-07-24 15:06:04 +02:00
crypto.c block: Add PreallocMode to bdrv_truncate() 2017-07-11 17:45:01 +02:00
crypto.h qcow: convert QCow to use QCryptoBlock for encryption 2017-07-11 17:44:56 +02:00
curl.c curl: do not do aio_poll when waiting for a free CURLState 2017-05-16 10:34:50 -04:00
dirty-bitmap.c dirty-bitmap: Report BlockDirtyInfo.count in bytes, as documented 2017-07-24 15:06:04 +02:00
dmg-bz2.c dmg: Move libbz2 code to dmg-bz2.so 2016-10-07 14:14:06 +02:00
dmg.c block: do not set BDS read_only if copy_on_read enabled 2017-04-24 15:09:33 -04:00
dmg.h dmg: Move libbz2 code to dmg-bz2.so 2016-10-07 14:14:06 +02:00
file-posix.c file-posix: Do runtime check for ofd lock API 2017-08-11 14:12:44 +02:00
file-win32.c block: Add PreallocMode to BD.bdrv_truncate() 2017-07-11 17:45:01 +02:00
gluster.c Error reporting patches for 2017-07-13 2017-07-14 09:36:40 +01:00
io.c block: move trace probes into bdrv_co_preadv|pwritev 2017-08-07 09:39:35 +01:00
iscsi-opts.c block/iscsi: statically link qemu_iscsi_opts 2017-01-27 18:07:58 +01:00
iscsi.c Error reporting patches for 2017-07-13 2017-07-14 09:36:40 +01:00
linux-aio.c block: explicitly acquire aiocontext in aio callbacks that need it 2017-02-21 11:39:39 +00:00
Makefile.objs qcow2: add bitmaps extension 2017-07-11 17:44:57 +02:00
mirror.c block: Skip implicit nodes in query-block/blockstats 2017-07-24 15:06:04 +02:00
nbd-client.c nbd-client: Fix regression when server sends garbage 2017-08-15 10:03:28 -05:00
nbd-client.h nbd-client: Fix regression when server sends garbage 2017-08-15 10:03:28 -05:00
nbd.c nbd: Implement NBD_INFO_BLOCK_SIZE on client 2017-07-14 12:04:42 +02:00
nfs.c block/nfs: fix mutex assertion in nfs_file_close() 2017-08-08 15:19:16 +02:00
null.c block/null: Remove 'filename' option 2017-08-08 15:19:16 +02:00
parallels.c parallels: drop check that bdrv_truncate() is working 2017-08-08 15:19:16 +02:00
qapi.c block/qapi: Remove redundant NULL check to silence Coverity 2017-08-01 18:09:33 +02:00
qcow.c qcow: fix memory leaks related to encryption 2017-07-25 16:33:31 +02:00
qcow2-bitmap.c qcow2-bitmap: fix bitmap_free 2017-07-25 16:33:31 +02:00
qcow2-cache.c qcow2: Remove stale comment 2016-11-25 13:51:30 +01:00
qcow2-cluster.c qcow2: add support for LUKS encryption format 2017-07-11 17:44:56 +02:00
qcow2-refcount.c qcow2: fix null pointer dereference 2017-07-31 13:06:38 +03:00
qcow2-snapshot.c qcow2: Discard/zero clusters by byte count 2017-05-11 14:28:07 +02:00
qcow2.c qcow2: Check failure of bdrv_getlength() 2017-08-11 13:23:47 +02:00
qcow2.h block/qcow2: falloc/full preallocating growth 2017-07-11 17:45:02 +02:00
qed-check.c qed: Use DIV_ROUND_UP 2016-06-07 18:19:24 +03:00
qed-cluster.c qed: protect table cache with CoMutex 2017-07-17 11:34:11 +08:00
qed-l2-cache.c qed: protect table cache with CoMutex 2017-07-17 11:34:11 +08:00
qed-table.c qed: protect table cache with CoMutex 2017-07-17 11:34:11 +08:00
qed.c qed: protect table cache with CoMutex 2017-07-17 11:34:11 +08:00
qed.h qed: protect table cache with CoMutex 2017-07-17 11:34:11 +08:00
quorum.c quorum: Set sectors-count to 0 when reporting a flush error 2017-08-08 14:37:00 +02:00
raw-format.c block: Add PreallocMode to bdrv_truncate() 2017-07-11 17:45:01 +02:00
rbd.c Error reporting patches for 2017-07-13 2017-07-14 09:36:40 +01:00
replication.c block: Make bdrv_is_allocated_above() byte-based 2017-07-10 13:18:07 +02:00
sheepdog.c sheepdog: add queue_lock 2017-07-17 11:34:20 +08:00
snapshot.c qobject: Use simpler QDict/QList scalar insertion macros 2017-05-09 09:13:51 +02:00
ssh.c ssh: support I/O from any AioContext 2017-07-17 11:34:20 +08:00
stream.c block: Make bdrv_is_allocated_above() byte-based 2017-07-10 13:18:07 +02:00
throttle-groups.c block: remove timer canceling in throttle_config() 2017-07-18 15:14:35 +02:00
trace-events block: move trace probes into bdrv_co_preadv|pwritev 2017-08-07 09:39:35 +01:00
vdi.c vdi: make it thread-safe 2017-07-17 11:28:15 +08:00
vhdx-endian.c vhdx: Use QEMU UUID API 2016-09-23 11:42:52 +08:00
vhdx-log.c block/vhdx: check error return of bdrv_truncate() 2017-08-08 14:37:00 +02:00
vhdx.c block/vhdx: check for offset overflow to bdrv_truncate() 2017-08-08 14:37:00 +02:00
vhdx.h block: vhdx - update PAYLOAD_BLOCK_UNMAPPED value to match 1.00 spec 2014-12-12 15:42:22 +00:00
vmdk.c vmdk: Fix error handling/reporting of vmdk_check 2017-08-08 15:19:16 +02:00
vpc.c vpc: Check failure of bdrv_getlength() 2017-08-11 13:23:40 +02:00
vvfat.c block/vvfat: Fix compiler warning with gcc 7 2017-07-18 15:14:36 +02:00
vxhs.c qobject: Use simpler QDict/QList scalar insertion macros 2017-05-09 09:13:51 +02:00
win32-aio.c block: explicitly acquire aiocontext in aio callbacks that need it 2017-02-21 11:39:39 +00:00
write-threshold.c block: use bdrv_add_before_write_notifier 2016-10-07 13:34:07 +02:00