summaryrefslogtreecommitdiffstats
path: root/sys/gnu
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2001-01-23 22:41:15 +0000
committerjhb <jhb@FreeBSD.org>2001-01-23 22:41:15 +0000
commit45daa2e3ce5127d3a90b289e0f3628ed66f7bce8 (patch)
tree4ff4ee72470aed31a91e531ffa7338143b8086bb /sys/gnu
parent24fda4f13ec981051ae684c13423bcc48885891f (diff)
downloadFreeBSD-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.c2
-rw-r--r--sys/gnu/ext2fs/ext2_vfsops.c31
-rw-r--r--sys/gnu/fs/ext2fs/ext2_readwrite.c2
-rw-r--r--sys/gnu/fs/ext2fs/ext2_vfsops.c31
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;
OpenPOWER on IntegriCloud