Subject: mount option symperm/nosymperm (was Re: bizarre symbolic link problem)
To: None <tech-kern@NetBSD.ORG>
From: enami tsugutomo <enami@but-b.or.jp>
List: tech-kern
Date: 10/27/1997 10:46:54
# moved from current-users to tech-kern.

matthew green <mrg@eterna.com.au> writes:

> my feelings on this are that:
> 	- symbolic link permissions should be enabled via a mount option,
> 	  eg `symperm', and
> 	- `nosymperm' should be the default, for at least 1.3.

I just implement as follows.  Please comments it, especially,

	* for current, which should be default?
	* should be standard mount option, or specific to some fs?

enami.

changes for kernel:
Index: kern/vfs_lookup.c
===================================================================
RCS file: /cvsroot/NetBSD/src/sys/kern/vfs_lookup.c,v
retrieving revision 1.1.1.7
diff -c -r1.1.1.7 vfs_lookup.c
*** vfs_lookup.c	1997/10/11 15:43:05	1.1.1.7
--- vfs_lookup.c	1997/10/27 01:08:05
***************
*** 168,177 ****
  			error = ELOOP;
  			break;
  		}
! 		error = VOP_ACCESS(ndp->ni_vp, VEXEC, cnp->cn_cred,
! 		    cnp->cn_proc);
! 		if (error != 0)
! 			break;
  		if (ndp->ni_pathlen > 1)
  			MALLOC(cp, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
  		else
--- 168,179 ----
  			error = ELOOP;
  			break;
  		}
