panic in bpobj_space(): null pointer dereference
commitdf7eeccc7597980efd3cb1efd9377ad5e0483042
authorMatthew Ahrens <mahrens@delphix.com>
Thu, 9 Feb 2017 18:19:12 +0000 (9 10:19 -0800)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 9 Feb 2017 18:19:12 +0000 (9 10:19 -0800)
tree019acfbccd405cdc2ee0f41b0ba0fdafd3aeea42
parentb0eac56a4d69c6f2ae7cb1937cf59e05c52e3a60
panic in bpobj_space(): null pointer dereference

This is a race condition in the deadlist code.

A thread executing an administrative command that uses
dsl_deadlist_space_range() holds the lock of the whole deadlist_t to
protect the access of all its entries that the deadlist contains in an
avl tree.

Sync threads trying to insert a new entry in the deadlist (through
dsl_deadlist_insert() -> dle_enqueue()) do not hold the deadlist lock at
that moment.  If the dle_bpobj is the empty bpobj (our sentinel value),
we close and reopen it.  Between these two operations, it is possible
for the dsl_deadlist_space_range() thread to dereference that bpobj
which is NULL during that window.

Threads should hold the a deadlist's dl_lock when they manipulate its
internal data so scenarios like the one above are avoided.

Reviewed-by: Matthew Ahrens <mahrens@delphix.com>
Reviewed-by: Dan Kimmel <dan.kimmel@delphix.com>
Reviewed-by: George Melikov <mail@gmelikov.ru>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Matthew Ahrens <mahrens@delphix.com>
Closes #5762
module/zfs/bpobj.c
module/zfs/dsl_deadlist.c