summaryrefslogtreecommitdiffstats
path: root/sys/gnu
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>1998-09-09 20:21:18 +0000
committerbde <bde@FreeBSD.org>1998-09-09 20:21:18 +0000
commit6dbde5515d7069e0ca5fa5c47dcc86c3f547d1a1 (patch)
tree933bdc20a40840bcdefde97e580f7fbbe3086a59 /sys/gnu
parent1c30948b9b22fe063a8e9b7b12e21d49aa5df37c (diff)
downloadFreeBSD-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.c36
-rw-r--r--sys/gnu/fs/ext2fs/ext2_vfsops.c36
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;
OpenPOWER on IntegriCloud