Skip site navigation (1)Skip section navigation (2)
Date:      31 Oct 1997 00:13:48 +0100
From:      Wolfram Schneider <wosch@cs.tu-berlin.de>
To:        Ollivier Robert <roberto@keltia.freenix.fr>
Cc:        freebsd-fs@FreeBSD.ORG
Subject:   Re: disabled symlinks
Message-ID:  <p1i67qe974j.fsf@panke.panke.de>
In-Reply-To: Ollivier Robert's message of Mon, 27 Oct 1997 00:11:40 %2B0100
References:  <199710261041.LAA00556@panke.panke.de> <19971027001140.31561@keltia.freenix.fr>

next in thread | previous in thread | raw e-mail | index | archive | help
Ollivier Robert <roberto@keltia.freenix.fr> writes:
> Could you please modify your patch not to _follow_ symlinks in order to
> disallow all symlinks in a given FS ?

I split the nosymlink flag into 3 flags

     nosymlinkcreate
             Do not allow the creation of a symlink(2) for non-root
             users on the mounted file system.

     nosymlinkfollow
             Do not follow symlinks on the mounted file system.

     nosymlinkpubdir
             Do not allow the creation of a symlink(2) for non-root
             users in public writable directories with the sticky bit
             (mode 1777) on the mounted file system.

Index: sys/sys/mount.h
===================================================================
RCS file: /usr/cvs/src/sys/sys/mount.h,v
retrieving revision 1.34.2.1
diff -u -r1.34.2.1 mount.h
--- mount.h	1997/08/17 13:33:43	1.34.2.1
+++ mount.h	1997/10/30 17:04:30
@@ -161,6 +161,10 @@
 #define	MNT_UNION	0x00000020	/* union with underlying filesystem */
 #define	MNT_ASYNC	0x00000040	/* file system written asynchronously */
 #define	MNT_NOATIME	0x10000000	/* Disable update of file access times */
+#define	MNT_NOSYMLINKCREATE	0x20000000	/* do not create symlinks */
+#define	MNT_NOSYMLINKFOLLOW	0x40000000	/* do not follow symlinks */
+/* do not create symlinks in public writable directories with sticky bit */
+#define	MNT_NOSYMLINKPUBDIR	0x80000000	
 
 /*
  * exported mount flags.
@@ -185,7 +189,9 @@
 #define	MNT_VISFLAGMASK	(MNT_RDONLY|MNT_SYNCHRONOUS|MNT_NOEXEC|MNT_NOSUID| \
 			 MNT_NODEV|MNT_UNION|MNT_ASYNC|MNT_EXRDONLY|MNT_EXPORTED| \
 			 MNT_DEFEXPORTED|MNT_EXPORTANON|MNT_EXKERB|MNT_LOCAL| \
-			 MNT_QUOTA|MNT_ROOTFS|MNT_USER|MNT_NOATIME)
+			 MNT_QUOTA|MNT_ROOTFS|MNT_USER|MNT_NOATIME|\
+			 MNT_NOSYMLINKCREATE|MNT_NOSYMLINKFOLLOW|\
+			 MNT_NOSYMLINKPUBDIR)
 
 /*
  * filesystem control flags.
Index: sys/kern/vfs_lookup.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/vfs_lookup.c,v
retrieving revision 1.11.4.1
diff -u -r1.11.4.1 vfs_lookup.c
--- vfs_lookup.c	1996/12/03 15:48:25	1.11.4.1
+++ vfs_lookup.c	1997/10/30 17:05:55
@@ -493,6 +493,10 @@
 	    ((cnp->cn_flags & FOLLOW) || trailing_slash ||
 	     *ndp->ni_next == '/')) {
 		cnp->cn_flags |= ISSYMLINK;
+		if (dp->v_mount->mnt_flag & MNT_NOSYMLINKFOLLOW) {
+			error = EACCES;
+			goto bad2;
+		}
 		return (0);
 	}
 
Index: sys/kern/vfs_syscalls.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.51.2.6
diff -u -r1.51.2.6 vfs_syscalls.c
--- vfs_syscalls.c	1997/10/23 18:04:55	1.51.2.6
+++ vfs_syscalls.c	1997/10/30 22:24:47
@@ -183,9 +183,11 @@
 	else if (mp->mnt_flag & MNT_RDONLY)
 		mp->mnt_flag |= MNT_WANTRDWR;
 	mp->mnt_flag &=~ (MNT_NOSUID | MNT_NOEXEC | MNT_NODEV |
-	    MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_NOATIME);
+	    MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_NOATIME |
+	    MNT_NOSYMLINKCREATE | MNT_NOSYMLINKFOLLOW | MNT_NOSYMLINKPUBDIR);
 	mp->mnt_flag |= uap->flags & (MNT_NOSUID | MNT_NOEXEC | MNT_NODEV |
-	    MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_FORCE | MNT_NOATIME);
+	    MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_FORCE | MNT_NOATIME |
+	    MNT_NOSYMLINKCREATE | MNT_NOSYMLINKFOLLOW | MNT_NOSYMLINKPUBDIR);
 	/*
 	 * Mount the filesystem.
 	 */
