]> git.ipfire.org Git - thirdparty/qemu.git/commit - block.c
block: fix bdrv_check_perm for non-tree subgraph
authorVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Sat, 23 Feb 2019 19:20:40 +0000 (22:20 +0300)
committerKevin Wolf <kwolf@redhat.com>
Mon, 25 Feb 2019 14:03:19 +0000 (15:03 +0100)
commitf962e96150e9c6a41e26caeaf93a65ec5b755607
tree0043e65f73d0ada51a7230afeb0ad111a9dd3dc2
parent2f30b7c377fa9a7dfbaf6eed56a07be7953e509e
block: fix bdrv_check_perm for non-tree subgraph

bdrv_check_perm in it's recursion checks each node in context of new
permissions for one parent, because of nature of DFS. It works well,
while children subgraph of top-most updated node is a tree, i.e. it
doesn't have any kind of loops. But if we have a loop (not oriented,
of course), i.e. we have two different ways from top-node to some
child-node, then bdrv_check_perm will do wrong thing:

  top
  | \
  |  |
  v  v
  A  B
  |  |
  v  v
  node

It will once check new permissions of node in context of new A
permissions and old B permissions and once visa-versa. It's a wrong way
and may lead to corruption of permission system. We may start with
no-permissions and all-shared for both A->node and B->node relations
and finish up with non shared write permission for both ways.

The following commit will add a test, which shows this bug.

To fix this situation, let's really set BdrvChild permissions during
bdrv_check_perm procedure. And we are happy here, as check-perm is
already written in transaction manner, so we just need to restore
backed-up permissions in _abort.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
block.c
include/block/block_int.h