Do not delete BlockDriverState when deleting the drive

When removing a drive from the host-side via drive_del we currently have
the following path:

drive_del
qemu_aio_flush()
bdrv_close()    // zaps bs->drv, which makes any subsequent I/O get
                // dropped.  Works as designed
drive_uninit()
bdrv_delete()   // frees the bs.  Since the device is still connected to
                // bs, any subsequent I/O is a use-after-free.

The value of bs->drv becomes unpredictable on free.  As long as it
remains null, I/O still gets dropped, however it could become non-null
at any point after the free resulting SEGVs or other QEMU state
corruption.

To resolve this issue as simply as possible, we can chose to not
actually delete the BlockDriverState pointer.  Since bdrv_close()
handles setting the drv pointer to NULL, we just need to remove the
BlockDriverState from the QLIST that is used to enumerate the block
devices.  This is currently handled within bdrv_delete, so move this
into its own function, bdrv_make_anon().

The result is that we can now invoke drive_del, this closes the file
descriptors and sets BlockDriverState->drv to NULL which prevents futher
IO to the device, and since we do not free BlockDriverState, we don't
have to worry about the copy retained in the block devices.

We also don't attempt to remove the qdev property since we are no longer
deleting the BlockDriverState on drives with associated drives.  This
also allows for removing Drives with no devices associated either.