@@ -1326,8 +1328,10 @@
 		return (error);
 	vp = nd.ni_vp;
 	error = vn_stat(vp, &sb, p);
-	if (vp->v_type == VLNK)
+	if (vp->v_type == VLNK && 
+		(vp->v_mount->mnt_flag & MNT_NOSYMLINKFOLLOW) != 0)
 		sb.st_mode |= S_IFLNK | ACCESSPERMS;	/* 0777 */
+
 	vput(vp);
 	if (error)
 		return (error);
Index: sys/kern/vfs_vnops.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/vfs_vnops.c,v
retrieving revision 1.26.2.2
diff -u -r1.26.2.2 vfs_vnops.c
--- vfs_vnops.c	1997/03/08 15:16:18	1.26.2.2
+++ vfs_vnops.c	1997/10/30 22:24:34
@@ -353,6 +353,9 @@
 		break;
 	case VLNK:
 		mode |= S_IFLNK;
+		/* mark symlinks as unreadable, cosmetic, 000 */
+		if (vp->v_mount->mnt_flag & MNT_NOSYMLINKFOLLOW)
+			mode &= ~ACCESSPERMS;
 		break;
 	case VSOCK:
 		mode |= S_IFSOCK;
Index: sys/ufs/ufs/ufs_vnops.c
===================================================================
RCS file: /usr/cvs/src/sys/ufs/ufs/ufs_vnops.c,v
retrieving revision 1.41.2.3
diff -u -r1.41.2.3 ufs_vnops.c
--- ufs_vnops.c	1997/06/29 08:48:50	1.41.2.3
+++ ufs_vnops.c	1997/10/30 17:53:53
@@ -1515,6 +1515,26 @@
 	register struct inode *ip;
 	int len, error;
 
+	/* do not create symlinks for non-root users */
+	if (ap->a_dvp->v_mount->mnt_flag & MNT_NOSYMLINKCREATE &&
+		ap->a_cnp->cn_cred->cr_uid != 0) {
+		vput(ap->a_dvp);
+		return ENOSYS;
+	} else 
+
+	/* 
+	 * Do not create symlinks for non-root users in 
+	 * public writable directories  with sticky bit (mode = 41777) 
+	 */
+	if (ap->a_dvp->v_mount->mnt_flag & MNT_NOSYMLINKPUBDIR &&
+		ap->a_cnp->cn_cred->cr_uid != 0 &&
+		(VTOI(ap->a_dvp)->i_mode & 
+			(S_IFDIR | S_ISTXT | S_IRWXU | S_IRWXG | S_IRWXO)) == 
+			(S_IFDIR | S_ISTXT | S_IRWXU | S_IRWXG | S_IRWXO)) {
+		vput(ap->a_dvp);
+		return ENOSYS;
+	}    
+
 	error = ufs_makeinode(IFLNK | ap->a_vap->va_mode, ap->a_dvp,
 	    vpp, ap->a_cnp);
 	if (error)
