Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 22 Oct 1995 04:40:03 -0700
From:      David Greenman <davidg@Root.COM>
To:        Heikki Suonsivu <hsu@cs.hut.fi>
Cc:        "Jordan K. Hubbard" <jkh@time.cdrom.com>, stable@freebsd.org
Subject:   Re: 2.1.0-951020-SNAP - 2.1 *Release Candidate* 
Message-ID:  <199510221140.EAA04058@corbin.Root.COM>
In-Reply-To: Your message of "Sun, 22 Oct 95 08:55:30 %2B0200." <199510220655.IAA12565@shadows.cs.hut.fi> 

next in thread | previous in thread | raw e-mail | index | archive | help
>Sorry, I forgot about using sed :-(

   I recommend removing any device drivers from your kernel that you are not
using - the matcd driver, for instance, and many others.

   I need you to install and test the attached patches. This needs to be done
*ASAP* if there will be any hope for these fixes to be in the 2.1 release.
Please start testing these as soon as possible and tell me if they 1) fix the
problem you are having and 2) don't cause any other problems. I'm especially
interested in problems with NFS client operation and any new problems with
msdosfs (I already know about it's old bugs :-)).
   I welcome feedback from other people, too...

-DG

Index: isofs/cd9660/cd9660_lookup.c
===================================================================
RCS file: /home/ncvs/src/sys/isofs/cd9660/cd9660_lookup.c,v
retrieving revision 1.7
diff -c -r1.7 cd9660_lookup.c
*** 1.7	1995/05/30 08:04:57
--- cd9660_lookup.c	1995/10/22 11:08:09
***************
*** 142,147 ****
--- 142,150 ----
  	    return (ENOTDIR);
  	if ((error = VOP_ACCESS(vdp, VEXEC, cred, cnp->cn_proc)))
  		return (error);
+ 	if ((flags & ISLASTCN) && (vdp->v_mount->mnt_flag & MNT_RDONLY) &&
+ 	    (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
+ 		return (EROFS);
  
  	/*
  	 * We now have a segment name to search for, and a directory to search.
Index: kern/vfs_lookup.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_lookup.c,v
retrieving revision 1.7.4.2
diff -c -r1.7.4.2 vfs_lookup.c
*** 1.7.4.2	1995/09/12 08:39:06
--- vfs_lookup.c	1995/10/22 11:08:09
***************
*** 422,428 ****
  		 * If creating and at end of pathname, then can consider
  		 * allowing file to be created.
  		 */
! 		if (rdonly || (ndp->ni_dvp->v_mount->mnt_flag & MNT_RDONLY)) {
  			error = EROFS;
  			goto bad;
  		}
--- 422,428 ----
  		 * If creating and at end of pathname, then can consider
  		 * allowing file to be created.
  		 */
! 		if (rdonly) {
  			error = EROFS;
  			goto bad;
  		}
***************
*** 510,528 ****
  		goto dirloop;
  	}
  	/*
! 	 * Check for read-only file systems.
  	 */
! 	if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME) {
! 		/*
! 		 * Disallow directory write attempts on read-only
! 		 * file systems.
! 		 */
! 		if (rdonly || (dp->v_mount->mnt_flag & MNT_RDONLY) ||
! 		    (wantparent &&
! 		     (ndp->ni_dvp->v_mount->mnt_flag & MNT_RDONLY))) {
! 			error = EROFS;
! 			goto bad2;
! 		}
  	}
  	if (cnp->cn_flags & SAVESTART) {
  		ndp->ni_startdir = ndp->ni_dvp;
--- 510,521 ----
  		goto dirloop;
  	}
  	/*
! 	 * Disallow directory write attempts on read-only file systems.
  	 */
! 	if (rdonly &&
! 	    (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) {
! 		error = EROFS;
! 		goto bad2;
  	}
  	if (cnp->cn_flags & SAVESTART) {
  		ndp->ni_startdir = ndp->ni_dvp;
***************
*** 638,644 ****
  		 * If creating and at end of pathname, then can consider
  		 * allowing file to be created.
  		 */
! 		if (rdonly || (dvp->v_mount->mnt_flag & MNT_RDONLY)) {
  			error = EROFS;
  			goto bad;
  		}
--- 631,637 ----
  		 * If creating and at end of pathname, then can consider
  		 * allowing file to be created.
  		 */
! 		if (rdonly) {
  			error = EROFS;
  			goto bad;
  		}
***************
*** 663,681 ****
  #endif
  
  	/*
! 	 * Check for read-only file systems.
  	 */
! 	if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME) {
! 		/*
! 		 * Disallow directory write attempts on read-only
! 		 * file systems.
! 		 */
! 		if (rdonly || (dp->v_mount->mnt_flag & MNT_RDONLY) ||
! 		    (wantparent &&
! 		     (dvp->v_mount->mnt_flag & MNT_RDONLY))) {
! 			error = EROFS;
! 			goto bad2;
! 		}
  	}
  	/* ASSERT(dvp == ndp->ni_startdir) */
  	if (cnp->cn_flags & SAVESTART)
--- 656,667 ----
  #endif
  
  	/*
! 	 * Disallow directory write attempts on read-only file systems.
  	 */
! 	if (rdonly &&
! 	    (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) {
! 		error = EROFS;
! 		goto bad2;
  	}
  	/* ASSERT(dvp == ndp->ni_startdir) */
  	if (cnp->cn_flags & SAVESTART)
Index: kern/vfs_syscalls.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.25.4.2
diff -c -r1.25.4.2 vfs_syscalls.c
*** 1.25.4.2	1995/09/18 05:30:19
--- vfs_syscalls.c	1995/10/22 11:08:10
***************
*** 1391,1403 ****
  	vp = nd.ni_vp;
  	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
  	VOP_LOCK(vp);
! 	if (vp->v_mount->mnt_flag & MNT_RDONLY)
! 		error = EROFS;
! 	else {
! 		VATTR_NULL(&vattr);
! 		vattr.va_flags = uap->flags;
! 		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
! 	}
  	vput(vp);
  	return (error);
  }
--- 1391,1399 ----
  	vp = nd.ni_vp;
  	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
  	VOP_LOCK(vp);
! 	VATTR_NULL(&vattr);
! 	vattr.va_flags = uap->flags;
! 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
  	vput(vp);
  	return (error);
  }
***************
*** 1427,1439 ****
  	vp = (struct vnode *)fp->f_data;
  	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
  	VOP_LOCK(vp);
! 	if (vp->v_mount->mnt_flag & MNT_RDONLY)
! 		error = EROFS;
! 	else {
! 		VATTR_NULL(&vattr);
! 		vattr.va_flags = uap->flags;
! 		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
! 	}
  	VOP_UNLOCK(vp);
  	return (error);
  }
