The original code validated the PID:inode by opening a pidfd via
ul_get_valid_pidfd_or_err(), but immediately closed it. Later,
pidfd_open() was called again for the same PID. This created a
window between close() and the second pidfd_open() where the PID
could be recycled by the kernel, defeating the purpose of the
PID:inode identity verification.
Keep the validated pidfd from PID:inode open and reuse it, so the
process identity is pinned for the entire lifetime of nsenter. As
long as the pidfd is held open, the kernel will not recycle the PID,
making subsequent operations (setns, ioctls) race-free.
Introduce ns_pid_fd to separate the pidfd used for enter_namespaces()
(setns, requires kernel >= 5.7) from the general-purpose pid_fd used
for ioctls like PIDFD_GET_USER_NAMESPACE and pidfd_getfd(). The kernel
version check gates only the setns-related usage.
Also use ul_parse_pid_str_or_err() for consistent error handling
across utilities that support the PID:inode format.