Reported-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Ryan Harper <ryanh@us.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
3 files changed
tree: 327f9815ca8157d2324f4c2a732e9683bc400b2b
  1. audio/
  2. block/
  3. bsd-user/
  4. darwin-user/
  5. default-configs/
  6. docs/
  7. fpu/
  8. fsdev/
  9. gdb-xml/
  10. hw/
  11. libcacard/
  12. linux-user/
  13. net/
  14. pc-bios/
  15. QMP/
  16. roms/
  17. scripts/
  18. slirp/
  19. sysconfigs/
  20. target-alpha/
  21. target-arm/
  22. target-cris/
  23. target-i386/
  24. target-lm32/
  25. target-m68k/
  26. target-microblaze/
  27. target-mips/
  28. target-ppc/
  29. target-s390x/
  30. target-sh4/
  31. target-sparc/
  32. tcg/
  33. tests/
  34. ui/
  35. .gitignore
  36. .gitmodules
  37. a.out.h
  38. acl.c
  39. acl.h
  40. aes.c
  41. aes.h
  42. aio.c
  43. alpha-dis.c
  44. alpha.ld
  45. arch_init.c
  46. arch_init.h
  47. arm-dis.c
  48. arm-semi.c
  49. arm.ld
  50. async.c
  51. balloon.c
  52. balloon.h
  53. bitmap.c
  54. bitmap.h
  55. bitops.c
  56. bitops.h
  57. block-migration.c
  58. block-migration.h
  59. block.c
  60. block.h
  61. block_int.h
  62. blockdev.c
  63. blockdev.h
  64. bswap.h
  65. bt-host.c
  66. bt-host.h
  67. bt-vhci.c
  68. buffered_file.c
  69. buffered_file.h
  70. cache-utils.c
  71. cache-utils.h
  72. Changelog
  73. check-qdict.c
  74. check-qfloat.c
  75. check-qint.c
  76. check-qjson.c
  77. check-qlist.c
  78. check-qstring.c
  79. cmd.c
  80. cmd.h
  81. CODING_STYLE
  82. compatfd.c
  83. compatfd.h
  84. config.h
  85. configure
  86. console.c
  87. console.h
  88. COPYING
  89. COPYING.LIB
  90. cpu-all.h
  91. cpu-common.h
  92. cpu-defs.h
  93. cpu-exec.c
  94. cpus.c
  95. cpus.h
  96. cris-dis.c
  97. cursor.c
  98. cursor_hidden.xpm
  99. cursor_left_ptr.xpm
  100. cutils.c
  101. def-helper.h
  102. device_tree.c
  103. device_tree.h
  104. dis-asm.h
  105. disas.c
  106. disas.h
  107. dma-helpers.c
  108. dma.h
  109. dyngen-exec.h
  110. elf.h
  111. envlist.c
  112. envlist.h
  113. exec-all.h
  114. exec.c
  115. gdbstub.c
  116. gdbstub.h
  117. gen-icount.h
  118. HACKING
  119. hmp-commands.hx
  120. host-utils.c
  121. host-utils.h
  122. hpet.h
  123. hppa-dis.c
  124. hppa.ld
  125. i386-dis.c
  126. i386.ld
  127. ia64-dis.c
  128. ia64.ld
  129. input.c
  130. iohandler.c
  131. ioport-user.c
  132. ioport.c
  133. ioport.h
  134. iorange.h
  135. iov.c
  136. iov.h
  137. json-lexer.c
  138. json-lexer.h
  139. json-parser.c
  140. json-parser.h
  141. json-streamer.c
  142. json-streamer.h
  143. kvm-all.c
  144. kvm-stub.c
  145. kvm.h
  146. libfdt_env.h
  147. LICENSE
  148. linux-aio.c
  149. m68k-dis.c
  150. m68k-semi.c
  151. m68k.ld
  152. MAINTAINERS
  153. Makefile
  154. Makefile.dis
  155. Makefile.hw
  156. Makefile.objs
  157. Makefile.target
  158. Makefile.user
  159. microblaze-dis.c
  160. migration-exec.c
  161. migration-fd.c
  162. migration-tcp.c
  163. migration-unix.c
  164. migration.c
  165. migration.h
  166. mips-dis.c
  167. mips.ld
  168. module.c
  169. module.h
  170. monitor.c
  171. monitor.h
  172. nbd.c
  173. nbd.h
  174. net.c
  175. net.h
  176. notify.c
  177. notify.h
  178. os-posix.c
  179. os-win32.c
  180. osdep.c
  181. osdep.h
  182. oslib-posix.c
  183. oslib-win32.c
  184. path.c
  185. pci-ids.txt
  186. pflib.c
  187. pflib.h
  188. poison.h
  189. posix-aio-compat.c
  190. ppc-dis.c
  191. ppc.ld
  192. ppc64.ld
  193. qbool.c
  194. qbool.h
  195. qdict-test-data.txt
  196. qdict.c
  197. qdict.h
  198. qemu-aio.h
  199. qemu-barrier.h
  200. qemu-char.c
  201. qemu-char.h
  202. qemu-common.h
  203. qemu-config.c
  204. qemu-config.h
  205. qemu-doc.texi
  206. qemu-error.c
  207. qemu-error.h
  208. qemu-img-cmds.hx
  209. qemu-img.c
  210. qemu-img.texi
  211. qemu-io.c
  212. qemu-lock.h
  213. qemu-log.h
  214. qemu-malloc.c
  215. qemu-nbd.c
  216. qemu-nbd.texi
  217. qemu-objects.h
  218. qemu-option.c
  219. qemu-option.h
  220. qemu-options.h
  221. qemu-options.hx
  222. qemu-os-posix.h
  223. qemu-os-win32.h
  224. qemu-queue.h
  225. qemu-sockets.c
  226. qemu-tech.texi
  227. qemu-thread-posix.c
  228. qemu-thread-posix.h
  229. qemu-thread-win32.c
  230. qemu-thread-win32.h
  231. qemu-thread.h
  232. qemu-timer-common.c
  233. qemu-timer.c
  234. qemu-timer.h
  235. qemu-tool.c
  236. qemu-x509.h
  237. qemu.sasl
  238. qemu_socket.h
  239. qerror.c
  240. qerror.h
  241. qfloat.c
  242. qfloat.h
  243. qint.c
  244. qint.h
  245. qjson.c
  246. qjson.h
  247. qlist.c
  248. qlist.h
  249. qmp-commands.hx
  250. qobject.h
  251. qstring.c
  252. qstring.h
  253. range.h
  254. readline.c
  255. readline.h
  256. README
  257. rules.mak
  258. rwhandler.c
  259. rwhandler.h
  260. s390-dis.c
  261. s390.ld
  262. savevm.c
  263. sh4-dis.c
  264. simpletrace.c
  265. simpletrace.h
  266. softmmu-semi.h
  267. softmmu_defs.h
  268. softmmu_exec.h
  269. softmmu_header.h
  270. softmmu_template.h
  271. sparc-dis.c
  272. sparc.ld
  273. sparc64.ld
  274. spice-qemu-char.c
  275. sysemu.h
  276. targphys.h
  277. tcg-runtime.c
  278. thunk.c
  279. thunk.h
  280. TODO
  281. trace-events
  282. translate-all.c
  283. uboot_image.h
  284. usb-bsd.c
  285. usb-linux.c
  286. usb-stub.c
  287. VERSION
  288. version.rc
  289. vgafont.h
  290. vl.c
  291. x86_64.ld