--- 1423,1431 ----
  	vp = (struct vnode *)fp->f_data;
  	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
  	VOP_LOCK(vp);
! 	VATTR_NULL(&vattr);
! 	vattr.va_flags = uap->flags;
! 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
  	VOP_UNLOCK(vp);
  	return (error);
  }
***************
*** 1464,1476 ****
  	vp = nd.ni_vp;
  	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
  	VOP_LOCK(vp);
! 	if (vp->v_mount->mnt_flag & MNT_RDONLY)
! 		error = EROFS;
! 	else {
! 		VATTR_NULL(&vattr);
! 		vattr.va_mode = uap->mode & ALLPERMS;
! 		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
! 	}
  	vput(vp);
  	return (error);
  }
--- 1456,1464 ----
  	vp = nd.ni_vp;
  	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
  	VOP_LOCK(vp);
! 	VATTR_NULL(&vattr);
! 	vattr.va_mode = uap->mode & ALLPERMS;
! 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
  	vput(vp);
  	return (error);
  }
***************
*** 1500,1512 ****
  	vp = (struct vnode *)fp->f_data;
  	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
  	VOP_LOCK(vp);
! 	if (vp->v_mount->mnt_flag & MNT_RDONLY)
! 		error = EROFS;
! 	else {
! 		VATTR_NULL(&vattr);
! 		vattr.va_mode = uap->mode & ALLPERMS;
! 		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
! 	}
  	VOP_UNLOCK(vp);
  	return (error);
  }
--- 1488,1496 ----
  	vp = (struct vnode *)fp->f_data;
  	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
  	VOP_LOCK(vp);
! 	VATTR_NULL(&vattr);
! 	vattr.va_mode = uap->mode & ALLPERMS;
! 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
  	VOP_UNLOCK(vp);
  	return (error);
  }
***************
*** 1538,1551 ****
  	vp = nd.ni_vp;
  	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
  	VOP_LOCK(vp);
! 	if (vp->v_mount->mnt_flag & MNT_RDONLY)
! 		error = EROFS;
! 	else {
! 		VATTR_NULL(&vattr);
! 		vattr.va_uid = uap->uid;
! 		vattr.va_gid = uap->gid;
! 		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
! 	}
  	vput(vp);
  	return (error);
  }
--- 1522,1531 ----
  	vp = nd.ni_vp;
  	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
  	VOP_LOCK(vp);
! 	VATTR_NULL(&vattr);
! 	vattr.va_uid = uap->uid;
! 	vattr.va_gid = uap->gid;
! 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
  	vput(vp);
  	return (error);
  }
***************
*** 1576,1589 ****
  	vp = (struct vnode *)fp->f_data;
  	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
  	VOP_LOCK(vp);
! 	if (vp->v_mount->mnt_flag & MNT_RDONLY)
! 		error = EROFS;
! 	else {
! 		VATTR_NULL(&vattr);
! 		vattr.va_uid = uap->uid;
! 		vattr.va_gid = uap->gid;
! 		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
! 	}
  	VOP_UNLOCK(vp);
  	return (error);
  }
--- 1556,1565 ----
  	vp = (struct vnode *)fp->f_data;
  	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
  	VOP_LOCK(vp);
! 	VATTR_NULL(&vattr);
! 	vattr.va_uid = uap->uid;
! 	vattr.va_gid = uap->gid;
! 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
  	VOP_UNLOCK(vp);
  	return (error);
  }
***************
*** 1625,1639 ****
  	vp = nd.ni_vp;
  	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
  	VOP_LOCK(vp);
