Skip to content

Missing O_CLOEXEC/FD_CLOEXEC flag handling on file descriptors #2819

@irozzo-1A

Description

@irozzo-1A

Describe the bug

The O_CLOEXEC (or FD_CLOEXEC) flag is correctly captured and stored in file descriptor metadata when files are opened, but the flag is not acted upon during execve syscall processing. According to Linux kernel behavior, all file descriptors with the O_CLOEXEC flag set should be automatically closed when a process calls execve, but libsinsp currently does not implement this behavior.

Current behavior:

  1. The O_CLOEXEC flag is correctly captured from syscalls (e.g., open, openat, pipe2, dup3) and stored in sinsp_fdinfo::m_openflags as PPM_O_CLOEXEC (see userspace/libsinsp/parsers.cpp:2075).
  2. The flag is preserved in the fd table and can be queried via m_openflags.
  3. When execve is called, the parser (parse_execve_exit()) does not check for or close file descriptors with the PPM_O_CLOEXEC flag set. The fd table remains unchanged, leading to an incorrect state where CLOEXEC-marked fds appear to still be open after execve.

Impact:

  • Incorrect fd counts in the process state
  • Potential false positive due to stale cahced information when querying FDs that should have been closed

How to reproduce it

  1. Capture events from a process that:

    • Opens a file descriptor with O_CLOEXEC flag (e.g., open(path, O_RDONLY | O_CLOEXEC))
    • Calls execve() to execute a new program
    • The new program opens a file and reuses the same FD number
  2. Query the fd table after execve for the CLOEXEC-marked FD

  3. Observe that the FD still exists in the table with stale information (file path, metadata from before execve)

Minimal reproduction example:

// Program opens file with O_CLOEXEC
int fd = open("/tmp/test", O_RDONLY | O_CLOEXEC);
// Process calls execve
execve("/bin/ls", argv, envp);
// New program may reuse fd=3, but libsinsp still has stale info for the old fd=3

Expected behaviour

When a process calls execve (or execveat), all file descriptors that were opened with the O_CLOEXEC flag should be automatically closed in libsinsp's internal fd table, mirroring the kernel's behavior. After execve:

  • FDs with PPM_O_CLOEXEC set should be removed from the fd table
  • Queries for those FDs should return nullptr or indicate the FD doesn't exist
  • No stale information should be retrievable for CLOEXEC-marked FDs

Screenshots

N/A

Environment

  • Falco version: N/A (libsinsp issue, affects all versions)
  • System info: N/A
  • Cloud provider or hardware configuration: N/A
  • OS: Linux (any distribution)
  • Kernel: Any kernel version that supports O_CLOEXEC
  • Installation method: N/A (libsinsp library issue)

Additional context

Relevant Code Locations:

  1. Flag Storage:

    • userspace/libsinsp/parsers.cpp:2075 - fdi->m_openflags = flags; stores the flag
    • driver/ppm_events_public.h:108 - PPM_O_CLOEXEC definition
  2. Missing execve Handling:

    • userspace/libsinsp/parsers.cpp:1728-1734 - parse_execve_exit() has a commented-out section about clearing the fd table, but no CLOEXEC-specific logic
    • The function should iterate through the fd table and close fds with PPM_O_CLOEXEC set
  3. Acknowledgment of Limitation:

    • userspace/libsinsp/fdtable.cpp:103-110 - Comment states "which we don't currently parse" and "XXX Can't have this enabled until the FD_CLOEXEC flag is supported"
    • userspace/libscap/scap_procs.c:107-109 - Similar comment in libscap code

References:

  • Linux execve(2) man page: "By default, file descriptors remain open across an execve(). File descriptors that are marked close-on-exec are closed"
  • O_CLOEXEC flag documentation in Linux open(2) man page
  • Kernel source: File descriptors with FD_CLOEXEC set are closed in do_execveat_common()do_close_on_exec()

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions