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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user