dm mpath: fix infinite recursion in ioctl when no paths and !queue_if_no_path
authorJunichi Nomura <j-nomura@ce.jp.nec.com>
Tue, 17 Nov 2015 09:36:56 +0000 (09:36 +0000)
committerMike Snitzer <snitzer@redhat.com>
Tue, 17 Nov 2015 19:19:00 +0000 (14:19 -0500)
commit43e43c9ea60a7a1831ec823773e924d2dadefd44
treead17d6501aab2fc131ce103b8310941bf18c7b36
parent647a20d5cad7477033bc021ec9dd75edf4bbf9a0
dm mpath: fix infinite recursion in ioctl when no paths and !queue_if_no_path

In multipath_prepare_ioctl(),
  - pgpath is a path selected from available paths
  - m->queue_io is true if we cannot send a request immediately to
    paths, either because:
      * there is no available path
      * the path group needs activation (pg_init)
          - pg_init is not started
          - pg_init is still running
  - m->queue_if_no_path is true if the device is configured to queue
    I/O if there are no available paths

If !pgpath && !m->queue_if_no_path, the handler should return -EIO.
However in the course of refactoring the condition check has broken
and returns success in that case.  Since bdev points to the dm device
itself, dm_blk_ioctl() calls __blk_dev_driver_ioctl() for itself and
recurses until crash.

You could reproduce the problem like this:

  # dmsetup create mp --table '0 1024 multipath 0 0 0 0'
  # sg_inq /dev/mapper/mp
  <crash>
  [  172.648615] BUG: unable to handle kernel paging request at fffffffc81b10268
  [  172.662843] PGD 19dd067 PUD 0
  [  172.666269] Thread overran stack, or stack corrupted
  [  172.671808] Oops: 0000 [#1] SMP
  ...

Fix the condition check with some clarifications.

Fixes: e56f81e0b01e ("dm: refactor ioctl handling")
Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
drivers/md/dm-mpath.c