! 	if (vp->v_mount->mnt_flag & MNT_RDONLY)
! 		error = EROFS;
! 	else {
! 		vattr.va_atime.ts_sec = tv[0].tv_sec;
! 		vattr.va_atime.ts_nsec = tv[0].tv_usec * 1000;
! 		vattr.va_mtime.ts_sec = tv[1].tv_sec;
! 		vattr.va_mtime.ts_nsec = tv[1].tv_usec * 1000;
! 		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
! 	}
  	vput(vp);
  	return (error);
  }
--- 1601,1611 ----
  	vp = nd.ni_vp;
  	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
  	VOP_LOCK(vp);
! 	vattr.va_atime.ts_sec = tv[0].tv_sec;
! 	vattr.va_atime.ts_nsec = tv[0].tv_usec * 1000;
! 	vattr.va_mtime.ts_sec = tv[1].tv_sec;
! 	vattr.va_mtime.ts_nsec = tv[1].tv_usec * 1000;
! 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
  	vput(vp);
  	return (error);
  }
Index: kern/vfs_vnops.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_vnops.c,v
retrieving revision 1.11.4.3
diff -c -r1.11.4.3 vfs_vnops.c
*** 1.11.4.3	1995/08/24 05:29:36
--- vfs_vnops.c	1995/10/22 11:08:10
***************
*** 199,217 ****
  {
  
  	/*
- 	 * Disallow write attempts on read-only file systems;
- 	 * unless the file is a socket or a block or character
- 	 * device resident on the file system.
- 	 */
- 	if (vp->v_mount->mnt_flag & MNT_RDONLY) {
- 		switch (vp->v_type) {
- 		case VREG: case VDIR: case VLNK:
- 			return (EROFS);
- 		default:
- 			break;
- 		}
- 	}
- 	/*
  	 * If there's shared text associated with
  	 * the vnode, try to free it up once.  If
  	 * we fail, we can't allow writing.
--- 199,204 ----
Index: msdosfs/msdosfs_vnops.c
===================================================================
RCS file: /home/ncvs/src/sys/msdosfs/msdosfs_vnops.c,v
retrieving revision 1.17.2.3
diff -c -r1.17.2.3 msdosfs_vnops.c
*** 1.17.2.3	1995/10/09 06:13:08
--- msdosfs_vnops.c	1995/10/22 11:08:11
***************
*** 204,227 ****
  	return 0;
  }
  
! /*
!  * This routine will go into sys/kern/vfs_subr.c one day!
!  *
!  * Do the usual access checking.
!  * file_node, uid and gid are from the vnode in question,
!  * while acc_mode and cred are from the VOP_ACCESS parameter list.
!  */
! static int
! vaccess(file_mode, uid, gid, acc_mode, cred)
! 	mode_t file_mode;
! 	uid_t uid;
! 	gid_t gid;
! 	mode_t acc_mode;
! 	struct ucred *cred;
  {
! 	mode_t mask;
! 	int i;
  	register gid_t *gp;
  
  	/* User id 0 always gets access. */
  	if (cred->cr_uid == 0)
--- 204,245 ----
  	return 0;
  }
  
! int
! msdosfs_access(ap)
! 	struct vop_access_args /* {
! 		struct vnode *a_vp;
! 		int a_mode;
! 		struct ucred *a_cred;
! 		struct proc *a_p;
! 	} */ *ap;
  {
! 	struct vnode *vp = ap->a_vp;
! 	struct denode *dep = VTODE(ap->a_vp);
! 	struct msdosfsmount *pmp = dep->de_pmp;
! 	struct ucred *cred = ap->a_cred;
! 	mode_t mask, file_mode, mode = ap->a_mode;
  	register gid_t *gp;
+ 	int i;
+ 
+ 	file_mode = (S_IXUSR|S_IXGRP|S_IXOTH) | (S_IRUSR|S_IRGRP|S_IROTH) |
+ 	    ((dep->de_Attributes & ATTR_READONLY) ? 0 : (S_IWUSR|S_IWGRP|S_IWOTH));
+ 	file_mode &= pmp->pm_mask;
+ 
+ 	/*
+ 	 * Disallow write attempts on read-only file systems;
+ 	 * unless the file is a socket, fifo, or a block or
+ 	 * character device resident on the file system.
+ 	 */
+ 	if (mode & VWRITE) {
+ 		switch (vp->v_type) {
+ 		case VDIR:
+ 		case VLNK:
+ 		case VREG:
+ 			if (vp->v_mount->mnt_flag & MNT_RDONLY)
+ 				return (EROFS);
+ 			break;
+ 		}
+ 	}
  
  	/* User id 0 always gets access. */
  	if (cred->cr_uid == 0)
***************
*** 230,288 ****
  	mask = 0;
  
  	/* Otherwise, check the owner. */
! 	if (cred->cr_uid == uid) {
! 		if (acc_mode & VEXEC)
  			mask |= S_IXUSR;
! 		if (acc_mode & VREAD)
  			mask |= S_IRUSR;
! 		if (acc_mode & VWRITE)
  			mask |= S_IWUSR;
  		return (file_mode & mask) == mask ? 0 : EACCES;
  	}
  
  	/* Otherwise, check the groups. */
  	for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++)
! 		if (gid == *gp) {
! 			if (acc_mode & VEXEC)
  				mask |= S_IXGRP;
! 			if (acc_mode & VREAD)
  				mask |= S_IRGRP;
! 			if (acc_mode & VWRITE)
  				mask |= S_IWGRP;
  			return (file_mode & mask) == mask ? 0 : EACCES;
  		}
  
  	/* Otherwise, check everyone else. */
! 	if (acc_mode & VEXEC)
  		mask |= S_IXOTH;
! 	if (acc_mode & VREAD)
  		mask |= S_IROTH;
! 	if (acc_mode & VWRITE)
  		mask |= S_IWOTH;
  	return (file_mode & mask) == mask ? 0 : EACCES;
  }
  
  int
