diff --git a/compel/arch/arm/plugins/std/syscalls/syscall.def b/compel/arch/arm/plugins/std/syscalls/syscall.def index b20b6cb35..e6508ed9f 100644 --- a/compel/arch/arm/plugins/std/syscalls/syscall.def +++ b/compel/arch/arm/plugins/std/syscalls/syscall.def @@ -117,3 +117,4 @@ fsconfig 431 431 (int fd, unsigned int cmd, const char *key, const char *value fsmount 432 432 (int fd, unsigned int flags, unsigned int attr_flags) clone3 435 435 (struct clone_args *uargs, size_t size) pidfd_open 434 434 (pid_t pid, unsigned int flags) +pidfd_getfd 438 438 (int pidfd, int targetfd, unsigned int flags) diff --git a/compel/arch/mips/plugins/std/syscalls/syscall_64.tbl b/compel/arch/mips/plugins/std/syscalls/syscall_64.tbl index 2397c943c..7a6db192c 100644 --- a/compel/arch/mips/plugins/std/syscalls/syscall_64.tbl +++ b/compel/arch/mips/plugins/std/syscalls/syscall_64.tbl @@ -114,3 +114,4 @@ __NR_fsconfig 5431 sys_fsconfig (int fd, unsigned int cmd, const char *key, __NR_fsmount 5432 sys_fsmount (int fd, unsigned int flags, unsigned int attr_flags) __NR_clone3 5435 sys_clone3 (struct clone_args *uargs, size_t size) __NR_pidfd_open 5434 sys_pidfd_open (pid_t pid, unsigned int flags) +__NR_pidfd_getfd 5438 sys_pidfd_getfd (int pidfd, int targetfd, unsigned int flags) diff --git a/compel/arch/ppc64/plugins/std/syscalls/syscall-ppc64.tbl b/compel/arch/ppc64/plugins/std/syscalls/syscall-ppc64.tbl index ce93d8249..1bb626bc5 100644 --- a/compel/arch/ppc64/plugins/std/syscalls/syscall-ppc64.tbl +++ b/compel/arch/ppc64/plugins/std/syscalls/syscall-ppc64.tbl @@ -113,3 +113,4 @@ __NR_fsconfig 431 sys_fsconfig (int fd, unsigned int cmd, const char *key, co __NR_fsmount 432 sys_fsmount (int fd, unsigned int flags, unsigned int attr_flags) __NR_clone3 435 sys_clone3 (struct clone_args *uargs, size_t size) __NR_pidfd_open 434 sys_pidfd_open (pid_t pid, unsigned int flags) +__NR_pidfd_getfd 438 sys_pidfd_getfd (int pidfd, int targetfd, unsigned int flags) diff --git a/compel/arch/s390/plugins/std/syscalls/syscall-s390.tbl b/compel/arch/s390/plugins/std/syscalls/syscall-s390.tbl index 4d058375c..7178bf483 100644 --- a/compel/arch/s390/plugins/std/syscalls/syscall-s390.tbl +++ b/compel/arch/s390/plugins/std/syscalls/syscall-s390.tbl @@ -113,3 +113,4 @@ __NR_fsconfig 431 sys_fsconfig (int fd, unsigned int cmd, const char *key, co __NR_fsmount 432 sys_fsmount (int fd, unsigned int flags, unsigned int attr_flags) __NR_clone3 435 sys_clone3 (struct clone_args *uargs, size_t size) __NR_pidfd_open 434 sys_pidfd_open (pid_t pid, unsigned int flags) +__NR_pidfd_getfd 438 sys_pidfd_getfd (int pidfd, int targetfd, unsigned int flags) diff --git a/compel/arch/x86/plugins/std/syscalls/syscall_32.tbl b/compel/arch/x86/plugins/std/syscalls/syscall_32.tbl index 863db6a56..7e456cdb7 100644 --- a/compel/arch/x86/plugins/std/syscalls/syscall_32.tbl +++ b/compel/arch/x86/plugins/std/syscalls/syscall_32.tbl @@ -101,3 +101,4 @@ __NR_fsconfig 431 sys_fsconfig (int fd, unsigned int cmd, const char *key, co __NR_fsmount 432 sys_fsmount (int fd, unsigned int flags, unsigned int attr_flags) __NR_clone3 435 sys_clone3 (struct clone_args *uargs, size_t size) __NR_pidfd_open 434 sys_pidfd_open (pid_t pid, unsigned int flags) +__NR_pidfd_getfd 438 sys_pidfd_getfd (int pidfd, int targetfd, unsigned int flags) diff --git a/compel/arch/x86/plugins/std/syscalls/syscall_64.tbl b/compel/arch/x86/plugins/std/syscalls/syscall_64.tbl index ba32affb0..2dfcc6eee 100644 --- a/compel/arch/x86/plugins/std/syscalls/syscall_64.tbl +++ b/compel/arch/x86/plugins/std/syscalls/syscall_64.tbl @@ -112,3 +112,4 @@ __NR_fsconfig 431 sys_fsconfig (int fd, unsigned int cmd, const char *key, c __NR_fsmount 432 sys_fsmount (int fd, unsigned int flags, unsigned int attr_flags) __NR_clone3 435 sys_clone3 (struct clone_args *uargs, size_t size) __NR_pidfd_open 434 sys_pidfd_open (pid_t pid, unsigned int flags) +__NR_pidfd_getfd 438 sys_pidfd_getfd (int pidfd, int targetfd, unsigned int flags) diff --git a/criu/include/kerndat.h b/criu/include/kerndat.h index bd5352a48..df57ca185 100644 --- a/criu/include/kerndat.h +++ b/criu/include/kerndat.h @@ -70,6 +70,7 @@ struct kerndat_s { bool has_timens; bool has_newifindex; bool has_pidfd_open; + bool has_pidfd_getfd; }; extern struct kerndat_s kdat; diff --git a/criu/kerndat.c b/criu/kerndat.c index 9aeef17d2..90f4f2d9a 100644 --- a/criu/kerndat.c +++ b/criu/kerndat.c @@ -1068,6 +1068,69 @@ static void kerndat_has_pidfd_open(void) close_safe(&pidfd); } +static int kerndat_has_pidfd_getfd(void) +{ + int ret; + int fds[2]; + int val_a, val_b; + int pidfd, stolen_fd; + + ret = 0; + + if (socketpair(AF_UNIX, SOCK_DGRAM, 0, fds)) { + pr_perror("Can't open unix socket pair"); + ret = -1; + goto out; + } + + val_a = 1984; + if (write(fds[0], &val_a, sizeof(val_a)) != sizeof(val_a)) { + pr_perror("Can't write to socket"); + ret = -1; + goto close_pair; + } + + pidfd = syscall(SYS_pidfd_open, getpid(), 0); + if (pidfd == -1) { + pr_warn("Can't get pidfd\n"); + /* + * If pidfd_open is not supported then pidfd_getfd + * will not be supported as well. + */ + kdat.has_pidfd_getfd = false; + goto close_pair; + } + + stolen_fd = syscall(SYS_pidfd_getfd, pidfd, fds[1], 0); + if (stolen_fd == -1) { + kdat.has_pidfd_getfd = false; + goto close_all; + } + + if (read(fds[1], &val_b, sizeof(val_b)) != sizeof(val_b)) { + pr_perror("Can't read from socket"); + ret = -1; + goto close_all; + } + + if (val_b == val_a) { + kdat.has_pidfd_getfd = true; + } else { + /* If val_b != val_a then something unexpected happend. */ + pr_err("Unexpected value read from socket\n"); + ret = -1; + } + +close_all: + close_safe(&stolen_fd); + close_safe(&pidfd); +close_pair: + close(fds[0]); + close(fds[1]); +out: + return ret; +} + int kerndat_init(void) { int ret; @@ -1205,6 +1268,10 @@ int kerndat_init(void) pr_err("kerndat_has_newifindex failed when initializing kerndat.\n"); ret = -1; } + if (!ret && kerndat_has_pidfd_getfd()) { + pr_err("kerndat_has_pidfd_getfd failed when initializing kerndat.\n"); + ret = -1; + } if (!ret) kerndat_has_pidfd_open();