diff options
author | bde <bde@FreeBSD.org> | 1998-09-09 20:21:18 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 1998-09-09 20:21:18 +0000 |
commit | 6dbde5515d7069e0ca5fa5c47dcc86c3f547d1a1 (patch) | |
tree | 933bdc20a40840bcdefde97e580f7fbbe3086a59 /sys/gnu | |
parent | 1c30948b9b22fe063a8e9b7b12e21d49aa5df37c (diff) | |
download | FreeBSD-src-6dbde5515d7069e0ca5fa5c47dcc86c3f547d1a1.zip FreeBSD-src-6dbde5515d7069e0ca5fa5c47dcc86c3f547d1a1.tar.gz |
Fixed the usual missing permissions checks in mount(). As for cd9660,
the damage was limited by the default of 0 for vfs.usermount.
Obtained from: Lite2 via the -current ffs_vfsops.c
Diffstat (limited to 'sys/gnu')
-rw-r--r-- | sys/gnu/ext2fs/ext2_vfsops.c | 36 | ||||
-rw-r--r-- | sys/gnu/fs/ext2fs/ext2_vfsops.c | 36 |
2 files changed, 70 insertions, 2 deletions
diff --git a/sys/gnu/ext2fs/ext2_vfsops.c b/sys/gnu/ext2fs/ext2_vfsops.c index a9cf8fb..c9b8e4a 100644 --- a/sys/gnu/ext2fs/ext2_vfsops.c +++ b/sys/gnu/ext2fs/ext2_vfsops.c @@ -187,6 +187,7 @@ ext2_mount(mp, path, data, ndp, p) register struct ext2_sb_info *fs; u_int size; int error, flags; + mode_t accessmode; if (error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args))) return (error); @@ -217,8 +218,24 @@ ext2_mount(mp, path, data, ndp, p) error = ext2_reload(mp, ndp->ni_cnd.cn_cred, p); if (error) return (error); - if (fs->s_rd_only && (mp->mnt_kern_flag & MNTK_WANTRDWR)) + if (fs->s_rd_only && (mp->mnt_kern_flag & MNTK_WANTRDWR)) { + /* + * If upgrade to read-write by non-root, then verify + * that user has necessary permissions on the device. + */ + if (p->p_ucred->cr_uid != 0) { + devvp = ump->um_devvp; + vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p); + if (error = VOP_ACCESS(devvp, VREAD | VWRITE, + p->p_ucred, p)) { + VOP_UNLOCK(devvp, 0, p); + return (error); + } + VOP_UNLOCK(devvp, 0, p); + } + fs->s_rd_only = 0; + } if (fs->s_rd_only == 0) { /* don't say it's clean */ fs->s_es->s_state &= ~EXT2_VALID_FS; @@ -248,6 +265,23 @@ ext2_mount(mp, path, data, ndp, p) vrele(devvp); return (ENXIO); } + + /* + * If mount by non-root, then verify that user has necessary + * permissions on the device. + */ + if (p->p_ucred->cr_uid != 0) { + accessmode = VREAD; + if ((mp->mnt_flag & MNT_RDONLY) == 0) + accessmode |= VWRITE; + vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p); + if (error = VOP_ACCESS(devvp, accessmode, p->p_ucred, p)) { + vput(devvp); + return (error); + } + VOP_UNLOCK(devvp, 0, p); + } + if ((mp->mnt_flag & MNT_UPDATE) == 0) { if (bdevsw[major(devvp->v_rdev)]->d_flags & D_NOCLUSTERR) mp->mnt_flag |= MNT_NOCLUSTERR; diff --git a/sys/gnu/fs/ext2fs/ext2_vfsops.c b/sys/gnu/fs/ext2fs/ext2_vfsops.c index a9cf8fb..c9b8e4a 100644 --- a/sys/gnu/fs/ext2fs/ext2_vfsops.c +++ b/sys/gnu/fs/ext2fs/ext2_vfsops.c @@ -187,6 +187,7 @@ ext2_mount(mp, path, data, ndp, p) register struct ext2_sb_info *fs; u_int size; int error, flags; + mode_t accessmode; if (error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args))) return (error); @@ -217,8 +218,24 @@ ext2_mount(mp, path, data, ndp, p) error = ext2_reload(mp, ndp->ni_cnd.cn_cred, p); if (error) return (error); - if (fs->s_rd_only && (mp->mnt_kern_flag & MNTK_WANTRDWR)) + if (fs->s_rd_only && (mp->mnt_kern_flag & MNTK_WANTRDWR)) { + /* + * If upgrade to read-write by non-root, then verify + * that user has necessary permissions on the device. + */ + if (p->p_ucred->cr_uid != 0) { + devvp = ump->um_devvp; + vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p); + if (error = VOP_ACCESS(devvp, VREAD | VWRITE, + p->p_ucred, p)) { + VOP_UNLOCK(devvp, 0, p); + return (error); + } + VOP_UNLOCK(devvp, 0, p); + } + fs->s_rd_only = 0; + } if (fs->s_rd_only == 0) { /* don't say it's clean */ fs->s_es->s_state &= ~EXT2_VALID_FS; @@ -248,6 +265,23 @@ ext2_mount(mp, path, data, ndp, p) vrele(devvp); return (ENXIO); } + + /* + * If mount by non-root, then verify that user has necessary + * permissions on the device. + */ + if (p->p_ucred->cr_uid != 0) { + accessmode = VREAD; + if ((mp->mnt_flag & MNT_RDONLY) == 0) + accessmode |= VWRITE; + vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p); + if (error = VOP_ACCESS(devvp, accessmode, p->p_ucred, p)) { + vput(devvp); + return (error); + } + VOP_UNLOCK(devvp, 0, p); + } + if ((mp->mnt_flag & MNT_UPDATE) == 0) { if (bdevsw[major(devvp->v_rdev)]->d_flags & D_NOCLUSTERR) mp->mnt_flag |= MNT_NOCLUSTERR; |