Skip to content

Commit e6b6367

Browse files
berrangeAnthony Liguori
authored and
Anthony Liguori
committed
Add -f FMT / --format FMT arg to qemu-nbd
Currently the qemu-nbd program will auto-detect the format of any disk it is given. This behaviour is known to be insecure. For example, if qemu-nbd initially exposes a 'raw' file to an unprivileged app, and that app runs 'qemu-img create -f qcow2 -o backing_file=/etc/shadow /dev/nbd0' then the next time the app is started, the qemu-nbd will now detect it as a 'qcow2' file and expose /etc/shadow to the unprivileged app. The only way to avoid this is to explicitly tell qemu-nbd what disk format to use on the command line, completely disabling auto-detection. This patch adds a '-f' / '--format' arg for this purpose, mirroring what is already available via qemu-img and qemu commands. qemu-nbd --format raw -p 9000 evil.img will now always use raw, regardless of what format 'evil.img' looks like it contains Signed-off-by: Daniel P. Berrange <[email protected]> [Use errx, not err. - Paolo] Signed-off-by: Paolo Bonzini <[email protected]> Signed-off-by: Anthony Liguori <[email protected]>
1 parent 0ca5aa4 commit e6b6367

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

qemu-nbd.c

+18-2
Original file line numberDiff line numberDiff line change
@@ -306,14 +306,15 @@ static void nbd_accept(void *opaque)
306306
int main(int argc, char **argv)
307307
{
308308
BlockDriverState *bs;
309+
BlockDriver *drv;
309310
off_t dev_offset = 0;
310311
uint32_t nbdflags = 0;
311312
bool disconnect = false;
312313
const char *bindto = "0.0.0.0";
313314
char *device = NULL;
314315
int port = NBD_DEFAULT_PORT;
315316
off_t fd_size;
316-
const char *sopt = "hVb:o:p:rsnP:c:dvk:e:t";
317+
const char *sopt = "hVb:o:p:rsnP:c:dvk:e:f:t";
317318
struct option lopt[] = {
318319
{ "help", 0, NULL, 'h' },
319320
{ "version", 0, NULL, 'V' },
@@ -333,6 +334,7 @@ int main(int argc, char **argv)
333334
#endif
334335
{ "discard", 1, NULL, QEMU_NBD_OPT_DISCARD },
335336
{ "shared", 1, NULL, 'e' },
337+
{ "format", 1, NULL, 'f' },
336338
{ "persistent", 0, NULL, 't' },
337339
{ "verbose", 0, NULL, 'v' },
338340
{ NULL, 0, NULL, 0 }
@@ -351,6 +353,7 @@ int main(int argc, char **argv)
351353
bool seen_aio = false;
352354
#endif
353355
pthread_t client_thread;
356+
const char *fmt = NULL;
354357

355358
/* The client thread uses SIGTERM to interrupt the server. A signal
356359
* handler ensures that "qemu-nbd -v -c" exits with a nice status code.
@@ -454,6 +457,9 @@ int main(int argc, char **argv)
454457
errx(EXIT_FAILURE, "Shared device number must be greater than 0\n");
455458
}
456459
break;
460+
case 'f':
461+
fmt = optarg;
462+
break;
457463
case 't':
458464
persistent = 1;
459465
break;
@@ -555,9 +561,19 @@ int main(int argc, char **argv)
555561
bdrv_init();
556562
atexit(bdrv_close_all);
557563

564+
if (fmt) {
565+
drv = bdrv_find_format(fmt);
566+
if (!drv) {
567+
errx(EXIT_FAILURE, "Unknown file format '%s'", fmt);
568+
}
569+
} else {
570+
drv = NULL;
571+
}
572+
558573
bs = bdrv_new("hda");
559574
srcpath = argv[optind];
560-
if ((ret = bdrv_open(bs, srcpath, NULL, flags, NULL)) < 0) {
575+
ret = bdrv_open(bs, srcpath, NULL, flags, drv);
576+
if (ret < 0) {
561577
errno = -ret;
562578
err(EXIT_FAILURE, "Failed to bdrv_open '%s'", argv[optind]);
563579
}

qemu-nbd.texi

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ Export QEMU disk image using NBD protocol.
4545
disconnect the specified device
4646
@item -e, --shared=@var{num}
4747
device can be shared by @var{num} clients (default @samp{1})
48+
@item -f, --format=@var{fmt}
49+
force block driver for format @var{fmt} instead of auto-detecting
4850
@item -t, --persistent
4951
don't exit on the last connection
5052
@item -v, --verbose

0 commit comments

Comments
 (0)