Subject: Re: coredump following symlinks (3)
To: Charles M. Hannum <root@ihack.net>
From: Manuel Bouyer <bouyer@antioche.lip6.fr>
List: tech-kern
Date: 08/27/1999 19:42:38
--J/dobhs11T7y2rNN
Content-Type: text/plain; charset=us-ascii

On Fri, Aug 27, 1999 at 12:50:09PM -0400, Charles M. Hannum wrote:
> 
> This part of the patch:
> 
> +                       if ((ndp->ni_vp->v_type == VLNK) &
> +                           ((fmode & FNOSYMLINK) != 0)) {
> 
> should read:
> 
> +                       if (ndp->ni_vp->v_type == VLNK)
> 
> You should not be able to open(2) a symlink, regardless of flag
> settings.

Sure, it seems reasonable.
Current diffs appenend below (I checked it still works :)

--
Manuel Bouyer, LIP6, Universite Paris VI.           Manuel.Bouyer@lip6.fr
--

--J/dobhs11T7y2rNN
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=diff

Index: sys/fcntl.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/fcntl.h,v
retrieving revision 1.16
diff -u -r1.16 fcntl.h
--- fcntl.h	1999/08/03 20:19:21	1.16
+++ fcntl.h	1999/08/27 17:42:17
@@ -125,6 +125,13 @@
 #define	FMARK		0x00001000	/* mark during gc() */
 #define	FDEFER		0x00002000	/* defer for next gc pass */
 #define	FHASLOCK	0x00004000	/* descriptor holds advisory lock */
+/*
+ * Note: The below is not a flag that can be used in the struct file. 
+ * It's an option that can be passed to vn_open to make sure it doesn't
+ * follow a symlink on the last lookup
+ */
+#define	FNOSYMLINK	0x00010000	/* Don't follow symlink for last
+					   component */
 /* bits to save after open(2) */
 #define	FMASK		(FREAD|FWRITE|FAPPEND|FASYNC|FFSYNC|FNONBLOCK|FDSYNC|\
 			 FRSYNC|FALTIO)
Index: kern/kern_sig.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_sig.c,v
retrieving revision 1.92
diff -u -r1.92 kern_sig.c
--- kern_sig.c	1999/07/25 06:30:34	1.92
+++ kern_sig.c	1999/08/27 17:42:17
@@ -1297,8 +1297,9 @@
 		sprintf(name, "core");
 	else
 		sprintf(name, "%s.core", p->p_comm);
-	NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, name, p);
-	error = vn_open(&nd, O_CREAT | FWRITE, S_IRUSR | S_IWUSR);
+	
+	NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, p);
+	error = vn_open(&nd, O_CREAT | FWRITE | FNOSYMLINK, S_IRUSR | S_IWUSR);
 	if (error)
 		return (error);
 	vp = nd.ni_vp;
Index: kern/vfs_vnops.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/vfs_vnops.c,v
retrieving revision 1.37
diff -u -r1.37 vfs_vnops.c
--- vfs_vnops.c	1999/08/03 20:19:17	1.37
+++ vfs_vnops.c	1999/08/27 17:42:17
@@ -85,7 +85,8 @@
 	if (fmode & O_CREAT) {
 		ndp->ni_cnd.cn_nameiop = CREATE;
 		ndp->ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF;
-		if ((fmode & O_EXCL) == 0)
+		if ((fmode & O_EXCL) == 0 &&
+		    ((fmode & FNOSYMLINK) == 0))
 			ndp->ni_cnd.cn_flags |= FOLLOW;
 		if ((error = namei(ndp)) != 0)
 			return (error);
@@ -112,6 +113,10 @@
 			vp = ndp->ni_vp;
 			if (fmode & O_EXCL) {
 				error = EEXIST;
+				goto bad;
+			}
+			if (ndp->ni_vp->v_type == VLNK) {
+				error = EFTYPE;
 				goto bad;
 			}
 			fmode &= ~O_CREAT;

--J/dobhs11T7y2rNN--