summaryrefslogtreecommitdiffstats
path: root/man/man2/kcmp.2
diff options
context:
space:
mode:
Diffstat (limited to 'man/man2/kcmp.2')
-rw-r--r--man/man2/kcmp.2421
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)