! 		if (!(ndp->ni_vp->v_mount->mnt_flag & MNT_NOSYMPERM)) {
! 			error = VOP_ACCESS(ndp->ni_vp, VEXEC, cnp->cn_cred,
! 			    cnp->cn_proc);
! 			if (error != 0)
! 				break;
! 		}
  		if (ndp->ni_pathlen > 1)
  			MALLOC(cp, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
  		else
Index: kern/vfs_syscalls.c
===================================================================
RCS file: /cvsroot/NetBSD/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.1.1.26
diff -c -r1.1.1.26 vfs_syscalls.c
*** vfs_syscalls.c	1997/10/22 01:40:31	1.1.1.26
--- vfs_syscalls.c	1997/10/27 01:08:06
***************
*** 269,278 ****
  		mp->mnt_flag |= MNT_WANTRDWR;
  	mp->mnt_flag &=~ (MNT_NOSUID | MNT_NOEXEC | MNT_NODEV |
  	    MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_NOCOREDUMP |
! 	    MNT_NOATIME);
  	mp->mnt_flag |= SCARG(uap, flags) & (MNT_NOSUID | MNT_NOEXEC |
  	    MNT_NODEV | MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC |
! 	    MNT_NOCOREDUMP | MNT_NOATIME);
  	/*
  	 * Mount the filesystem.
  	 */
--- 269,278 ----
  		mp->mnt_flag |= MNT_WANTRDWR;
  	mp->mnt_flag &=~ (MNT_NOSUID | MNT_NOEXEC | MNT_NODEV |
  	    MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_NOCOREDUMP |
! 	    MNT_NOATIME | MNT_NOSYMPERM);
  	mp->mnt_flag |= SCARG(uap, flags) & (MNT_NOSUID | MNT_NOEXEC |
  	    MNT_NODEV | MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC |
! 	    MNT_NOCOREDUMP | MNT_NOATIME | MNT_NOSYMPERM);
  	/*
  	 * Mount the filesystem.
  	 */
***************
*** 1366,1372 ****
  	vp = nd.ni_vp;
  	if (vp->v_type != VLNK)
  		error = EINVAL;
! 	else if ((error = VOP_ACCESS(vp, VREAD, p->p_ucred, p)) == 0) {
  		aiov.iov_base = SCARG(uap, buf);
  		aiov.iov_len = SCARG(uap, count);
  		auio.uio_iov = &aiov;
--- 1366,1373 ----
  	vp = nd.ni_vp;
  	if (vp->v_type != VLNK)
  		error = EINVAL;
! 	else if (vp->v_mount->mnt_flag & MNT_NOSYMPERM ||
! 	    (error = VOP_ACCESS(vp, VREAD, p->p_ucred, p)) == 0) {
  		aiov.iov_base = SCARG(uap, buf);
  		aiov.iov_len = SCARG(uap, count);
  		auio.uio_iov = &aiov;
Index: sys/mount.h
===================================================================
RCS file: /cvsroot/NetBSD/src/sys/sys/mount.h,v
retrieving revision 1.1.1.14
diff -c -r1.1.1.14 mount.h
*** mount.h	1997/10/20 00:02:57	1.1.1.14
--- mount.h	1997/10/27 01:08:15
***************
*** 135,140 ****
--- 135,141 ----
  #define	MNT_ASYNC	0x00000040	/* file system written asynchronously */
  #define	MNT_NOCOREDUMP	0x00008000	/* don't write core dumps to this FS */
  #define MNT_NOATIME	0x04000000	/* Never update access times in fs */
+ #define MNT_NOSYMPERM	0x20000000	/* don't use symlink permission */
  
  /*
   * exported mount flags.
***************
*** 156,163 ****
  
  /*
   * Mask of flags that are visible to statfs()
   */
! #define	MNT_VISFLAGMASK	0x0400ffff
  
  /*
   * filesystem control flags.
--- 157,165 ----
  
  /*
   * Mask of flags that are visible to statfs()
+  * This overflows f_flags in struct statfs. XXX
   */
! #define	MNT_VISFLAGMASK	0x2400ffff
  
  /*
   * filesystem control flags.

changes for userland:
Index: mount/mntopts.h
===================================================================
RCS file: /cvsroot/NetBSD/src/sbin/mount/mntopts.h,v
retrieving revision 1.1.1.4
diff -c -r1.1.1.4 mntopts.h
*** mntopts.h	1997/09/17 15:39:41	1.1.1.4
--- mntopts.h	1997/10/27 01:06:32
***************
*** 54,59 ****
--- 54,60 ----
  #define MOPT_USERQUOTA		{ "userquota",	0, 0, 0 }
  #define MOPT_GROUPQUOTA		{ "groupquota",	0, 0, 0 }
  #define MOPT_NOATIME		{ "atime",	1, MNT_NOATIME, 0 }
+ #define MOPT_NOSYMPERM		{ "symperm",	1, MNT_NOSYMPERM, 0 }
  
  /* Control flags. */
  #define MOPT_FORCE		{ "force",	1, MNT_FORCE, 0 }
***************
*** 82,88 ****
  	MOPT_NOEXEC,							\
  	MOPT_NOSUID,							\
  	MOPT_RDONLY,							\
! 	MOPT_UNION
  
  void getmntopts __P((const char *, const struct mntopt *, int *, int *));
  extern int getmnt_silent;
--- 83,90 ----
  	MOPT_NOEXEC,							\
  	MOPT_NOSUID,							\
  	MOPT_RDONLY,							\
! 	MOPT_UNION,							\
! 	MOPT_NOSYMPERM
  
  void getmntopts __P((const char *, const struct mntopt *, int *, int *));
  extern int getmnt_silent;
Index: mount/mount.8
===================================================================
RCS file: /cvsroot/NetBSD/src/sbin/mount/mount.8,v
retrieving revision 1.1.1.6
diff -c -r1.1.1.6 mount.8
*** mount.8	1997/10/20 23:33:21	1.1.1.6
--- mount.8	1997/10/27 01:06:34
***************
*** 155,160 ****
--- 155,162 ----
  binaries for architectures other than its own.
  .It nosuid
  Do not allow set-user-identifier or set-group-identifier bits to take effect.
+ .It nosymperm
+ Ignore permission of symbolic link when reading or traversing link.
  .It rdonly
  The same as
  .Fl r ;