【问题标题】:what is the purpose to set SOCK_CLOEXEC flag with accept4() same as O_CLOEXEC使用与 O_CLOEXEC 相同的 accept4() 设置 SOCK_CLOEXEC 标志的目的是什么
【发布时间】:2014-04-13 19:40:26
【问题描述】:

基本上,我需要知道在使用accept4() 时设置SOCK_CLOEXEC 的目的是什么。 如何使用从接受返回的文件描述符检查此标志的功能。

accepted_fd =   accept4(sd, (struct sockaddr *)& tcp_remote, &size,  SOCK_CLOEXEC);

【问题讨论】:

    标签: c++ c linux sockets unix


    【解决方案1】:

    SOCK_CLOEXEC 存在的原因是为了避免从accept 获取新套接字和之后设置FD_CLOEXEC 标志之间的竞争条件。

    通常,如果您希望文件描述符在执行时关闭,您首先需要以某种方式获取文件描述符,然后调用fcntl(fd, F_SETFD, FD_CLOEXEC)。但是在线程程序中,在获取该文件描述符(在本例中来自accept)和设置 CLOEXEC 标志之间可能存在竞争条件。因此,Linux 最近更改了大多数(如果不是全部)返回新文件描述符的系统调用,以接受指示内核在使文件描述符有效之前自动设置 close-on-exec 标志的标志。这样竞争条件就结束了。

    如果您想知道为什么存在 close on exec,那是因为在某些情况下,尤其是当您从特权程序执行非特权程序时,您不希望某些文件描述符泄漏到该程序。

    【讨论】:

    • 我不会描述O_CLOEXEC,因为主要是出于特权升级/安全原因——如果发生非安全错误(通常是无限期阻塞)也非常非常普遍一个 FD 处于打开状态,超出了它的预期关闭时间,因为子进程仍然拥有它。
    • ...如果他们不处理具有不同权限级别的进程,鼓励人们思考“哦,这不是我需要担心的事情”是没有帮助的。
    • 导致决定实施所有这些更改和添加的系统调用的讨论完全围绕安全原因展开。由多个进程保持打开的文件描述符与 close-on-exec 无关,因为在 exec 上关闭不是在 fork 上关闭。这是一个不同的问题领域。实际上,除了字符设备的“最后关闭实际关闭”语义之外,我不知道由于打开文件描述符而导致的许多非安全问题。
    • 我个人遇到过很多这样的问题——主要是在专有代码库上,或者我会向您指出错误报告和补丁。想一想产生由一对管道连接的子进程的正常过程,写入它,关闭出站管道,从入站管道读取,并在完成后等待它。如果您在出站管道关闭之前生成了一个子进程,并且该子进程无限期地保持 FD 处于打开状态,则您可能会遇到该进程永远不会完成其读取,因此永远不会退出的情况。
    • ...是的,这是最后关闭实际关闭的问题,但是,这是一个大问题。 :)
    猜你喜欢
    • 2013-08-20
    • 2023-04-10
    • 2019-06-07
    • 1970-01-01
    • 2019-07-18
    • 1970-01-01
    • 2014-06-05
    • 2012-08-15
    • 2018-01-05
    相关资源
    最近更新 更多