2

我一直在做一些 shell 编写,并遇到了access()检查文件是否存在、是否可以读取等的建议。似乎超级容易实现并且比stat(). 当我开始查看它的手册页时,我注意到不建议使用它,因为它可能导致安全漏洞。手册页是这样说的:

使用 access() 来检查用户是否被授权例如在使用 open(2) 实际打开文件之前打开文件会产生安全漏洞,因为用户可能会利用检查和打开文件之间的短时间间隔来操作它。

有谁知道如何利用它,或者它是否仅适用于open()检查文件后使用?我知道很多人说要stat()改用,但access()它很容易实现,尤其是对于我使用它的 shell。

4

3 回答 3

4

那是一场 TOCTOU 竞赛(检查时间到更新时间)。access()恶意用户可以将他有权访问的文件替换为指向他在调用和调用之间无权访问的内容的符号链接open()。使用faccessat()fstat()。通常,打开一个文件一次,然后f*()对其使用函数(例如:fchown()、...)。

于 2011-10-28T07:10:24.697 回答
0

我能想到的一件事,虽然它看起来很弱 - access() 使用真实的而不是有效的 uid 和 gid。这应该允许一个 setuid 程序(一个普通用户执行但获得所有者权限的程序)检查调用用户是否可以读取文件,以防止无意中让该用户访问他们应该无法读取的文件,也许通过使用一些符号链接或硬链接技巧。我找不到任何证据表明这是可能的,或者 stat() 不可能,但想象一下这种情况:

user executes program
program is setuid, immediately gets all privs of root
program checks file1 to ensure that user has access
file1 is a hardlink to file2, which user has access to
user changes file1 to hardlink to file3 (/etc/shadow or something like that)
program reads file1 and does something to it (print, convert, whatever)
user now has access to a file they shouldn't
于 2011-10-28T04:48:34.567 回答
0

该模式似乎正在调用access()stat()确定您是否可以打开文件,然后在您有权限的情况下打开它。

相反,通常最好继续尝试打开它,然后检查尝试是否成功(如果没有,为什么)。这避免了检查和尝试打开文件之间的时间间隔。

于 2011-10-28T08:39:36.137 回答