From 319ae529b8d55ea60b1036809aaab2130048d0e1 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Fri, 28 Jan 2011 11:21:46 +0100 Subject: blockdev: Fix drive_add for drives without media Watch this: (qemu) drive_add 0 if=none (qemu) info block none0: type=hd removable=0 [not inserted] (qemu) drive_del none0 Segmentation fault (core dumped) add_init_drive() is confused about drive_init()'s failure modes, and cleans up when it shouldn't. This leaves the DriveInfo with member opts dangling. drive_del attempts to free it, and dies. drive_init() behaves as follows: * If it created a drive with media, it returns its DriveInfo. * If it created a drive without media, it clears *fatal_error and returns NULL. * If it couldn't create a drive, it sets *fatal_error and returns NULL. Of its three callers: * drive_init_func() is correct. * usb_msd_init() assumes drive_init() failed when it returns NULL. This is correct only because it always passes option "file", and "drive without media" can't happen then. * add_init_drive() assumes drive_init() failed when it returns NULL. This is incorrect. Clean up drive_init() to return NULL on failure and only on failure. Drop its parameter fatal_error. Signed-off-by: Markus Armbruster Signed-off-by: Kevin Wolf --- blockdev.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'blockdev.c') diff --git a/blockdev.c b/blockdev.c index 4b2145c25b..1c56da0a16 100644 --- a/blockdev.c +++ b/blockdev.c @@ -203,7 +203,7 @@ static int parse_block_error_action(const char *buf, int is_read) } } -DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi, int *fatal_error) +DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi) { const char *buf; const char *file = NULL; @@ -225,8 +225,6 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi, int *fatal_error) int snapshot = 0; int ret; - *fatal_error = 1; - translation = BIOS_ATA_TRANSLATION_AUTO; if (default_to_scsi) { @@ -499,8 +497,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi, int *fatal_error) abort(); } if (!file || !*file) { - *fatal_error = 0; - return NULL; + return dinfo; } if (snapshot) { /* always use cache=unsafe with snapshot */ @@ -529,7 +526,6 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi, int *fatal_error) if (bdrv_key_required(dinfo->bdrv)) autostart = 0; - *fatal_error = 0; return dinfo; } -- cgit v1.2.3-55-g7522