diff options
Diffstat (limited to 'man/man2/kcmp.2')
-rw-r--r-- | man/man2/kcmp.2 | 421 |
1 files changed, 421 insertions, 0 deletions
diff --git a/man/man2/kcmp.2 b/man/man2/kcmp.2 new file mode 100644 index 0000000..0add272 --- /dev/null +++ b/man/man2/kcmp.2 @@ -0,0 +1,421 @@ +.\" Copyright (C) 2012, Cyrill Gorcunov <gorcunov@openvz.org> +.\" and Copyright (C) 2012, 2016, Michael Kerrisk <mtk.manpages@gmail.com> +.\" +.\" SPDX-License-Identifier: Linux-man-pages-copyleft +.\" +.\" Kernel commit d97b46a64674a267bc41c9e16132ee2a98c3347d +.\" +.TH kcmp 2 2024-05-02 "Linux man-pages (unreleased)" +.SH NAME +kcmp \- compare two processes to determine if they share a kernel resource +.SH LIBRARY +Standard C library +.RI ( libc ", " \-lc ) +.SH SYNOPSIS +.nf +.BR "#include <linux/kcmp.h>" " /* Definition of " KCMP_* " constants */" +.BR "#include <sys/syscall.h>" " /* Definition of " SYS_* " constants */" +.B #include <unistd.h> +.P +.BI "int syscall(SYS_kcmp, pid_t " pid1 ", pid_t " pid2 ", int " type , +.BI " unsigned long " idx1 ", unsigned long " idx2 ); +.fi +.P +.IR Note : +glibc provides no wrapper for +.BR kcmp (), +necessitating the use of +.BR syscall (2). +.SH DESCRIPTION +The +.BR kcmp () +system call can be used to check whether the two processes identified by +.I pid1 +and +.I pid2 +share a kernel resource such as virtual memory, file descriptors, +and so on. +.P +Permission to employ +.BR kcmp () +is governed by ptrace access mode +.B PTRACE_MODE_READ_REALCREDS +checks against both +.I pid1 +and +.IR pid2 ; +see +.BR ptrace (2). +.P +The +.I type +argument specifies which resource is to be compared in the two processes. +It has one of the following values: +.TP +.B KCMP_FILE +Check whether a file descriptor +.I idx1 +in the process +.I pid1 +refers to the same open file description (see +.BR open (2)) +as file descriptor +.I idx2 +in the process +.IR pid2 . +The existence of two file descriptors that refer to the same +open file description can occur as a result of +.BR dup (2) +(and similar) +.BR fork (2), +or passing file descriptors via a domain socket (see +.BR unix (7)). +.TP +.B KCMP_FILES +Check whether the processes share the same set of open file descriptors. +The arguments +.I idx1 +and +.I idx2 +are ignored. +See the discussion of the +.B CLONE_FILES +flag in +.BR clone (2). +.TP +.B KCMP_FS +Check whether the processes share the same filesystem information +(i.e., file mode creation mask, working directory, and filesystem root). +The arguments +.I idx1 +and +.I idx2 +are ignored. +See the discussion of the +.B CLONE_FS +flag in +.BR clone (2). +.TP +.B KCMP_IO +Check whether the processes share I/O context. +The arguments +.I idx1 +and +.I idx2 +are ignored. +See the discussion of the +.B CLONE_IO +flag in +.BR clone (2). +.TP +.B KCMP_SIGHAND +Check whether the processes share the same table of signal dispositions. +The arguments +.I idx1 +and +.I idx2 +are ignored. +See the discussion of the +.B CLONE_SIGHAND +flag in +.BR clone (2). +.TP +.B KCMP_SYSVSEM +Check whether the processes share the same +list of System\ V semaphore undo operations. +The arguments +.I idx1 +and +.I idx2 +are ignored. +See the discussion of the +.B CLONE_SYSVSEM +flag in +.BR clone (2). +.TP +.B KCMP_VM +Check whether the processes share the same address space. +The arguments +.I idx1 +and +.I idx2 +are ignored. +See the discussion of the +.B CLONE_VM +flag in +.BR clone (2). +.TP +.BR KCMP_EPOLL_TFD " (since Linux 4.13)" +.\" commit 0791e3644e5ef21646fe565b9061788d05ec71d4 +Check whether the file descriptor +.I idx1 +of the process +.I pid1 +is present in the +.BR epoll (7) +instance described by +.I idx2 +of the process +.IR pid2 . +The argument +.I idx2 +is a pointer to a structure where the target file is described. +This structure has the form: +.P +.in +4n +.EX +struct kcmp_epoll_slot { + __u32 efd; + __u32 tfd; + __u64 toff; +}; +.EE +.in +.P +Within this structure, +.I efd +is an epoll file descriptor returned from +.BR epoll_create (2), +.I tfd +is a target file descriptor number, and +.I toff +is a target file offset counted from zero. +Several different targets may be registered with +the same file descriptor number and setting a specific +offset helps to investigate each of them. +.P +Note the +.BR kcmp () +is not protected against false positives which may occur if +the processes are currently running. +One should stop the processes by sending +.B SIGSTOP +(see +.BR signal (7)) +prior to inspection with this system call to obtain meaningful results. +.SH RETURN VALUE +The return value of a successful call to +.BR kcmp () +is simply the result of arithmetic comparison +of kernel pointers (when the kernel compares resources, it uses their +memory addresses). +.P +The easiest way to explain is to consider an example. +Suppose that +.I v1 +and +.I v2 +are the addresses of appropriate resources, then the return value +is one of the following: +.RS +.TP +.B 0 +.I v1 +is equal to +.IR v2 ; +in other words, the two processes share the resource. +.TP +.B 1 +.I v1 +is less than +.IR v2 . +.TP +.B 2 +.I v1 +is greater than +.IR v2 . +.TP +.B 3 +.I v1 +is not equal to +.IR v2 , +but ordering information is unavailable. +.RE +.P +On error, \-1 is returned, and +.I errno +is set to indicate the error. +.P +.BR kcmp () +was designed to return values suitable for sorting. +This is particularly handy if one needs to compare +a large number of file descriptors. +.SH ERRORS +.TP +.B EBADF +.I type +is +.B KCMP_FILE +and +.I fd1 +or +.I fd2 +is not an open file descriptor. +.TP +.B EFAULT +The epoll slot addressed by +.I idx2 +is outside of the user's address space. +.TP +.B EINVAL +.I type +is invalid. +.TP +.B ENOENT +The target file is not present in +.BR epoll (7) +instance. +.TP +.B EPERM +Insufficient permission to inspect process resources. +The +.B CAP_SYS_PTRACE +capability is required to inspect processes that you do not own. +Other ptrace limitations may also apply, such as +.BR CONFIG_SECURITY_YAMA , +which, when +.I /proc/sys/kernel/yama/ptrace_scope +is 2, limits +.BR kcmp () +to child processes; +see +.BR ptrace (2). +.TP +.B ESRCH +Process +.I pid1 +or +.I pid2 +does not exist. +.SH STANDARDS +Linux. +.SH HISTORY +Linux 3.5. +.P +Before Linux 5.12, +this system call is available only if the kernel is configured with +.BR CONFIG_CHECKPOINT_RESTORE , +since the original purpose of the system call was for the +checkpoint/restore in user space (CRIU) feature. +(The alternative to this system call would have been to expose suitable +process information via the +.BR proc (5) +filesystem; this was deemed to be unsuitable for security reasons.) +Since Linux 5.12, +this system call is also available if the kernel is configured with +.BR CONFIG_KCMP . +.SH NOTES +See +.BR clone (2) +for some background information on the shared resources +referred to on this page. +.SH EXAMPLES +The program below uses +.BR kcmp () +to test whether pairs of file descriptors refer to +the same open file description. +The program tests different cases for the file descriptor pairs, +as described in the program output. +An example run of the program is as follows: +.P +.in +4n +.EX +$ \fB./a.out\fP +Parent PID is 1144 +Parent opened file on FD 3 +\& +PID of child of fork() is 1145 + Compare duplicate FDs from different processes: + kcmp(1145, 1144, KCMP_FILE, 3, 3) ==> same +Child opened file on FD 4 + Compare FDs from distinct open()s in same process: + kcmp(1145, 1145, KCMP_FILE, 3, 4) ==> different +Child duplicated FD 3 to create FD 5 + Compare duplicated FDs in same process: + kcmp(1145, 1145, KCMP_FILE, 3, 5) ==> same +.EE +.in +.SS Program source +\& +.\" SRC BEGIN (kcmp.c) +.EX +#define _GNU_SOURCE +#include <err.h> +#include <fcntl.h> +#include <linux/kcmp.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/syscall.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> +\& +static int +kcmp(pid_t pid1, pid_t pid2, int type, + unsigned long idx1, unsigned long idx2) +{ + return syscall(SYS_kcmp, pid1, pid2, type, idx1, idx2); +} +\& +static void +test_kcmp(char *msg, pid_t pid1, pid_t pid2, int fd_a, int fd_b) +{ + printf("\et%s\en", msg); + printf("\et\etkcmp(%jd, %jd, KCMP_FILE, %d, %d) ==> %s\en", + (intmax_t) pid1, (intmax_t) pid2, fd_a, fd_b, + (kcmp(pid1, pid2, KCMP_FILE, fd_a, fd_b) == 0) ? + "same" : "different"); +} +\& +int +main(void) +{ + int fd1, fd2, fd3; + static const char pathname[] = "/tmp/kcmp.test"; +\& + fd1 = open(pathname, O_CREAT | O_RDWR, 0600); + if (fd1 == \-1) + err(EXIT_FAILURE, "open"); +\& + printf("Parent PID is %jd\en", (intmax_t) getpid()); + printf("Parent opened file on FD %d\en\en", fd1); +\& + switch (fork()) { + case \-1: + err(EXIT_FAILURE, "fork"); +\& + case 0: + printf("PID of child of fork() is %jd\en", (intmax_t) getpid()); +\& + test_kcmp("Compare duplicate FDs from different processes:", + getpid(), getppid(), fd1, fd1); +\& + fd2 = open(pathname, O_CREAT | O_RDWR, 0600); + if (fd2 == \-1) + err(EXIT_FAILURE, "open"); + printf("Child opened file on FD %d\en", fd2); +\& + test_kcmp("Compare FDs from distinct open()s in same process:", + getpid(), getpid(), fd1, fd2); +\& + fd3 = dup(fd1); + if (fd3 == \-1) + err(EXIT_FAILURE, "dup"); + printf("Child duplicated FD %d to create FD %d\en", fd1, fd3); +\& + test_kcmp("Compare duplicated FDs in same process:", + getpid(), getpid(), fd1, fd3); + break; +\& + default: + wait(NULL); + } +\& + exit(EXIT_SUCCESS); +} +.EE +.\" SRC END +.SH SEE ALSO +.BR clone (2), +.BR unshare (2) |