summaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_state.h
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2017-08-29 10:20:39 +0200
committerJens Axboe <axboe@kernel.dk>2017-08-29 15:34:45 -0600
commit7c752ed3257517fc8607ab1d19fe4e86155721e3 (patch)
treee025a9525f246ea9d78d7f95123ce5add35f516a /drivers/block/drbd/drbd_state.h
parent9de7e14a1a9c6bc4f9be6ccd9b951341a80dbd52 (diff)
downloadlinux-7c752ed3257517fc8607ab1d19fe4e86155721e3.tar.bz2
drbd: fix potential get_ldev/put_ldev refcount imbalance during attach
Race: drbd_adm_attach() | async drbd_md_endio() | device->ldev is still NULL. | | drbd_md_read( | .endio = drbd_md_endio; | submit; | .... | wait for done == 1; | done = 1; ); | wake_up(); .. lot of other stuff, | .. includeing taking and | ...giving up locks, | .. doing further IO, | .. stuff that takes "some time" | | while in this context, | this is the next statement. | which means this context was scheduled .. only then, finally, | away for "some time". device->ldev = nbc; | | if (device->ldev) | put_ldev() Unlikely, but possible. I was able to provoke it "reliably" by adding an mdelay(500); after the wake_up(). Fixed by moving the if (!NULL) put_ldev() before done = 1; Impact of the bug was that the resulting refcount imbalance could lead to premature destruction of the object, potentially causing a NULL pointer dereference during a subsequent detach. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/block/drbd/drbd_state.h')
0 files changed, 0 insertions, 0 deletions