Linux: Fix use-after-free in zfsvfs_create()

Coverity reported that we pass a pointer to zfsvfs to
`dmu_objset_disown()` after freeing zfsvfs in zfsvfs_create_impl() after
a failure in zfsvfs_init().

We have nearly identical duplicate versions of this code for FreeBSD and
Linux, but interestingly, the FreeBSD version of this code differs in
such a way that it does not suffer from this bug. We remove the
difference from the FreeBSD version to fix this bug.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Richard Yao <richard.yao@alumni.stonybrook.edu>
Closes #13883
This commit is contained in:
Richard Yao 2022-09-19 20:30:58 -04:00 committed by GitHub
parent 042d43a1dd
commit 891ac937be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -784,9 +784,7 @@ zfsvfs_create(const char *osname, boolean_t readonly, zfsvfs_t **zfvp)
} }
error = zfsvfs_create_impl(zfvp, zfsvfs, os); error = zfsvfs_create_impl(zfvp, zfsvfs, os);
if (error != 0) {
dmu_objset_disown(os, B_TRUE, zfsvfs);
}
return (error); return (error);
} }
@ -826,6 +824,7 @@ zfsvfs_create_impl(zfsvfs_t **zfvp, zfsvfs_t *zfsvfs, objset_t *os)
error = zfsvfs_init(zfsvfs, os); error = zfsvfs_init(zfsvfs, os);
if (error != 0) { if (error != 0) {
dmu_objset_disown(os, B_TRUE, zfsvfs);
*zfvp = NULL; *zfvp = NULL;
zfsvfs_free(zfsvfs); zfsvfs_free(zfsvfs);
return (error); return (error);