Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

libbpf: keep FD_CLOEXEC flag when dup()'ing FD

Make sure to preserve and/or enforce FD_CLOEXEC flag on duped FDs.
Use dup3() with O_CLOEXEC flag for that.

Without this fix libbpf effectively clears FD_CLOEXEC flag on each of BPF
map/prog FD, which is definitely not the right or expected behavior.

Reported-by: Lennart Poettering <lennart@poettering.net>
Fixes: bc308d011ab8 ("libbpf: call dup2() syscall directly")
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Link: https://lore.kernel.org/r/20240529223239.504241-1-andrii@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Andrii Nakryiko and committed by
Alexei Starovoitov
531876c8 3f8fde31

+3 -7
+3 -7
tools/lib/bpf/libbpf_internal.h
··· 597 597 return fd; 598 598 } 599 599 600 - static inline int sys_dup2(int oldfd, int newfd) 600 + static inline int sys_dup3(int oldfd, int newfd, int flags) 601 601 { 602 - #ifdef __NR_dup2 603 - return syscall(__NR_dup2, oldfd, newfd); 604 - #else 605 - return syscall(__NR_dup3, oldfd, newfd, 0); 606 - #endif 602 + return syscall(__NR_dup3, oldfd, newfd, flags); 607 603 } 608 604 609 605 /* Point *fixed_fd* to the same file that *tmp_fd* points to. ··· 610 614 { 611 615 int err; 612 616 613 - err = sys_dup2(tmp_fd, fixed_fd); 617 + err = sys_dup3(tmp_fd, fixed_fd, O_CLOEXEC); 614 618 err = err < 0 ? -errno : 0; 615 619 close(tmp_fd); /* clean up temporary FD */ 616 620 return err;