Index: sbin/mount/mntopts.h
===================================================================
RCS file: /usr/cvs/src/sbin/mount/mntopts.h,v
retrieving revision 1.7
diff -u -r1.7 mntopts.h
--- mntopts.h	1996/09/03 07:13:55	1.7
+++ mntopts.h	1997/10/30 18:07:12
@@ -47,6 +47,9 @@
 #define MOPT_NODEV		{ "dev",	1, MNT_NODEV, 0 }
 #define MOPT_NOEXEC		{ "exec",	1, MNT_NOEXEC, 0 }
 #define MOPT_NOSUID		{ "suid",	1, MNT_NOSUID, 0 }
+#define MOPT_NOSYMLINKCREATE	{ "symlinkcreate", 1, MNT_NOSYMLINKCREATE, 0 }
+#define MOPT_NOSYMLINKFOLLOW	{ "symlinkfollow", 1, MNT_NOSYMLINKFOLLOW, 0 }
+#define MOPT_NOSYMLINKPUBDIR	{ "symlinkpubdir", 1, MNT_NOSYMLINKPUBDIR, 0 }
 #define MOPT_RDONLY		{ "rdonly",	0, MNT_RDONLY, 0 }
 #define MOPT_SYNC		{ "sync",	0, MNT_SYNCHRONOUS, 0 }
 #define MOPT_UNION		{ "union",	0, MNT_UNION, 0 }
@@ -75,6 +78,9 @@
 	MOPT_NODEV,							\
 	MOPT_NOEXEC,							\
 	MOPT_NOSUID,							\
+	MOPT_NOSYMLINKCREATE,						\
+	MOPT_NOSYMLINKFOLLOW,						\
+	MOPT_NOSYMLINKPUBDIR,						\
 	MOPT_RDONLY,							\
 	MOPT_UNION
 
Index: sbin/mount/mount.8
===================================================================
RCS file: /usr/cvs/src/sbin/mount/mount.8,v
retrieving revision 1.11.2.2
diff -u -r1.11.2.2 mount.8
--- mount.8	1997/08/24 17:52:01	1.11.2.2
+++ mount.8	1997/10/30 18:00:57
@@ -134,6 +134,20 @@
 wrapper like
 .Xr suidperl
 is installed on your system.
+.It nosymlinkcreate
+Do not allow the creation of a
+.Xr symlink 2
+for non-root users
+on the mounted file system.
+.It nosymlinkfollow
+Do not follow symlinks
+on the mounted file system.
+.It nosymlinkpubdir
+Do not allow the creation of a
+.Xr symlink 2
+for non-root users in public writable directories with the
+sticky bit (mode 1777)
+on the mounted file system.
 .It rdonly
 The same as
 .Fl r ;
Index: sbin/mount/mount.c
===================================================================
RCS file: /usr/cvs/src/sbin/mount/mount.c,v
retrieving revision 1.15
diff -u -r1.15 mount.c
--- mount.c	1996/09/03 07:13:56	1.15
+++ mount.c	1997/10/30 17:58:35
@@ -92,6 +92,9 @@
 	{ MNT_NODEV,		"nodev" },
 	{ MNT_NOEXEC,		"noexec" },
 	{ MNT_NOSUID,		"nosuid" },
+	{ MNT_NOSYMLINKCREATE,	"nosymlinkcreate" },
+	{ MNT_NOSYMLINKFOLLOW,	"nosymlinkfollow" },
+	{ MNT_NOSYMLINKPUBDIR,	"nosymlinkpubdir" },
 	{ MNT_QUOTA,		"with quotas" },
 	{ MNT_RDONLY,		"read-only" },
 	{ MNT_SYNCHRONOUS,	"synchronous" },
@@ -588,6 +591,15 @@
 
     if (ent->f_flags & MNT_ASYNC)
 	printf (",async");
+
+    if (ent->f_flags & MNT_NOSYMLINKCREATE)
+	printf (",nosymlinkcreate");
+
+    if (ent->f_flags & MNT_NOSYMLINKFOLLOW)
+	printf (",nosymlinkfollow");
+
+    if (ent->f_flags & MNT_NOSYMLINKPUBDIR)
+	printf (",nosymlinkpubdir");
 
     if (fst = getfsspec (ent->f_mntfromname))
 	printf ("\t%u %u\n", fst->fs_freq, fst->fs_passno);


-- 
Wolfram Schneider   <wosch@apfel.de>   http://www.apfel.de/~wosch/



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