access()有什么问题?

access()有什么问题?,c,linux,system-calls,C,Linux,System Calls,可能重复: 我引用手册页访问(2): 警告:使用访问()检查用户是否被授权,例如,在实际打开文件之前,使用打开(2)会创建一个安全漏洞,因为用户可能会利用检查和打开文件之间的短时间间隔来操纵文件因此,应避免使用此系统调用。 这意味着什么,在什么情况下会引起关注?这是一个典型的竞争条件。这是一个安全问题,仅适用于设置用户ID和设置组ID应用程序。对于以用户身份运行的应用程序,没有威胁,因为操作系统无论如何都会拒绝所讨论的操作 考虑这种情况:您有一个UNIX程序通过set-user-id以root

可能重复:

我引用手册页访问(2):

警告:使用访问()检查用户是否被授权,例如,在实际打开文件之前,使用打开(2)会创建一个安全漏洞,因为用户可能会利用检查和打开文件之间的短时间间隔来操纵文件因此,应避免使用此系统调用。


这意味着什么,在什么情况下会引起关注?

这是一个典型的竞争条件。

这是一个安全问题,仅适用于设置用户ID和设置组ID应用程序。对于以用户身份运行的应用程序,没有威胁,因为操作系统无论如何都会拒绝所讨论的操作

考虑这种情况:您有一个UNIX程序通过set-user-id以
root
身份运行。该程序使用
access
检查另一个用户的文件权限,然后以
root
身份运行该文件,但前提是权限检查成功。假设程序名为
securerun
,您可以按如下方式运行它:

securerun myfile
攻击者可以使用以下算法使利用此安全漏洞的程序运行:

  • 编写一个用户具有执行权限的文件
    xyz
  • 启动两个线程,
    A
    B
  • 线程
    A
    等待几毫秒,然后执行
    cp norunning xyz
    以将
    xyz
    替换为攻击者想要运行但没有运行权限的文件
  • 线程
    B
    调用
    securerun xyz

如果攻击者幸运地掌握了时间,您的
securerun
将检查旧
xyz
上的执行权限,但它将运行新的
xyz
,这是黑客不应该运行的
norunning
的副本。由于在检查和执行之间有一个很短的时间窗口,如果攻击者在一个循环中多次尝试他的策略,那么他一定会在某个时候运气好。

典型错误代码:

  • 使用
    access
    检查是否在以提升权限运行的程序中代表用户读取文件
  • 这里的间隙很短
  • 打开文件
在“短间隙”期间,用户可能能够操作文件系统,例如:

ln -f secret_file.txt non_secret_file.txt

然后,
open
将打开机密文件进行读取,即使在执行检查时链接已就位,
access
检查失败。

在什么情况下会引起关注?在
打开(2)
打开文件之前,不要使用它来检查用户读/写文件的权限。。。只需
直接打开(2)
文件。@Conrad:从
访问
手册页,“检查是用进程的真实UID和GID完成的,而不是像实际尝试操作时那样用有效ID。这是为了让设置用户ID的程序轻松确定调用用户的权限”。因此,如果您只是
打开(2)
,那么您将打开提升的setuid可以访问的文件,但用户不能。问题是,
access
实际上只适合通知用户是否可以访问该文件,而希望避免错误使用提升权限的人却错误地使用了该文件。换句话说,手册页中的注释应该是:,“这是为了允许设置用户ID程序在其期望值超过
access
所提供的值时轻松创建可利用的漏洞”——)@SteveJessop,噢,谢谢。我错过了这一区别。不过:只需使用
open(2)
。并酌情放弃您的特权…=)