mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
libzfs: don't read a dataset handle after closing it in resume send
zfs_send_resume_impl_cb_impl() closes the dataset handle before its error switch and then reads zhp->zfs_name again in the ESRCH case. zfs_name is an array declared inside struct zfs_handle, so the free() at the end of zfs_close() releases it along with the handle, and lzc_exists() copies out of the freed block. The close dates from the original resume send. The ESRCH case was added three years later with redacted send, below a handle that was no longer live. The path is reachable: dsl_bookmark_lookup() returns ESRCH when the incremental source is a bookmark that has gone away, which a resume can lose a race with. Keep a copy of the name alongside the error message that is already formatted before the close, and test that instead. Reported-by: RigelYoung <[email protected]> Reviewed-by: Rob Norris <[email protected]> Reviewed-by: Alexander Motin <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Michael Heller <[email protected]> Closes #18870 Closes #18883
This commit is contained in:
1 parent
674b1ae5cd
commit
3bd8cefdc9
1 file changed
+3
-1
@@ -1986,8 +1986,10 @@ zfs_send_resume_impl_cb_impl(libzfs_handle_t *hdl, sendflags_t *flags,
|
||||
}
|
||||
|
||||
char errbuf[ERRBUFLEN];
|
||||
char sendname[ZFS_MAX_DATASET_NAME_LEN];
|
||||
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
|
||||
"warning: cannot send '%s'"), zhp->zfs_name);
|
||||
(void) strlcpy(sendname, zhp->zfs_name, sizeof (sendname));
|
||||
|
||||
zfs_close(zhp);
|
||||
|
||||
@@ -1999,7 +2001,7 @@ zfs_send_resume_impl_cb_impl(libzfs_handle_t *hdl, sendflags_t *flags,
|
||||
"source key must be loaded"));
|
||||
return (zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf));
|
||||
case ESRCH:
|
||||
if (lzc_exists(zhp->zfs_name)) {
|
||||
if (lzc_exists(sendname)) {
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"incremental source could not be found"));
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user