Subject: kern/719: 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/09/1995 14:05:20
>Number: 719
>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: Mon Jan 9 14:05:09 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:
[ sorry if this is a repeat, but original appears to have missed ]
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: