close-on-exec标志介绍

在执行exec()之前,程序有时需要确保关闭某些特定的文件描述符。尤其是在特权进程中调用exec()来启动一个未知程序时(并非自己编写),抑或是启动程序并不需要使用这些已打开的文件描述符时,从安全编程的角度出发,应当在加载新程序之前确保关闭那些不必要的文件描述符。对所有此类描述符施以close()调用就可达到这一目的,然而这一做法存在如下局限性。

  1. 某些描述符可能是有库函数打开的。但库函数无法使主程序在执行exec()之前关闭相应的文件描述符。作为基本原则,库函数应总是为其打开的文件设置执行时关闭(close-on-exec)标志
  2. 如果exec()因某种原因而调用失败,可能还需要时描述符保持打开状态。如果这些描述符已然关闭,讲他们重新打开并指向相同文件的难度很大,基本上不太可能。

为此,内核为每个文件描述符提供了执行时关闭标志。如果设置了这一标志,那么在成功执行exec()时,会自动关闭该文件描述符,如果调用exec()失败,文件描述符则会保存打开状态。

 

方法:

  1. 通过fcntl()系统调用来访问执行时关闭标志。例如:
    int flags;
    
    flags = fcntl(fd, F_GETFD);
    if (flags == -1)
    {
    	perror("fcntl");
    }
    flags |= FD_CLOEXEC;
    
    if (fcntl(fd, F_SETFD, flags) == -1)
    {
    	perror("fcntl");
    }

     

  2. 调用open时在flags参数使用O_CLOEXEC标识位,为新的文件描述符启用close-on-flag标志。在open中使用的O_CLOEXEC和fcntl中使用的FD_CLOEXEC的作用是一样的,但是使用O_CLOEXEC标志,相对比较简单,而且在多线程程序中执行fcntl()的F_GETFD和F_SETFD操作有可能导致竞争状态。可能引发竞争的场景是:线程某甲打开一文件描述符,尝试为该描述符标记close-on-exec标志,与此同时,线程某乙执行fork()调用,然后调用exec()执行任意一个程序。(假设在某甲打开文件描述符和调用fcntl()设置close-on-exec标志之间,某乙成功执行了fork()和exec()操作。)此类竞争可能会在无意间打开的文件描述符泄露给不安全的程序。
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值