在FreeBSD上,如果file
不是目录,$ echo >test
$ chmod +t test
chmod: test: Inappropriate file type or format
$ su
Password:
# chmod +t test
# ls -l test
-rw-r--r-T 1 fuz wheel 1 Jan 26 12:44 test
是特权操作:
[EFTYPE] The effective user ID is not the super-user, the mode
includes the sticky bit (S_ISVTX), and path does not
refer to a directory.
chmod (2)记录此行为:
S_ISVTX
同时,粘性(7)解释如果file
不是目录,则会忽略 A special file mode, called the sticky bit (mode S_ISTXT), is used to
indicate special treatment for directories. It is ignored for regular
files. See chmod(2) or the file <sys/stat.h> for an explanation of file
modes.
:
EFTYPE
在FreeBSD上将非目录标记为粘贴是特权操作的历史或技术原因是什么?为什么为此创建了额外的错误代码EPERM
应该是ENOTDIR
或next(err)
?
答案 0 :(得分:3)
从历史上看,最初的Unix不允许这样做。 V7 chmod man page说
设置此位的能力仅限于超级用户,因为图像消耗了交换空间
如果用户试图设置粘滞位,V7 chmod system call没有返回错误,但它只是默默地关闭了位:
if (u.u_uid)
uap->fmode &= ~ISVTX;
此行为未更改地传递给BSD。 4.3BSD有这段代码,它会默默地关闭非root用户的非目录上的ISVTX位:
if (u.u_uid) {
if ((ip->i_mode & IFMT) != IFDIR)
mode &= ~ISVTX;
...
}
代码在4.4BSD中已更改,以返回错误EFTYPE
,但4.4BSD chmod man page未提及此问题。我不知道为什么会改变。
if (cred->cr_uid) {
if (vp->v_type != VDIR && (mode & ISVTX))
return (EFTYPE);
...
}
FreeBSD 1.0包含与4.4BSD相同的代码。
if (cred->cr_uid) {
if (vp->v_type != VDIR && (mode & ISVTX))
return (EFTYPE);
...
}
这已经延续到当前版本。 FreeBSD 10.2有这个:
if (vp->v_type != VDIR && (mode & S_ISTXT)) {
if (priv_check_cred(cred, PRIV_VFS_STICKYFILE, 0))
return (EFTYPE);
}
OpenBSD有类似的代码:
if (cred->cr_uid) {
if (vp->v_type != VDIR && (mode & S_ISTXT))
return (EFTYPE);
...
}
Solaris 10默默地忽略非root用户尝试在文件上设置粘滞位的尝试。 (我会在可用时添加源代码片段。)
答案 1 :(得分:0)
在FreeBSD上将非目录标记为粘贴是特权操作的历史或技术原因是什么?
为什么不呢?首先,它显然不是一个有意义的操作,因此它应该作为失败报告给用户,以表明他做错了什么。此外,允许它不是未来的证据,如同任何未使用的标志或字段 - 它可能在将来用于某些事情,并且不会造成安全性或一致性风险,它应该处于可预测的状态。
为什么在这个应该是EPERM或ENOTDIR的情况下发明了额外的错误代码EFTYPE?
见errno(2)。 EFTYPE不是专门针对这种情况发明的,具有更广泛的含义,并且比EPERM更适合这种情况,而ENOTDIR具有完全不相关的目的。