含义:在进程执行exec系统调用时关闭此打开的文件描述符。在子进程没有相应权限的情况下,防止父进程将打开的文件描述符泄露给子进程,防止子进程间接获得权限。
fd泄露引起普通用户访问无权限的文件:
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include
<fcntl.h> #include <stdlib.h> int main() { int count; pid_t pid; char buf[1024]
= {0}; int fd; //以root身份打开文件 fd = open("/etc/shadow", O_RDONLY); if( fd < 0 ) {
perror("open /etc/shadow"); return -1; } pid = fork(); if( 0 == pid ) {
seteuid(500); setegid(500); //fd是从父进程泄露出来,不受权限制约,可以读取文件 printf("EUID:%d,
UID:%d\n", geteuid(), getuid()); while( (count = read(fd, buf, sizeof(buf))) >
0 ) { write(STDOUT_FILENO, buf, count); } close(fd); //普通用户! 无法打开文件 fd =
open("/etc/shadow", O_RDONLY); printf("fd=%d\n", fd); if( fd<0 ) { perror("open
/etc/shadow"); return -1; } return 0; } close(fd); return 0; }
设置O_CLOEXEC一般是在open时设置,这个是原子操作;也可以用fcntl()的F_SETFD命令来设置,但它有并发危险,如多线程中,一个线程将要设置O_CLOEXEC标志时,虽一个线程fork(),且先得到执行,导致打开的文件描述符泄露到子进程中。