含义:在进程执行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(),且先得到执行,导致打开的文件描述符泄露到子进程中。
版权声明:本文为konga原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。