Subject: kern/707: users cannot remove symlinks from /tmp!
To: None <gnats-admin@NetBSD.ORG>
From: Simon J. Gerraty <sjg@zen.void.oz.au>
List: netbsd-bugs
Date: 01/06/1995 19:20:17
>Number:         707
>Category:       kern
>Synopsis:       users can create symlinks in /tmp but can't remove them.
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Jan  6 19:20:15 1995
>Originator:     Simon J. Gerraty
>Organization:
Zen Programming...
>Release:        1.0
>Environment:
	
System: NetBSD zen.void.oz.au 1.0 NetBSD 1.0 (ZEN) #6: Tue Dec 13 09:55:20 EST 1994 root@zen.void.oz.au:/usr/src/sys/arch/i386/compile/ZEN i386


>Description:
	Users can create symlinks in /tmp but cannot remove them.
	This is a result of the 4.4BSD symlink "feature" of giving
symlinks the owner/group of the containing directory. 

This relates to kern/642 (lstat() returns wrong inode for symlink?),
but this is now much more serious and IMHO a strong argument for
removing the suspect symlink behaviour.

>How-To-Repeat:

sjg:3367$ cd /tmp
sjg:3368$ ls -ald .
drwxrwxrwt  2 root  wheel  512 Jan  7 12:30 ./
sjg:3369$ touch file
sjg:3370$ ln -s file symlink
sjg:3371$ ls -li file symlink
6 -rw-rw-r--  1 sjg   wheel  0 Jan  7 12:32 file
2 lrwxrwxrwt  1 root  wheel  4 Jan  7 12:33 symlink@ -> file
sjg:3372$ rm file
sjg:3373$ rm symlink
rm: symlink: Operation not permitted.
sjg:3374$ uname -a
NetBSD zen.void.oz.au 1.0 NetBSD 1.0 (ZEN) #6: Tue Dec 13 09:55:20 EST 1994     root@zen.void.oz.au:/usr/src/sys/arch/i386/compile/ZEN i386
sjg:3375$ 

>Fix:

The following (ugly) hack adds the option NO_LINKDIR_INO which if
defined removed the 4.4BSD symlink behaviour and fixes the above bug.
I've been running a system like this since Dec 20 without problems.

*** sys/kern/vfs_syscalls.c.~1~ Sat Oct  8 01:13:27 1994
--- sys/kern/vfs_syscalls.c     Mon Dec 19 13:57:16 1994
***************
*** 1191,1197 ****
--- 1192,1200 ----
         */
        vp = nd.ni_vp;
        dvp = nd.ni_dvp;
+ #ifndef NO_LINKDIR_INO
        if (vp->v_type != VLNK) {
+ #endif
                if (dvp == vp)
                        vrele(dvp);
                else
***************
*** 1200,1205 ****
--- 1203,1209 ----
                vput(vp);
                if (error)
                        return (error);
+ #ifndef NO_LINKDIR_INO
        } else {
                error = vn_stat(dvp, &sb, p);
                vput(dvp);
***************
*** 1217,1222 ****
--- 1221,1227 ----
                sb.st_size = sb1.st_size;
                sb.st_blocks = sb1.st_blocks;
        }
+ #endif
        error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb));
        return (error);
  }
*** sys/ufs/ufs/ufs_vnops.c.~1~ Wed Nov 30 09:53:46 1994
--- sys/ufs/ufs/ufs_vnops.c     Tue Dec 20 14:26:57 1994
***************
*** 1916,1924 ****
--- 1916,1926 ----
        }
        ip = VTOI(tvp);
        ip->i_gid = pdir->i_gid;
+ #ifndef NO_LINKDIR_INO
        if ((mode & IFMT) == IFLNK)
                ip->i_uid = pdir->i_uid;
        else
+ #endif
                ip->i_uid = cnp->cn_cred->cr_uid;
  #ifdef QUOTA
        if ((error = getinoquota(ip)) ||
>Audit-Trail:
>Unformatted: