1KCMP(2)                    Linux Programmer's Manual                   KCMP(2)
2
3
4

NAME

6       kcmp  -  compare  two processes to determine if they share a kernel re‐
7       source
8

SYNOPSIS

10       #include <linux/kcmp.h>       /* Definition of KCMP_* constants */
11       #include <sys/syscall.h>      /* Definition of SYS_* constants */
12       #include <unistd.h>
13
14       int syscall(SYS_kcmp, pid_t pid1, pid_t pid2, int type,
15                   unsigned long idx1, unsigned long idx2);
16
17       Note: glibc provides no wrapper for kcmp(), necessitating  the  use  of
18       syscall(2).
19

DESCRIPTION

21       The  kcmp()  system call can be used to check whether the two processes
22       identified by pid1 and pid2 share a kernel  resource  such  as  virtual
23       memory, file descriptors, and so on.
24
25       Permission   to  employ  kcmp()  is  governed  by  ptrace  access  mode
26       PTRACE_MODE_READ_REALCREDS checks  against  both  pid1  and  pid2;  see
27       ptrace(2).
28
29       The type argument specifies which resource is to be compared in the two
30       processes.  It has one of the following values:
31
32       KCMP_FILE
33              Check whether a file descriptor idx1 in the process pid1  refers
34              to the same open file description (see open(2)) as file descrip‐
35              tor idx2 in the process pid2.  The existence  of  two  file  de‐
36              scriptors that refer to the same open file description can occur
37              as a result of dup(2) (and similar) fork(2), or passing file de‐
38              scriptors via a domain socket (see unix(7)).
39
40       KCMP_FILES
41              Check  whether the processes share the same set of open file de‐
42              scriptors.  The arguments idx1 and idx2 are  ignored.   See  the
43              discussion of the CLONE_FILES flag in clone(2).
44
45       KCMP_FS
46              Check  whether  the processes share the same filesystem informa‐
47              tion (i.e., file mode  creation  mask,  working  directory,  and
48              filesystem root).  The arguments idx1 and idx2 are ignored.  See
49              the discussion of the CLONE_FS flag in clone(2).
50
51       KCMP_IO
52              Check whether the processes share I/O  context.   The  arguments
53              idx1  and  idx2 are ignored.  See the discussion of the CLONE_IO
54              flag in clone(2).
55
56       KCMP_SIGHAND
57              Check whether the processes share the same table of signal  dis‐
58              positions.   The  arguments  idx1 and idx2 are ignored.  See the
59              discussion of the CLONE_SIGHAND flag in clone(2).
60
61       KCMP_SYSVSEM
62              Check whether the processes share the same list of System V sem‐
63              aphore  undo  operations.   The  arguments idx1 and idx2 are ig‐
64              nored.   See  the  discussion  of  the  CLONE_SYSVSEM  flag   in
65              clone(2).
66
67       KCMP_VM
68              Check  whether  the processes share the same address space.  The
69              arguments idx1 and idx2 are ignored.  See the discussion of  the
70              CLONE_VM flag in clone(2).
71
72       KCMP_EPOLL_TFD (since Linux 4.13)
73              Check  whether  the  file descriptor idx1 of the process pid1 is
74              present in the  epoll(7)  instance  described  by  idx2  of  the
75              process  pid2.   The  argument  idx2 is a pointer to a structure
76              where the target file is  described.   This  structure  has  the
77              form:
78
79           struct kcmp_epoll_slot {
80               __u32 efd;
81               __u32 tfd;
82               __u64 toff;
83           };
84
85       Within  this  structure,  efd is an epoll file descriptor returned from
86       epoll_create(2), tfd is a target file descriptor number, and toff is  a
87       target file offset counted from zero.  Several different targets may be
88       registered with the same file descriptor number and setting a  specific
89       offset helps to investigate each of them.
90
91       Note  the kcmp() is not protected against false positives which may oc‐
92       cur if the processes are currently running.  One should stop  the  pro‐
93       cesses by sending SIGSTOP (see signal(7)) prior to inspection with this
94       system call to obtain meaningful results.
95

RETURN VALUE

97       The return value of a successful call to kcmp() is simply the result of
98       arithmetic  comparison of kernel pointers (when the kernel compares re‐
99       sources, it uses their memory addresses).
100
101       The easiest way to explain is to consider an example.  Suppose that  v1
102       and  v2  are  the  addresses  of appropriate resources, then the return
103       value is one of the following:
104
105           0   v1 is equal to v2; in other words, the two processes share  the
106               resource.
107
108           1   v1 is less than v2.
109
110           2   v1 is greater than v2.
111
112           3   v1 is not equal to v2, but ordering information is unavailable.
113
114       On error, -1 is returned, and errno is set to indicate the error.
115
116       kcmp()  was  designed  to  return values suitable for sorting.  This is
117       particularly handy if one needs to compare a large number of  file  de‐
118       scriptors.
119

ERRORS

