Files
odroid-linux/include/linux
Jan Kara 3ee7e8697d bdi: Fix another oops in wb_workfn()
syzbot is reporting NULL pointer dereference at wb_workfn() [1] due to
wb->bdi->dev being NULL. And Dmitry confirmed that wb->state was
WB_shutting_down after wb->bdi->dev became NULL. This indicates that
unregister_bdi() failed to call wb_shutdown() on one of wb objects.

The problem is in cgwb_bdi_unregister() which does cgwb_kill() and thus
drops bdi's reference to wb structures before going through the list of
wbs again and calling wb_shutdown() on each of them. This way the loop
iterating through all wbs can easily miss a wb if that wb has already
passed through cgwb_remove_from_bdi_list() called from wb_shutdown()
from cgwb_release_workfn() and as a result fully shutdown bdi although
wb_workfn() for this wb structure is still running. In fact there are
also other ways cgwb_bdi_unregister() can race with
cgwb_release_workfn() leading e.g. to use-after-free issues:

CPU1                            CPU2
                                cgwb_bdi_unregister()
                                  cgwb_kill(*slot);

cgwb_release()
  queue_work(cgwb_release_wq, &wb->release_work);
cgwb_release_workfn()
                                  wb = list_first_entry(&bdi->wb_list, ...)
                                  spin_unlock_irq(&cgwb_lock);
  wb_shutdown(wb);
  ...
  kfree_rcu(wb, rcu);
                                  wb_shutdown(wb); -> oops use-after-free

We solve these issues by synchronizing writeback structure shutdown from
cgwb_bdi_unregister() with cgwb_release_workfn() using a new mutex. That
way we also no longer need synchronization using WB_shutting_down as the
mutex provides it for CONFIG_CGROUP_WRITEBACK case and without
CONFIG_CGROUP_WRITEBACK wb_shutdown() can be called only once from
bdi_unregister().

Reported-by: syzbot <syzbot+4a7438e774b21ddd8eca@syzkaller.appspotmail.com>
Acked-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
2018-06-22 12:08:07 -06:00
..
2018-05-25 18:23:56 +02:00
2018-05-23 14:01:03 +02:00
2018-06-05 10:48:09 -04:00
2018-06-07 14:23:08 +01:00
2018-06-07 17:34:35 -07:00
2018-04-16 14:20:26 -04:00
2018-05-26 09:16:44 +02:00
2018-04-20 17:18:35 -07:00
2018-06-14 17:01:45 +02:00
2018-03-16 10:56:13 +01:00
2018-05-28 17:41:02 +02:00
2018-05-09 17:25:13 +02:00
2018-03-16 15:45:51 -07:00
2018-03-16 10:55:47 +01:00
2018-03-26 15:09:38 +02:00
2018-04-27 14:34:51 +02:00
2018-06-01 07:38:16 -06:00
2018-03-26 15:56:44 +02:00
2018-04-26 09:02:01 -06:00
2018-06-07 17:34:37 -07:00
2018-02-22 21:13:03 +01:00
2018-03-26 08:53:43 -06:00
2018-01-17 11:30:16 +00:00
2018-05-09 12:21:46 -05:00
2018-04-11 10:28:38 -07:00
2018-04-12 09:41:19 -07:00
2018-06-05 08:50:16 -04:00
2018-06-07 17:34:35 -07:00
2018-04-11 10:28:32 -07:00
2018-06-07 17:34:37 -07:00
2018-06-07 17:34:39 -07:00
2018-03-26 13:14:43 -04:00
2018-03-26 13:14:43 -04:00
2018-01-28 22:17:24 -05:00
2018-06-01 14:37:35 +02:00
2018-01-17 15:25:50 +01:00
2018-06-07 17:34:36 -07:00
2018-04-11 10:28:39 -07:00
2018-01-31 17:18:37 -08:00
2018-06-06 16:10:45 -05:00
2018-05-15 15:51:38 +01:00
2018-06-07 17:34:35 -07:00
2018-05-31 00:13:56 +08:00
2018-05-11 17:28:45 -07:00
2018-05-11 17:28:45 -07:00
2018-06-04 17:28:20 -04:00
2018-03-01 08:33:05 -07:00
2018-05-04 12:48:54 -07:00
2018-04-30 05:14:55 -07:00
2018-06-07 17:34:35 -07:00
2018-06-07 17:34:37 -07:00
2018-05-03 15:55:23 -07:00
2018-01-15 12:07:46 -08:00
2018-04-16 14:25:08 -06:00
2018-02-06 18:32:47 -08:00
2018-05-18 11:40:27 -04:00
2018-05-19 13:57:31 +02:00
2018-05-19 13:57:31 +02:00
2018-04-26 15:08:04 -04:00
2018-02-06 18:32:44 -08:00
2018-05-14 09:51:34 -04:00