diff options
author | Mark Shellenbaum <Mark.Shellenbaum@Oracle.COM> | 2010-08-18 13:59:31 -0600 |
---|---|---|
committer | Mark Shellenbaum <Mark.Shellenbaum@Oracle.COM> | 2010-08-18 13:59:31 -0600 |
commit | 44bffe012cad6481c82ad67bacd6b40bd29def2b (patch) | |
tree | 02ac403d4fa8ec419c2e6046000b5eb6020f6f32 | |
parent | e291592ab12a560fc73b0610963bb3fe66aab341 (diff) | |
download | illumos-joyent-44bffe012cad6481c82ad67bacd6b40bd29def2b.tar.gz |
6977619 NULL pointer deference in sa_handle_get_from_db()
-rw-r--r-- | usr/src/uts/common/fs/vfs.c | 9 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/zfs_vfsops.c | 54 | ||||
-rw-r--r-- | usr/src/uts/common/sys/vfs.h | 1 |
3 files changed, 48 insertions, 16 deletions
diff --git a/usr/src/uts/common/fs/vfs.c b/usr/src/uts/common/fs/vfs.c index cbb2adfb37..e24f2d3b32 100644 --- a/usr/src/uts/common/fs/vfs.c +++ b/usr/src/uts/common/fs/vfs.c @@ -4718,6 +4718,15 @@ vfs_set_feature(vfs_t *vfsp, vfs_feature_t feature) vfsp->vfs_featureset[VFTINDEX(feature)] |= VFTBITS(feature); } +void +vfs_clear_feature(vfs_t *vfsp, vfs_feature_t feature) +{ + /* Note that vfs_featureset[] is found in *vfsp->vfs_implp */ + if (vfsp->vfs_implp == NULL) + return; + vfsp->vfs_featureset[VFTINDEX(feature)] &= VFTBITS(~feature); +} + /* * Query a vfs for a feature. * Returns 1 if feature is present, 0 if not diff --git a/usr/src/uts/common/fs/zfs/zfs_vfsops.c b/usr/src/uts/common/fs/zfs/zfs_vfsops.c index cb8c1d086e..4970552d0c 100644 --- a/usr/src/uts/common/fs/zfs/zfs_vfsops.c +++ b/usr/src/uts/common/fs/zfs/zfs_vfsops.c @@ -1086,13 +1086,22 @@ static void zfs_set_fuid_feature(zfsvfs_t *zfsvfs) { zfsvfs->z_use_fuids = USE_FUIDS(zfsvfs->z_version, zfsvfs->z_os); - if (zfsvfs->z_use_fuids && zfsvfs->z_vfs) { - vfs_set_feature(zfsvfs->z_vfs, VFSFT_XVATTR); - vfs_set_feature(zfsvfs->z_vfs, VFSFT_SYSATTR_VIEWS); - vfs_set_feature(zfsvfs->z_vfs, VFSFT_ACEMASKONACCESS); - vfs_set_feature(zfsvfs->z_vfs, VFSFT_ACLONCREATE); - vfs_set_feature(zfsvfs->z_vfs, VFSFT_ACCESS_FILTER); - vfs_set_feature(zfsvfs->z_vfs, VFSFT_REPARSE); + if (zfsvfs->z_vfs) { + if (zfsvfs->z_use_fuids) { + vfs_set_feature(zfsvfs->z_vfs, VFSFT_XVATTR); + vfs_set_feature(zfsvfs->z_vfs, VFSFT_SYSATTR_VIEWS); + vfs_set_feature(zfsvfs->z_vfs, VFSFT_ACEMASKONACCESS); + vfs_set_feature(zfsvfs->z_vfs, VFSFT_ACLONCREATE); + vfs_set_feature(zfsvfs->z_vfs, VFSFT_ACCESS_FILTER); + vfs_set_feature(zfsvfs->z_vfs, VFSFT_REPARSE); + } else { + vfs_clear_feature(zfsvfs->z_vfs, VFSFT_XVATTR); + vfs_clear_feature(zfsvfs->z_vfs, VFSFT_SYSATTR_VIEWS); + vfs_clear_feature(zfsvfs->z_vfs, VFSFT_ACEMASKONACCESS); + vfs_clear_feature(zfsvfs->z_vfs, VFSFT_ACLONCREATE); + vfs_clear_feature(zfsvfs->z_vfs, VFSFT_ACCESS_FILTER); + vfs_clear_feature(zfsvfs->z_vfs, VFSFT_REPARSE); + } } zfsvfs->z_use_sa = USE_SA(zfsvfs->z_version, zfsvfs->z_os); } @@ -2010,7 +2019,7 @@ zfs_suspend_fs(zfsvfs_t *zfsvfs) int zfs_resume_fs(zfsvfs_t *zfsvfs, const char *osname) { - int err, err2; + int err; ASSERT(RRW_WRITE_HELD(&zfsvfs->z_teardown_lock)); ASSERT(RW_WRITE_HELD(&zfsvfs->z_teardown_inactive_lock)); @@ -2023,19 +2032,34 @@ zfs_resume_fs(zfsvfs_t *zfsvfs, const char *osname) znode_t *zp; uint64_t sa_obj = 0; - err2 = zap_lookup(zfsvfs->z_os, MASTER_NODE_OBJ, - ZFS_SA_ATTRS, 8, 1, &sa_obj); + /* + * Make sure version hasn't changed + */ + + err = zfs_get_zplprop(zfsvfs->z_os, ZFS_PROP_VERSION, + &zfsvfs->z_version); - if ((err || err2) && zfsvfs->z_version >= ZPL_VERSION_SA) + if (err) goto bail; + err = zap_lookup(zfsvfs->z_os, MASTER_NODE_OBJ, + ZFS_SA_ATTRS, 8, 1, &sa_obj); + + if (err && zfsvfs->z_version >= ZPL_VERSION_SA) + goto bail; if ((err = sa_setup(zfsvfs->z_os, sa_obj, zfs_attr_table, ZPL_END, &zfsvfs->z_attr_table)) != 0) goto bail; + if (zfsvfs->z_version >= ZPL_VERSION_SA) + sa_register_update_callback(zfsvfs->z_os, + zfs_sa_upgrade); + VERIFY(zfsvfs_setup(zfsvfs, B_FALSE) == 0); + zfs_set_fuid_feature(zfsvfs); + /* * Attempt to re-establish all the active znodes with * their dbufs. If a zfs_rezget() fails, then we'll let @@ -2048,7 +2072,6 @@ zfs_resume_fs(zfsvfs_t *zfsvfs, const char *osname) (void) zfs_rezget(zp); } mutex_exit(&zfsvfs->z_znodes_lock); - } bail: @@ -2058,8 +2081,8 @@ bail: if (err) { /* - * Since we couldn't reopen zfsvfs::z_os, force - * unmount this file system. + * Since we couldn't reopen zfsvfs::z_os, or + * setup the sa framework force unmount this file system. */ if (vn_vfswlock(zfsvfs->z_vfs->vfs_vnodecovered) == 0) (void) dounmount(zfsvfs->z_vfs, MS_FORCE, CRED()); @@ -2219,8 +2242,7 @@ zfs_set_version(zfsvfs_t *zfsvfs, uint64_t newvers) zfsvfs->z_version = newvers; - if (zfsvfs->z_version >= ZPL_VERSION_FUID) - zfs_set_fuid_feature(zfsvfs); + zfs_set_fuid_feature(zfsvfs); return (0); } diff --git a/usr/src/uts/common/sys/vfs.h b/usr/src/uts/common/sys/vfs.h index ba013a0eda..879f2aad09 100644 --- a/usr/src/uts/common/sys/vfs.h +++ b/usr/src/uts/common/sys/vfs.h @@ -494,6 +494,7 @@ void vfs_remove(struct vfs *); /* VFS feature routines */ void vfs_set_feature(vfs_t *, vfs_feature_t); +void vfs_clear_feature(vfs_t *, vfs_feature_t); int vfs_has_feature(vfs_t *, vfs_feature_t); void vfs_propagate_features(vfs_t *, vfs_t *); |