- msdosfs_access(ap)
- 	struct vop_access_args /* {
- 		struct vnode *a_vp;
- 		int a_mode;
- 		struct ucred *a_cred;
- 		struct proc *a_p;
- 	} */ *ap;
- {
- 	mode_t dosmode;
- 	struct denode *dep = VTODE(ap->a_vp);
- 	struct msdosfsmount *pmp = dep->de_pmp;
- 
- 	dosmode = (S_IXUSR|S_IXGRP|S_IXOTH) | (S_IRUSR|S_IRGRP|S_IROTH) |
- 	    ((dep->de_Attributes & ATTR_READONLY) ? 0 : (S_IWUSR|S_IWGRP|S_IWOTH));
- 	dosmode &= pmp->pm_mask;
- 
- 	return vaccess(dosmode, pmp->pm_uid, pmp->pm_gid, ap->a_mode, ap->a_cred);
- }
- 
- int
  msdosfs_getattr(ap)
  	struct vop_getattr_args /* {
  		struct vnode *a_vp;
--- 248,286 ----
  	mask = 0;
  
  	/* Otherwise, check the owner. */
! 	if (cred->cr_uid == pmp->pm_uid) {
! 		if (mode & VEXEC)
  			mask |= S_IXUSR;
! 		if (mode & VREAD)
  			mask |= S_IRUSR;
! 		if (mode & VWRITE)
  			mask |= S_IWUSR;
  		return (file_mode & mask) == mask ? 0 : EACCES;
  	}
  
  	/* Otherwise, check the groups. */
  	for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++)
! 		if (pmp->pm_gid == *gp) {
! 			if (mode & VEXEC)
  				mask |= S_IXGRP;
! 			if (mode & VREAD)
  				mask |= S_IRGRP;
! 			if (mode & VWRITE)
  				mask |= S_IWGRP;
  			return (file_mode & mask) == mask ? 0 : EACCES;
  		}
  
  	/* Otherwise, check everyone else. */
! 	if (mode & VEXEC)
  		mask |= S_IXOTH;
! 	if (mode & VREAD)
  		mask |= S_IROTH;