121       EBADF  type is KCMP_FILE and fd1 or fd2 is not an open file descriptor.
122
123       EFAULT The  epoll  slot  addressed by idx2 is outside of the user's ad‐
124              dress space.
125
126       EINVAL type is invalid.
127
128       ENOENT The target file is not present in epoll(7) instance.
129
130       EPERM  Insufficient  permission  to  inspect  process  resources.   The
131              CAP_SYS_PTRACE  capability is required to inspect processes that
132              you do not own.  Other ptrace limitations may also  apply,  such
133              as     CONFIG_SECURITY_YAMA,    which,    when    /proc/sys/ker‐
134              nel/yama/ptrace_scope is 2, limits kcmp()  to  child  processes;
135              see ptrace(2).
136
137       ESRCH  Process pid1 or pid2 does not exist.
138

VERSIONS

140       The kcmp() system call first appeared in Linux 3.5.
141

CONFORMING TO

143       kcmp() is Linux-specific and should not be used in programs intended to
144       be portable.
145

NOTES

147       Before Linux 5.12, this system call is available only if the kernel  is
148       configured  with  CONFIG_CHECKPOINT_RESTORE, since the original purpose
149       of the system call was for the checkpoint/restore in user space  (CRIU)
150       feature.   (The  alternative to this system call would have been to ex‐
151       pose suitable process information via the proc(5) filesystem; this  was
152       deemed  to be unsuitable for security reasons.)  Since Linux 5.12, this
153       system call is made available unconditionally.
154
155       See clone(2) for some background information on  the  shared  resources
156       referred to on this page.
157

EXAMPLES

159       The program below uses kcmp() to test whether pairs of file descriptors
160       refer to the same open file description.  The program  tests  different
161       cases  for  the file descriptor pairs, as described in the program out‐
162       put.  An example run of the program is as follows:
163
164           $ ./a.out
165           Parent PID is 1144
166           Parent opened file on FD 3
167
168           PID of child of fork() is 1145
169                Compare duplicate FDs from different processes:
170                     kcmp(1145, 1144, KCMP_FILE, 3, 3) ==> same
171           Child opened file on FD 4
172                Compare FDs from distinct open()s in same process:
173                     kcmp(1145, 1145, KCMP_FILE, 3, 4) ==> different
174           Child duplicated FD 3 to create FD 5
175                Compare duplicated FDs in same process:
176                     kcmp(1145, 1145, KCMP_FILE, 3, 5) ==> same
177
178   Program source
179
180       #define _GNU_SOURCE
181       #include <sys/syscall.h>
182       #include <sys/wait.h>
183       #include <sys/stat.h>
184       #include <stdint.h>
185       #include <stdlib.h>
186       #include <stdio.h>
187       #include <unistd.h>
188       #include <fcntl.h>
189       #include <linux/kcmp.h>
190
191       #define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \
192                               } while (0)
193
194       static int
195       kcmp(pid_t pid1, pid_t pid2, int type,
196            unsigned long idx1, unsigned long idx2)
197       {
198           return syscall(SYS_kcmp, pid1, pid2, type, idx1, idx2);
199       }
200
201       static void
202       test_kcmp(char *msg, pid_t pid1, pid_t pid2, int fd_a, int fd_b)
203       {
204           printf("\t%s\n", msg);
205           printf("\t\tkcmp(%jd, %jd, KCMP_FILE, %d, %d) ==> %s\n",
206                   (intmax_t) pid1, (intmax_t) pid2, fd_a, fd_b,
207                   (kcmp(pid1, pid2, KCMP_FILE, fd_a, fd_b) == 0) ?
208                               "same" : "different");
209       }
210
211       int
212       main(int argc, char *argv[])
213       {
214           int fd1, fd2, fd3;
215           char pathname[] = "/tmp/kcmp.test";
216
217           fd1 = open(pathname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
218           if (fd1 == -1)
219               errExit("open");
220
221           printf("Parent PID is %jd\n", (intmax_t) getpid());
222           printf("Parent opened file on FD %d\n\n", fd1);
223
224           switch (fork()) {
225           case -1:
226               errExit("fork");
227
228           case 0:
229               printf("PID of child of fork() is %jd\n", (intmax_t) getpid());
230
231               test_kcmp("Compare duplicate FDs from different processes:",
232                       getpid(), getppid(), fd1, fd1);
233
234               fd2 = open(pathname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
235               if (fd2 == -1)
236                   errExit("open");
237               printf("Child opened file on FD %d\n", fd2);
238
239               test_kcmp("Compare FDs from distinct open()s in same process:",
240                       getpid(), getpid(), fd1, fd2);
241
242               fd3 = dup(fd1);
243               if (fd3 == -1)
244                   errExit("dup");
245               printf("Child duplicated FD %d to create FD %d\n", fd1, fd3);
246
247               test_kcmp("Compare duplicated FDs in same process:",
248                       getpid(), getpid(), fd1, fd3);
249               break;
250
251           default:
252               wait(NULL);
253           }
254
255           exit(EXIT_SUCCESS);
256       }
257

SEE ALSO

259       clone(2), unshare(2)
260

COLOPHON

262       This page is part of release 5.12 of the Linux  man-pages  project.   A
263       description  of  the project, information about reporting bugs, and the
264       latest    version    of    this    page,    can     be     found     at
265       https://www.kernel.org/doc/man-pages/.
266
267
268
269Linux                             2021-03-22                           KCMP(2)
Impressum