diff options
author | jhb <jhb@FreeBSD.org> | 2001-01-23 22:41:15 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2001-01-23 22:41:15 +0000 |
commit | 45daa2e3ce5127d3a90b289e0f3628ed66f7bce8 (patch) | |
tree | 4ff4ee72470aed31a91e531ffa7338143b8086bb /sys/gnu | |
parent | 24fda4f13ec981051ae684c13423bcc48885891f (diff) | |
download | FreeBSD-src-45daa2e3ce5127d3a90b289e0f3628ed66f7bce8.zip FreeBSD-src-45daa2e3ce5127d3a90b289e0f3628ed66f7bce8.tar.gz |
Proc locking, mostly protecting p_ucred while obtaining additional
references.
Diffstat (limited to 'sys/gnu')
-rw-r--r-- | sys/gnu/ext2fs/ext2_readwrite.c | 2 | ||||
-rw-r--r-- | sys/gnu/ext2fs/ext2_vfsops.c | 31 | ||||
-rw-r--r-- | sys/gnu/fs/ext2fs/ext2_readwrite.c | 2 | ||||
-rw-r--r-- | sys/gnu/fs/ext2fs/ext2_vfsops.c | 31 |
4 files changed, 56 insertions, 10 deletions
diff --git a/sys/gnu/ext2fs/ext2_readwrite.c b/sys/gnu/ext2fs/ext2_readwrite.c index 30a2f56..64065c3 100644 --- a/sys/gnu/ext2fs/ext2_readwrite.c +++ b/sys/gnu/ext2fs/ext2_readwrite.c @@ -217,6 +217,8 @@ WRITE(ap) * file servers have no limits, I don't think it matters. */ p = uio->uio_procp; + /* For p_rlimit. */ + mtx_assert(&Giant, MA_OWNED); if (vp->v_type == VREG && p && uio->uio_offset + uio->uio_resid > p->p_rlimit[RLIMIT_FSIZE].rlim_cur) { diff --git a/sys/gnu/ext2fs/ext2_vfsops.c b/sys/gnu/ext2fs/ext2_vfsops.c index cbaac5e..12682e4 100644 --- a/sys/gnu/ext2fs/ext2_vfsops.c +++ b/sys/gnu/ext2fs/ext2_vfsops.c @@ -188,6 +188,7 @@ ext2_mount(mp, path, data, ndp, p) struct vnode *devvp; struct ufs_args args; struct ufsmount *ump = 0; + struct ucred *uc; register struct ext2_sb_info *fs; size_t size; int error, flags; @@ -230,13 +231,19 @@ ext2_mount(mp, path, data, ndp, p) * 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) { + if (suser(p)) { vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p); + PROC_LOCK(p); + uc = p->p_ucred; + crhold(uc); + PROC_UNLOCK(p); if ((error = VOP_ACCESS(devvp, VREAD | VWRITE, - p->p_ucred, p)) != 0) { + uc, p)) != 0) { + crfree(uc); VOP_UNLOCK(devvp, 0, p); return (error); } + crfree(uc); VOP_UNLOCK(devvp, 0, p); } @@ -283,15 +290,21 @@ ext2_mount(mp, path, data, ndp, p) * If mount by non-root, then verify that user has necessary * permissions on the device. */ - if (p->p_ucred->cr_uid != 0) { + if (suser(p)) { 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)) != 0) { + PROC_LOCK(p); + uc = p->p_ucred; + crhold(uc); + PROC_UNLOCK(p); + if ((error = VOP_ACCESS(devvp, accessmode, uc, p)) != 0) { + crfree(uc); vput(devvp); return (error); } + crfree(uc); VOP_UNLOCK(devvp, 0, p); } @@ -617,6 +630,7 @@ ext2_mountfs(devvp, mp, p) { register struct ufsmount *ump; struct buf *bp; + struct ucred *uc; register struct ext2_sb_info *fs; struct ext2_super_block * es; dev_t dev = devvp->v_rdev; @@ -635,8 +649,15 @@ ext2_mountfs(devvp, mp, p) return (error); if (vcount(devvp) > 1 && devvp != rootvp) return (EBUSY); - if ((error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0)) != 0) + PROC_LOCK(p); + uc = p->p_ucred; + crhold(uc); + PROC_UNLOCK(p); + if ((error = vinvalbuf(devvp, V_SAVE, uc, p, 0, 0)) != 0) { + crfree(uc); return (error); + } + crfree(uc); #ifdef READONLY /* turn on this to force it to be read-only */ mp->mnt_flag |= MNT_RDONLY; diff --git a/sys/gnu/fs/ext2fs/ext2_readwrite.c b/sys/gnu/fs/ext2fs/ext2_readwrite.c index 30a2f56..64065c3 100644 --- a/sys/gnu/fs/ext2fs/ext2_readwrite.c +++ b/sys/gnu/fs/ext2fs/ext2_readwrite.c @@ -217,6 +217,8 @@ WRITE(ap) * file servers have no limits, I don't think it matters. */ p = uio->uio_procp; + /* For p_rlimit. */ + mtx_assert(&Giant, MA_OWNED); if (vp->v_type == VREG && p && uio->uio_offset + uio->uio_resid > p->p_rlimit[RLIMIT_FSIZE].rlim_cur) { diff --git a/sys/gnu/fs/ext2fs/ext2_vfsops.c b/sys/gnu/fs/ext2fs/ext2_vfsops.c index cbaac5e..12682e4 100644 --- a/sys/gnu/fs/ext2fs/ext2_vfsops.c +++ b/sys/gnu/fs/ext2fs/ext2_vfsops.c @@ -188,6 +188,7 @@ ext2_mount(mp, path, data, ndp, p) struct vnode *devvp; struct ufs_args args; struct ufsmount *ump = 0; + struct ucred *uc; register struct ext2_sb_info *fs; size_t size; int error, flags; @@ -230,13 +231,19 @@ ext2_mount(mp, path, data, ndp, p) * 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) { + if (suser(p)) { vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p); + PROC_LOCK(p); + uc = p->p_ucred; + crhold(uc); + PROC_UNLOCK(p); if ((error = VOP_ACCESS(devvp, VREAD | VWRITE, - p->p_ucred, p)) != 0) { + uc, p)) != 0) { + crfree(uc); VOP_UNLOCK(devvp, 0, p); return (error); } + crfree(uc); VOP_UNLOCK(devvp, 0, p); } @@ -283,15 +290,21 @@ ext2_mount(mp, path, data, ndp, p) * If mount by non-root, then verify that user has necessary * permissions on the device. */ - if (p->p_ucred->cr_uid != 0) { + if (suser(p)) { 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)) != 0) { + PROC_LOCK(p); + uc = p->p_ucred; + crhold(uc); + PROC_UNLOCK(p); + if ((error = VOP_ACCESS(devvp, accessmode, uc, p)) != 0) { + crfree(uc); vput(devvp); return (error); } + crfree(uc); VOP_UNLOCK(devvp, 0, p); } @@ -617,6 +630,7 @@ ext2_mountfs(devvp, mp, p) { register struct ufsmount *ump; struct buf *bp; + struct ucred *uc; register struct ext2_sb_info *fs; struct ext2_super_block * es; dev_t dev = devvp->v_rdev; @@ -635,8 +649,15 @@ ext2_mountfs(devvp, mp, p) return (error); if (vcount(devvp) > 1 && devvp != rootvp) return (EBUSY); - if ((error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0)) != 0) + PROC_LOCK(p); + uc = p->p_ucred; + crhold(uc); + PROC_UNLOCK(p); + if ((error = vinvalbuf(devvp, V_SAVE, uc, p, 0, 0)) != 0) { + crfree(uc); return (error); + } + crfree(uc); #ifdef READONLY /* turn on this to force it to be read-only */ mp->mnt_flag |= MNT_RDONLY; |