C 模拟O_NOFOLLOW(2):另一种方法安全吗?
作为对的后续问题,我想到了另一种方法,它基于@caf的答案,用于我想附加到文件C 模拟O_NOFOLLOW(2):另一种方法安全吗?,c,security,race-condition,symlink,C,Security,Race Condition,Symlink,作为对的后续问题,我想到了另一种方法,它基于@caf的答案,用于我想附加到文件name并在不存在时创建它的情况 以下是我的想法: 在与filename相同的文件系统上的系统临时目录中创建一个模式为0700的临时目录 打开文件name进行只读和O_create。如果是符号链接,操作系统可能会遵循name。使用mkstemp在临时目录中创建一个临时文件,并尝试将mkstemp创建的临时文件重命名为filename打开filename,以便只读和创建O_EXCL 迭代尝试在临时目录中的临时名称处创建指
name
并在不存在时创建它的情况
以下是我的想法:
name
相同的文件系统上的系统临时目录中创建一个模式为0700的临时目录name
进行只读和O_create
。如果是符号链接,操作系统可能会遵循name
。使用
mkstemp
在临时目录中创建一个临时文件,并尝试将mkstemp
创建的临时文件重命名为filename
打开filename
,以便只读和创建O_EXCL
name
的硬链接。如果由于“链接目标存在”(errnoEEXIST
)以外的错误导致调用失败,则退出。(可能有人从name
删除了文件,谁知道呢?)temp\u name
(硬链接)上使用。如果S\u ISLNK(lst.st\u模式)
,则退出temp_name
用于写入和追加(O_WRONLY | O_append
)name
的inode在检查期间表示常规文件,然后使inode成为符号链接,此时temp\u name
硬链接指向新的符号链接
我假设恶意进程不会影响temp\u name
编辑:不会覆盖目标,因此创建“占位符”临时文件不是我想要做的。此后,我更新了代码,并更新了上述步骤
EDIT2:我现在使用第2步的另一个过程来创建文件名称
,如果它不存在,我认为不容易受到影响
EDIT3:甚至比将一个临时的、空的、常规的文件重命名为name
更好,它还具有取消name
链接的效果,然后重命名,我可以打开文件O|u RDONLY | O|u create | O|u EXCL
open
的POSIX标准规定:
如果设置了O_EXCL
和O_CREAT
,并且path
命名了符号链接,open()
将失败,并将errno
设置为EEXIST
,而不管符号链接的内容如何
好的,步骤2有一个问题(“打开文件
name
进行只读和O_create
。如果它是一个符号链接,操作系统可能会遵循name
”),如果完全可利用,可能会允许一个非特权进程实质上接触文件系统中的任何路径。这样做的后果包括在下次重新启动时强制执行磁盘检查(通过触摸/forcefsck
),以及其他更具破坏性的操作。例如,在从Debian Lenny升级到Square的过程中,DBU和内核映像必须同时升级,因为每个相应的包都相互依赖(新的DBU不能与旧内核一起工作,旧的DBU不能与新内核一起工作)。管理员绕过这种循环依赖关系的方法是touch
ing一个特定路径,它通知新的dbus包内核映像将在下次重新启动之前升级。但是,如果在从Lenny升级到Squire的过程中,恶意进程在第一次升级和重新启动之前设法触摸该路径,则系统可能无法启动。如果我没记错的话,第一次升级将安装新的dbus,但是必须再次显式升级才能安装新的内核映像。升级后重新启动可能会阻塞系统
通过查看,当
touch
被传递到--无取消引用
选项时,他们似乎只设置文件时间戳,但如果文件不存在则不创建文件。它们通过gnulib的实用函数来实现这一点,gnulib封装了Linux,允许在Linux>=2.6.22时更新符号链接文件本身的时间戳。如果是这样,为什么不把它作为一个答案发布并接受它,这样这个问题就不再显示为“未回答”?@R.对不起。我已经接受了我的回答。