I try to set O_CLOEXEC flag using open() and have no sucess.

Consider the following microtest:

#include <stdio.h>
#include <fcntl.h>

int main() {
  int fd = open("test.c", O_RDONLY | O_CLOEXEC);
  int ret = fcntl(fd, F_GETFL);
  if(ret & O_CLOEXEC) {
    printf("OK!\n");
  } else {
    printf("FAIL!\n");
  }
  printf("fd = %d\n", fd);
  printf("ret = %x, O_CLOEXEC = %x\n", ret, O_CLOEXEC);
  return 0;
} 

When running on linux with kernel version 2.6 the test succeeds and prints "OK!", but fails with 3.8 or 3.9 kernels.

What's wrong? Thanks!

有帮助吗?

解决方案

It was decided that exposing O_CLOEXEC flag to fcntl(fd, F_GETFL) is security leak. Change was made by this commit in kernel 3.6-rc7:

commit c6f3d81115989e274c42a852222b80d2e14ced6f
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Sun Aug 26 11:01:04 2012 -0400

don't leak O_CLOEXEC into ->f_flags

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

In other words, you should not have relied on O_CLOEXEC being visible in first place.

其他提示

The fcntl call parameter F_GETFD, the flag is FD_CLOEXEC and the O_CLOEXEC support appeared in 2.6.23. Read the manuals:

 File descriptor flags
   The following commands manipulate the flags associated with a file descriptor.
   Currently,  only one such flag is defined: FD_CLOEXEC, the close-on-exec flag.
   If the FD_CLOEXEC bit is 0, the file descriptor will  remain  open  across  an
   execve(2), otherwise it will be closed.

   F_GETFD (void)
          Read the file descriptor flags; arg is ignored.

   F_SETFD (int)
          Set the file descriptor flags to the value specified by arg.

You are doing it wrong. You should do by this way:

int ret = fcntl(fd, F_GETFD);
if (ret & FD_CLOEXEC) {
...
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top