zfs/lib/libzfs
Matthew Ahrens 018f26041d
deadlock between spa_errlog_lock and dp_config_rwlock
There is a lock order inversion deadlock between `spa_errlog_lock` and
`dp_config_rwlock`:

A thread in `spa_delete_dataset_errlog()` is running from a sync task.
It is holding the `dp_config_rwlock` for writer (see
`dsl_sync_task_sync()`), and waiting for the `spa_errlog_lock`.

A thread in `dsl_pool_config_enter()` is holding the `spa_errlog_lock`
(see `spa_get_errlog_size()`) and waiting for the `dp_config_rwlock` (as
reader).

Note that this was introduced by #12812.

This commit address this by defining the lock ordering to be
dp_config_rwlock first, then spa_errlog_lock / spa_errlist_lock.
spa_get_errlog() and spa_get_errlog_size() can acquire the locks in this
order, and then process_error_block() and get_head_and_birth_txg() can
verify that the dp_config_rwlock is already held.

Additionally, a buffer overrun in `spa_get_errlog()` is corrected.  Many
code paths didn't check if `*count` got to zero, instead continuing to
overwrite past the beginning of the userspace buffer at `uaddr`.

Tested by having some errors in the pool (via `zinject -t data
/path/to/file`), one thread running `zpool iostat 0.001`, and another
thread runs `zfs destroy` (in a loop, although it hits the first time).
This reproduces the problem easily without the fix, and works with the
fix.

Reviewed-by: Mark Maybee <mark.maybee@delphix.com>
Reviewed-by: George Amanakis <gamanakis@gmail.com>
Reviewed-by: George Wilson <gwilson@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Matthew Ahrens <mahrens@delphix.com>
Closes #14239
Closes #14289
2022-12-22 11:48:49 -08:00
..
os FreeBSD: do_mount() passes wrong string length to helper 2022-11-18 11:34:25 -08:00
.gitignore Clean up lib dependencies 2020-07-10 14:26:00 -07:00
Makefile.am Replace EXTRA_DIST with dist_noinst_DATA 2022-05-26 09:24:50 -07:00
THIRDPARTYLICENSE.openssl Fix typos in lib/ 2019-09-02 17:53:27 -07:00
THIRDPARTYLICENSE.openssl.descrip Encryption patch follow-up 2017-10-11 16:54:48 -04:00
libzfs.abi zfs list: Allow more fields in ZFS_ITER_SIMPLE mode 2022-12-13 17:27:54 -08:00
libzfs.pc.in Spruce up pkg-config files for libzfs/libzfs_core 2020-09-04 11:11:18 -07:00
libzfs.suppr Library ABI tracking with abigail 2020-11-17 09:18:52 -08:00
libzfs_changelist.c zfs list: Allow more fields in ZFS_ITER_SIMPLE mode 2022-12-13 17:27:54 -08:00
libzfs_config.c Replace dead opensolaris.org license link 2022-07-11 14:16:13 -07:00
libzfs_crypto.c zfs list: Allow more fields in ZFS_ITER_SIMPLE mode 2022-12-13 17:27:54 -08:00
libzfs_dataset.c zfs list: Allow more fields in ZFS_ITER_SIMPLE mode 2022-12-13 17:27:54 -08:00
libzfs_diff.c Add color output to zfs diff. 2022-12-15 10:14:32 -08:00
libzfs_impl.h Replace dead opensolaris.org license link 2022-07-11 14:16:13 -07:00
libzfs_import.c Replace dead opensolaris.org license link 2022-07-11 14:16:13 -07:00
libzfs_iter.c zfs list: Allow more fields in ZFS_ITER_SIMPLE mode 2022-12-13 17:27:54 -08:00
libzfs_mount.c zfs list: Allow more fields in ZFS_ITER_SIMPLE mode 2022-12-13 17:27:54 -08:00
libzfs_pool.c deadlock between spa_errlog_lock and dp_config_rwlock 2022-12-22 11:48:49 -08:00
libzfs_sendrecv.c Allow receiver to override encryption properties in case of replication 2022-12-13 17:30:46 -08:00
libzfs_status.c deadlock between spa_errlog_lock and dp_config_rwlock 2022-12-22 11:48:49 -08:00
libzfs_util.c Add color output to zfs diff. 2022-12-15 10:14:32 -08:00