mirror of https://github.com/xemu-project/xemu.git
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 <berrange@redhat.com> [Use errx, not err. - Paolo] Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
0ca5aa4f4c
commit
e6b636779b
20
qemu-nbd.c
20
qemu-nbd.c
|
@ -306,6 +306,7 @@ static void nbd_accept(void *opaque)
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
BlockDriverState *bs;
|
BlockDriverState *bs;
|
||||||
|
BlockDriver *drv;
|
||||||
off_t dev_offset = 0;
|
off_t dev_offset = 0;
|
||||||
uint32_t nbdflags = 0;
|
uint32_t nbdflags = 0;
|
||||||
bool disconnect = false;
|
bool disconnect = false;
|
||||||
|
@ -313,7 +314,7 @@ int main(int argc, char **argv)
|
||||||
char *device = NULL;
|
char *device = NULL;
|
||||||
int port = NBD_DEFAULT_PORT;
|
int port = NBD_DEFAULT_PORT;
|
||||||
off_t fd_size;
|
off_t fd_size;
|
||||||
const char *sopt = "hVb:o:p:rsnP:c:dvk:e:t";
|
const char *sopt = "hVb:o:p:rsnP:c:dvk:e:f:t";
|
||||||
struct option lopt[] = {
|
struct option lopt[] = {
|
||||||
{ "help", 0, NULL, 'h' },
|
{ "help", 0, NULL, 'h' },
|
||||||
{ "version", 0, NULL, 'V' },
|
{ "version", 0, NULL, 'V' },
|
||||||
|
@ -333,6 +334,7 @@ int main(int argc, char **argv)
|
||||||
#endif
|
#endif
|
||||||
{ "discard", 1, NULL, QEMU_NBD_OPT_DISCARD },
|
{ "discard", 1, NULL, QEMU_NBD_OPT_DISCARD },
|
||||||
{ "shared", 1, NULL, 'e' },
|
{ "shared", 1, NULL, 'e' },
|
||||||
|
{ "format", 1, NULL, 'f' },
|
||||||
{ "persistent", 0, NULL, 't' },
|
{ "persistent", 0, NULL, 't' },
|
||||||
{ "verbose", 0, NULL, 'v' },
|
{ "verbose", 0, NULL, 'v' },
|
||||||
{ NULL, 0, NULL, 0 }
|
{ NULL, 0, NULL, 0 }
|
||||||
|
@ -351,6 +353,7 @@ int main(int argc, char **argv)
|
||||||
bool seen_aio = false;
|
bool seen_aio = false;
|
||||||
#endif
|
#endif
|
||||||
pthread_t client_thread;
|
pthread_t client_thread;
|
||||||
|
const char *fmt = NULL;
|
||||||
|
|
||||||
/* The client thread uses SIGTERM to interrupt the server. A signal
|
/* The client thread uses SIGTERM to interrupt the server. A signal
|
||||||
* handler ensures that "qemu-nbd -v -c" exits with a nice status code.
|
* handler ensures that "qemu-nbd -v -c" exits with a nice status code.
|
||||||
|
@ -454,6 +457,9 @@ int main(int argc, char **argv)
|
||||||
errx(EXIT_FAILURE, "Shared device number must be greater than 0\n");
|
errx(EXIT_FAILURE, "Shared device number must be greater than 0\n");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'f':
|
||||||
|
fmt = optarg;
|
||||||
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
persistent = 1;
|
persistent = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -555,9 +561,19 @@ int main(int argc, char **argv)
|
||||||
bdrv_init();
|
bdrv_init();
|
||||||
atexit(bdrv_close_all);
|
atexit(bdrv_close_all);
|
||||||
|
|
||||||
|
if (fmt) {
|
||||||
|
drv = bdrv_find_format(fmt);
|
||||||
|
if (!drv) {
|
||||||
|
errx(EXIT_FAILURE, "Unknown file format '%s'", fmt);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
drv = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
bs = bdrv_new("hda");
|
bs = bdrv_new("hda");
|
||||||
srcpath = argv[optind];
|
srcpath = argv[optind];
|
||||||
if ((ret = bdrv_open(bs, srcpath, NULL, flags, NULL)) < 0) {
|
ret = bdrv_open(bs, srcpath, NULL, flags, drv);
|
||||||
|
if (ret < 0) {
|
||||||
errno = -ret;
|
errno = -ret;
|
||||||
err(EXIT_FAILURE, "Failed to bdrv_open '%s'", argv[optind]);
|
err(EXIT_FAILURE, "Failed to bdrv_open '%s'", argv[optind]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,8 @@ Export QEMU disk image using NBD protocol.
|
||||||
disconnect the specified device
|
disconnect the specified device
|
||||||
@item -e, --shared=@var{num}
|
@item -e, --shared=@var{num}
|
||||||
device can be shared by @var{num} clients (default @samp{1})
|
device can be shared by @var{num} clients (default @samp{1})
|
||||||
|
@item -f, --format=@var{fmt}
|
||||||
|
force block driver for format @var{fmt} instead of auto-detecting
|
||||||
@item -t, --persistent
|
@item -t, --persistent
|
||||||
don't exit on the last connection
|
don't exit on the last connection
|
||||||
@item -v, --verbose
|
@item -v, --verbose
|
||||||
|
|
Loading…
Reference in New Issue