! 	if (mode & VWRITE)
  		mask |= S_IWOTH;
  	return (file_mode & mask) == mask ? 0 : EACCES;
  }
  
  int
  msdosfs_getattr(ap)
  	struct vop_getattr_args /* {
  		struct vnode *a_vp;
***************
*** 348,381 ****
  		struct proc *a_p;
  	} */ *ap;
  {
! 	int error = 0;
  	struct denode *dep = VTODE(ap->a_vp);
  	struct vattr *vap = ap->a_vap;
  	struct ucred *cred = ap->a_cred;
  
! #ifdef MSDOSFS_DEBUG
! 	printf("msdosfs_setattr(): vp %08x, vap %08x, cred %08x, p %08x\n",
! 	       ap->a_vp, vap, cred, ap->a_p);
! #endif
! 	if ((vap->va_type != VNON) ||
! 	    (vap->va_nlink != VNOVAL) ||
! 	    (vap->va_fsid != VNOVAL) ||
! 	    (vap->va_fileid != VNOVAL) ||
! 	    (vap->va_blocksize != VNOVAL) ||
! 	    (vap->va_rdev != VNOVAL) ||
! 	    (vap->va_bytes != VNOVAL) ||
! 	    (vap->va_gen != VNOVAL)) {
! #ifdef MSDOSFS_DEBUG
! 		printf("msdosfs_setattr(): returning EINVAL\n");
! 		printf("    va_type %d, va_nlink %x, va_fsid %x, va_fileid %x\n",
! 		       vap->va_type, vap->va_nlink, vap->va_fsid, vap->va_fileid);
! 		printf("    va_blocksize %x, va_rdev %x, va_bytes %x, va_gen %x\n",
! 		       vap->va_blocksize, vap->va_rdev, vap->va_bytes, vap->va_gen);
! #endif
! 		return EINVAL;
  	}
  
  	if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (uid_t)VNOVAL) {
  		if ((cred->cr_uid != dep->de_pmp->pm_uid ||
  		     vap->va_uid != dep->de_pmp->pm_uid ||
  		     (vap->va_gid != dep->de_pmp->pm_gid &&
--- 346,400 ----
  		struct proc *a_p;
  	} */ *ap;
  {
! 	struct vnode *vp = ap->a_vp;
  	struct denode *dep = VTODE(ap->a_vp);
  	struct vattr *vap = ap->a_vap;
  	struct ucred *cred = ap->a_cred;
+ 	int error = 0;
  
! 	/*
! 	 * Check for unsettable attributes.
! 	 */
! 	if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
! 	    (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
! 	    (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
! 	    (vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) {
! 		return (EINVAL);
! 	}
! 	if (vap->va_flags != VNOVAL) {
! 		if (vp->v_mount->mnt_flag & MNT_RDONLY)
! 			return (EROFS);
! 		if (cred->cr_uid != dep->de_pmp->pm_uid &&
! 		    (error = suser(cred, &ap->a_p->p_acflag)))
! 			return (error);
! 		/*
! 		 * We are very inconsistent about handling unsupported
! 		 * attributes.  We ignored the the access time and the
! 		 * read and execute bits.  We were strict for the other
! 		 * attributes.
! 		 *
! 		 * Here we are strict, stricter than ufs in not allowing
! 		 * users to attempt to set SF_SETTABLE bits or anyone to
! 		 * set unsupported bits.  However, we ignore attempts to
! 		 * set ATTR_ARCHIVE for directories `cp -pr' from a more
! 		 * sensible file system attempts it a lot.
! 		 */
! 		if (cred->cr_uid != 0) {
! 			if (vap->va_flags & SF_SETTABLE)
! 				return EPERM;
! 		}
! 		if (vap->va_flags & ~SF_ARCHIVED)
! 			return EINVAL;
! 		if (vap->va_flags & SF_ARCHIVED)
! 			dep->de_Attributes &= ~ATTR_ARCHIVE;
! 		else if (!(dep->de_Attributes & ATTR_DIRECTORY))
! 			dep->de_Attributes |= ATTR_ARCHIVE;
! 		dep->de_flag |= DE_MODIFIED;
  	}
  
  	if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (uid_t)VNOVAL) {
+ 		if (vp->v_mount->mnt_flag & MNT_RDONLY)
+ 			return (EROFS);
  		if ((cred->cr_uid != dep->de_pmp->pm_uid ||
  		     vap->va_uid != dep->de_pmp->pm_uid ||
  		     (vap->va_gid != dep->de_pmp->pm_gid &&
***************
*** 387,403 ****
  			return EINVAL;
  	}
  	if (vap->va_size != VNOVAL) {
! 		if (ap->a_vp->v_type == VDIR)
! 			return EISDIR;
  		error = detrunc(dep, vap->va_size, 0, cred, ap->a_p);
  		if (error)
  			return error;
  	}
  	if (vap->va_mtime.ts_sec != VNOVAL) {
  		if (cred->cr_uid != dep->de_pmp->pm_uid &&
  		    (error = suser(cred, &ap->a_p->p_acflag)) &&
  		    ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
! 		    (error = VOP_ACCESS(ap->a_vp, VWRITE, cred, ap->a_p))))
  			return error;
  		dep->de_flag |= DE_UPDATE;
  		error = deupdat(dep, &vap->va_mtime, 1);
--- 406,436 ----
  			return EINVAL;
  	}
  	if (vap->va_size != VNOVAL) {
! 		/*
! 		 * Disallow write attempts on read-only file systems;
! 		 * unless the file is a socket, fifo, or a block or
! 		 * character device resident on the file system.
! 		 */
! 		switch (vp->v_type) {
! 		case VDIR:
! 			return (EISDIR);
! 		case VLNK:
! 		case VREG:
! 			if (vp->v_mount->mnt_flag & MNT_RDONLY)
! 				return (EROFS);
! 			break;
! 		}
  		error = detrunc(dep, vap->va_size, 0, cred, ap->a_p);
  		if (error)
  			return error;
  	}
  	if (vap->va_mtime.ts_sec != VNOVAL) {
+ 		if (vp->v_mount->mnt_flag & MNT_RDONLY)
+ 			return (EROFS);
  		if (cred->cr_uid != dep->de_pmp->pm_uid &&
  		    (error = suser(cred, &ap->a_p->p_acflag)) &&
  		    ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
! 		    (error = VOP_ACCESS(vp, VWRITE, cred, ap->a_p))))
  			return error;
  		dep->de_flag |= DE_UPDATE;
  		error = deupdat(dep, &vap->va_mtime, 1);
***************
*** 410,416 ****
--- 443,452 ----
  	 * attribute set, so we use the owner write bit to set the readonly
  	 * attribute.
  	 */
+ 	error = 0;
  	if (vap->va_mode != (u_short) VNOVAL) {
+ 		if (vp->v_mount->mnt_flag & MNT_RDONLY)
+ 			return (EROFS);
  		if (cred->cr_uid != dep->de_pmp->pm_uid &&
  		    (error = suser(cred, &ap->a_p->p_acflag)))
  			return error;
***************
*** 420,454 ****
  			dep->de_Attributes &= ~ATTR_READONLY;
  		else
  			dep->de_Attributes |= ATTR_READONLY;
- 		dep->de_flag |= DE_MODIFIED;
- 	}
- 
- 	if (vap->va_flags != VNOVAL) {
- 		if (cred->cr_uid != dep->de_pmp->pm_uid &&
- 		    (error = suser(cred, &ap->a_p->p_acflag)))
- 			return error;
- 		/*
- 		 * We are very inconsistent about handling unsupported
- 		 * attributes.  We ignored the the access time and the
- 		 * read and execute bits.  We were strict for the other
- 		 * attributes.
- 		 *
- 		 * Here we are strict, stricter than ufs in not allowing
- 		 * users to attempt to set SF_SETTABLE bits or anyone to
- 		 * set unsupported bits.  However, we ignore attempts to
- 		 * set ATTR_ARCHIVE for directories `cp -pr' from a more
- 		 * sensible file system attempts it a lot.
- 		 */
- 		if (cred->cr_uid != 0) {
- 			if (vap->va_flags & SF_SETTABLE)
- 				return EPERM;
- 		}
- 		if (vap->va_flags & ~SF_ARCHIVED)
- 			return EINVAL;
- 		if (vap->va_flags & SF_ARCHIVED)
- 			dep->de_Attributes &= ~ATTR_ARCHIVE;
- 		else if (!(dep->de_Attributes & ATTR_DIRECTORY))
- 			dep->de_Attributes |= ATTR_ARCHIVE;
  		dep->de_flag |= DE_MODIFIED;
  	}
  	return error;
--- 456,461 ----
Index: nfs/nfs_vnops.c
===================================================================
RCS file: /home/ncvs/src/sys/nfs/nfs_vnops.c,v
retrieving revision 1.15.4.1
diff -c -r1.15.4.1 nfs_vnops.c
*** 1.15.4.1	1995/07/25 07:47:54
--- nfs_vnops.c	1995/10/22 11:28:13
***************
*** 282,287 ****
--- 282,298 ----
  	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
  
  	/*
+ 	 * Disallow write attempts on filesystems mounted read-only;
+ 	 * unless the file is a socket, fifo, or a block or character
+ 	 * device resident on the filesystem.
+ 	 */
+ 	if ((ap->a_mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) {
+ 		switch (vp->v_type) {
+ 		case VREG: case VDIR: case VLNK:
+ 			return (EROFS);
+ 		}
+ 	}
+ 	/*
  	 * For nqnfs, do an access rpc, otherwise you are stuck emulating
  	 * ufs_access() locally using the vattr. This may not be correct,
  	 * since the server may apply other access criteria such as
***************
*** 481,486 ****
--- 492,505 ----
  	register struct vattr *vap = ap->a_vap;
  	u_quad_t frev, tsize = 0;
  
+ 	/*
+ 	 * Disallow write attempts if the filesystem is mounted read-only.
+ 	 */
+ 	if ((vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL ||
+ 	    vap->va_gid != (gid_t)VNOVAL || vap->va_atime.ts_sec != VNOVAL ||
+ 	    vap->va_mtime.ts_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) &&
+ 	    (vp->v_mount->mnt_flag & MNT_RDONLY))
+ 		return (EROFS);
  	if (vap->va_size != VNOVAL) {
  		switch (vp->v_type) {
  		case VDIR:
***************
*** 496,501 ****
--- 515,526 ----
  			vap->va_size = VNOVAL;
  			break;
  		default:
+ 			/*
+ 			 * Disallow write attempts if the filesystem is
+ 			 * mounted read-only.
+ 			 */
+ 			if (vp->v_mount->mnt_flag & MNT_RDONLY)
+ 				return (EROFS);
  			if (np->n_flag & NMODIFIED) {
  				error = nfs_vinvalbuf(vp,
  					vap->va_size ? V_SAVE : 0,
***************
*** 592,597 ****
--- 617,625 ----
  	int nqlflag = 0, cachable = 0;
  	u_quad_t frev;
  
+ 	if ((flags & ISLASTCN) && (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
+ 	    (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
+ 		return (EROFS);
  	*vpp = NULL;
  	if (dvp->v_type != VDIR)
  		return (ENOTDIR);
***************
*** 2379,2389 ****
--- 2407,2429 ----
  	register struct vattr *vap;
  	register gid_t *gp;
  	register struct ucred *cred = ap->a_cred;
+ 	struct vnode *vp = ap->a_vp;
  	mode_t mode = ap->a_mode;
  	struct vattr vattr;
  	register int i;
  	int error;
  
+ 	/*
+ 	 * Disallow write attempts on filesystems mounted read-only;
+ 	 * unless the file is a socket, fifo, or a block or character
+ 	 * device resident on the filesystem.
+ 	 */
+ 	if ((mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) {
+ 		switch (vp->v_type) {
+ 		case VREG: case VDIR: case VLNK:
+ 			return (EROFS);
+ 		}
+ 	}
  	/*
  	 * If you're the super-user,
  	 * you always get access.
Index: ufs/ufs/ufs_lookup.c
===================================================================
RCS file: /home/ncvs/src/sys/ufs/ufs/ufs_lookup.c,v
retrieving revision 1.3
diff -c -r1.3 ufs_lookup.c
*** 1.3	1994/10/08 06:57:26
--- ufs_lookup.c	1995/10/22 11:08:11
***************
*** 145,150 ****
--- 145,153 ----
  	error = VOP_ACCESS(vdp, VEXEC, cred, cnp->cn_proc);
  	if (error)
  		return (error);
+ 	if ((flags & ISLASTCN) && (vdp->v_mount->mnt_flag & MNT_RDONLY) &&
+ 	    (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
+ 		return (EROFS);
  
  	/*
  	 * We now have a segment name to search for, and a directory to search.
Index: ufs/ufs/ufs_vnops.c
===================================================================
RCS file: /home/ncvs/src/sys/ufs/ufs/ufs_vnops.c,v
retrieving revision 1.24.4.2
diff -c -r1.24.4.2 ufs_vnops.c
*** 1.24.4.2	1995/10/09 07:42:46
--- ufs_vnops.c	1995/10/22 11:08:11
***************
*** 122,130 ****
  		struct vattr *a_vap;
  	} */ *ap;
  {
! 	register struct vattr *vap = ap->a_vap;
! 	register struct vnode **vpp = ap->a_vpp;
! 	register struct inode *ip;
  	int error;
  
  	error = ufs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode),
--- 122,130 ----
  		struct vattr *a_vap;
  	} */ *ap;
  {
! 	struct vattr *vap = ap->a_vap;
! 	struct vnode **vpp = ap->a_vpp;
! 	struct inode *ip;
  	int error;
  
  	error = ufs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode),
***************
*** 209,241 ****
  		struct proc *a_p;
  	} */ *ap;
  {
! 	register struct vnode *vp = ap->a_vp;
! 	register struct inode *ip = VTOI(vp);
! 	register struct ucred *cred = ap->a_cred;
  	mode_t mask, mode = ap->a_mode;
  	register gid_t *gp;
! 	int i;
! #ifdef QUOTA
! 	int error;
! #endif
  
! #ifdef DIAGNOSTIC
! 	if (!VOP_ISLOCKED(vp)) {
! 		vprint("ufs_access: not locked", vp);
! 		panic("ufs_access: not locked");
! 	}
! #endif
! #ifdef QUOTA
! 	if (mode & VWRITE)
  		switch (vp->v_type) {
  		case VDIR:
  		case VLNK:
  		case VREG:
  			if (error = getinoquota(ip))
  				return (error);
  			break;
  		}
! #endif
  
  	/* If immutable bit set, nobody gets to write it. */
  	if ((mode & VWRITE) && (ip->i_flags & IMMUTABLE))
--- 209,240 ----
  		struct proc *a_p;
  	} */ *ap;
  {
! 	struct vnode *vp = ap->a_vp;
! 	struct inode *ip = VTOI(vp);
! 	struct ucred *cred = ap->a_cred;
  	mode_t mask, mode = ap->a_mode;
  	register gid_t *gp;
! 	int i, error;
  
! 	/*
! 	 * Disallow write attempts on read-only file systems;
! 	 * unless the file is a socket, fifo, or a block or
! 	 * character device resident on the file system.
! 	 */
! 	if (mode & VWRITE) {
  		switch (vp->v_type) {
  		case VDIR:
  		case VLNK:
  		case VREG:
+ 			if (vp->v_mount->mnt_flag & MNT_RDONLY)
+ 				return (EROFS);
+ #ifdef QUOTA
  			if (error = getinoquota(ip))
  				return (error);
+ #endif
  			break;
  		}
! 	}
  
  	/* If immutable bit set, nobody gets to write it. */
  	if ((mode & VWRITE) && (ip->i_flags & IMMUTABLE))
***************
*** 336,346 ****
  		struct proc *a_p;
  	} */ *ap;
  {
! 	register struct vattr *vap = ap->a_vap;
! 	register struct vnode *vp = ap->a_vp;
! 	register struct inode *ip = VTOI(vp);
! 	register struct ucred *cred = ap->a_cred;
! 	register struct proc *p = ap->a_p;
  	struct timeval atimeval, mtimeval;
  	int error;
  
--- 335,345 ----
  		struct proc *a_p;
  	} */ *ap;
  {
! 	struct vattr *vap = ap->a_vap;
! 	struct vnode *vp = ap->a_vp;
! 	struct inode *ip = VTOI(vp);
! 	struct ucred *cred = ap->a_cred;
! 	struct proc *p = ap->a_p;
  	struct timeval atimeval, mtimeval;
  	int error;
  
***************
*** 354,359 ****
--- 353,360 ----
  		return (EINVAL);
  	}
  	if (vap->va_flags != VNOVAL) {
+ 		if (vp->v_mount->mnt_flag & MNT_RDONLY)
+ 			return (EROFS);
  		if (cred->cr_uid != ip->i_uid &&
  		    (error = suser(cred, &p->p_acflag)))
  			return (error);
***************
*** 378,396 ****
  	 * Go through the fields and update iff not VNOVAL.
  	 */
  	if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) {
  		error = ufs_chown(vp, vap->va_uid, vap->va_gid, cred, p);
  		if (error)
  			return (error);
  	}
  	if (vap->va_size != VNOVAL) {
! 		if (vp->v_type == VDIR)
  			return (EISDIR);
  		error = VOP_TRUNCATE(vp, vap->va_size, 0, cred, p);
  		if (error)
  			return (error);
  	}
  	ip = VTOI(vp);
  	if (vap->va_atime.ts_sec != VNOVAL || vap->va_mtime.ts_sec != VNOVAL) {
  		if (cred->cr_uid != ip->i_uid &&
  		    (error = suser(cred, &p->p_acflag)) &&
  		    ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
--- 379,413 ----
  	 * Go through the fields and update iff not VNOVAL.
  	 */
  	if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) {
+ 		if (vp->v_mount->mnt_flag & MNT_RDONLY)
+ 			return (EROFS);
  		error = ufs_chown(vp, vap->va_uid, vap->va_gid, cred, p);
  		if (error)
  			return (error);
  	}
  	if (vap->va_size != VNOVAL) {
! 		/*
! 		 * Disallow write attempts on read-only file systems;
! 		 * unless the file is a socket, fifo, or a block or
! 		 * character device resident on the file system.
! 		 */
! 		switch (vp->v_type) {
! 		case VDIR:
  			return (EISDIR);
+ 		case VLNK:
+ 		case VREG:
+ 			if (vp->v_mount->mnt_flag & MNT_RDONLY)
+ 				return (EROFS);
+ 			break;
+ 		}
  		error = VOP_TRUNCATE(vp, vap->va_size, 0, cred, p);
  		if (error)
  			return (error);
  	}
  	ip = VTOI(vp);
  	if (vap->va_atime.ts_sec != VNOVAL || vap->va_mtime.ts_sec != VNOVAL) {
+ 		if (vp->v_mount->mnt_flag & MNT_RDONLY)
+ 			return (EROFS);
  		if (cred->cr_uid != ip->i_uid &&
  		    (error = suser(cred, &p->p_acflag)) &&
  		    ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
***************
*** 409,416 ****
  			return (error);
  	}
  	error = 0;
! 	if (vap->va_mode != (mode_t)VNOVAL)
  		error = ufs_chmod(vp, (int)vap->va_mode, cred, p);
  	return (error);
  }
  
--- 426,436 ----
  			return (error);
  	}
  	error = 0;
! 	if (vap->va_mode != (mode_t)VNOVAL) {
! 		if (vp->v_mount->mnt_flag & MNT_RDONLY)
! 			return (EROFS);
  		error = ufs_chmod(vp, (int)vap->va_mode, cred, p);
+ 	}
  	return (error);
  }
  
***************
*** 636,644 ****
  		struct componentname *a_cnp;
  	} */ *ap;
  {
! 	register struct inode *ip;
! 	register struct vnode *vp = ap->a_vp;
! 	register struct vnode *dvp = ap->a_dvp;
  	int error;
  
  	ip = VTOI(vp);
--- 656,664 ----
  		struct componentname *a_cnp;
  	} */ *ap;
  {
! 	struct inode *ip;
! 	struct vnode *vp = ap->a_vp;
! 	struct vnode *dvp = ap->a_dvp;
  	int error;
  
  	ip = VTOI(vp);
***************
*** 671,680 ****
  		struct componentname *a_cnp;
  	} */ *ap;
  {
! 	register struct vnode *vp = ap->a_vp;
! 	register struct vnode *tdvp = ap->a_tdvp;
! 	register struct componentname *cnp = ap->a_cnp;
! 	register struct inode *ip;
  	struct timeval tv;
  	int error;
  
--- 691,700 ----
  		struct componentname *a_cnp;
  	} */ *ap;
  {
! 	struct vnode *vp = ap->a_vp;
! 	struct vnode *tdvp = ap->a_tdvp;
! 	struct componentname *cnp = ap->a_cnp;
! 	struct inode *ip;
  	struct timeval tv;
  	int error;
  
***************
*** 760,769 ****
  	struct vnode *tvp = ap->a_tvp;
  	register struct vnode *tdvp = ap->a_tdvp;
  	struct vnode *fvp = ap->a_fvp;
! 	register struct vnode *fdvp = ap->a_fdvp;
! 	register struct componentname *tcnp = ap->a_tcnp;
! 	register struct componentname *fcnp = ap->a_fcnp;
! 	register struct inode *ip, *xp, *dp;
  	struct dirtemplate dirbuf;
  	struct timeval tv;
  	int doingdirectory = 0, oldparent = 0, newparent = 0;
--- 780,789 ----
  	struct vnode *tvp = ap->a_tvp;
  	register struct vnode *tdvp = ap->a_tdvp;
  	struct vnode *fvp = ap->a_fvp;
! 	struct vnode *fdvp = ap->a_fdvp;
! 	struct componentname *tcnp = ap->a_tcnp;
! 	struct componentname *fcnp = ap->a_fcnp;
! 	struct inode *ip, *xp, *dp;
  	struct dirtemplate dirbuf;
  	struct timeval tv;
  	int doingdirectory = 0, oldparent = 0, newparent = 0;
***************
*** 1264,1273 ****
  		struct componentname *a_cnp;
  	} */ *ap;
  {
! 	register struct vnode *vp = ap->a_vp;
! 	register struct vnode *dvp = ap->a_dvp;
! 	register struct componentname *cnp = ap->a_cnp;
! 	register struct inode *ip, *dp;
  	int error;
  
  	ip = VTOI(vp);
--- 1284,1293 ----
  		struct componentname *a_cnp;
  	} */ *ap;
  {
! 	struct vnode *vp = ap->a_vp;
! 	struct vnode *dvp = ap->a_dvp;
! 	struct componentname *cnp = ap->a_cnp;
! 	struct inode *ip, *dp;
  	int error;
  
  	ip = VTOI(vp);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199510221140.EAA04058>