]> git.ipfire.org Git - thirdparty/man-pages.git/blob - man2/kcmp.2
Many pages: Use .TP for tagged paragraphs
[thirdparty/man-pages.git] / man2 / kcmp.2
1 .\" Copyright (C) 2012, Cyrill Gorcunov <gorcunov@openvz.org>
2 .\" and Copyright (C) 2012, 2016, Michael Kerrisk <mtk.manpages@gmail.com>
3 .\"
4 .\" SPDX-License-Identifier: Linux-man-pages-copyleft
5 .\"
6 .\" Kernel commit d97b46a64674a267bc41c9e16132ee2a98c3347d
7 .\"
8 .TH KCMP 2 (date) "Linux man-pages (unreleased)"
9 .SH NAME
10 kcmp \- compare two processes to determine if they share a kernel resource
11 .SH LIBRARY
12 Standard C library
13 .RI ( libc ", " \-lc )
14 .SH SYNOPSIS
15 .nf
16 .BR "#include <linux/kcmp.h>" " /* Definition of " KCMP_* " constants */"
17 .BR "#include <sys/syscall.h>" " /* Definition of " SYS_* " constants */"
18 .B #include <unistd.h>
19 .PP
20 .BI "int syscall(SYS_kcmp, pid_t " pid1 ", pid_t " pid2 ", int " type ,
21 .BI " unsigned long " idx1 ", unsigned long " idx2 );
22 .fi
23 .PP
24 .IR Note :
25 glibc provides no wrapper for
26 .BR kcmp (),
27 necessitating the use of
28 .BR syscall (2).
29 .SH DESCRIPTION
30 The
31 .BR kcmp ()
32 system call can be used to check whether the two processes identified by
33 .I pid1
34 and
35 .I pid2
36 share a kernel resource such as virtual memory, file descriptors,
37 and so on.
38 .PP
39 Permission to employ
40 .BR kcmp ()
41 is governed by ptrace access mode
42 .B PTRACE_MODE_READ_REALCREDS
43 checks against both
44 .I pid1
45 and
46 .IR pid2 ;
47 see
48 .BR ptrace (2).
49 .PP
50 The
51 .I type
52 argument specifies which resource is to be compared in the two processes.
53 It has one of the following values:
54 .TP
55 .B KCMP_FILE
56 Check whether a file descriptor
57 .I idx1
58 in the process
59 .I pid1
60 refers to the same open file description (see
61 .BR open (2))
62 as file descriptor
63 .I idx2
64 in the process
65 .IR pid2 .
66 The existence of two file descriptors that refer to the same
67 open file description can occur as a result of
68 .BR dup (2)
69 (and similar)
70 .BR fork (2),
71 or passing file descriptors via a domain socket (see
72 .BR unix (7)).
73 .TP
74 .B KCMP_FILES
75 Check whether the processes share the same set of open file descriptors.
76 The arguments
77 .I idx1
78 and
79 .I idx2
80 are ignored.
81 See the discussion of the
82 .B CLONE_FILES
83 flag in
84 .BR clone (2).
85 .TP
86 .B KCMP_FS
87 Check whether the processes share the same filesystem information
88 (i.e., file mode creation mask, working directory, and filesystem root).
89 The arguments
90 .I idx1
91 and
92 .I idx2
93 are ignored.
94 See the discussion of the
95 .B CLONE_FS
96 flag in
97 .BR clone (2).
98 .TP
99 .B KCMP_IO
100 Check whether the processes share I/O context.
101 The arguments
102 .I idx1
103 and
104 .I idx2
105 are ignored.
106 See the discussion of the
107 .B CLONE_IO
108 flag in
109 .BR clone (2).
110 .TP
111 .B KCMP_SIGHAND
112 Check whether the processes share the same table of signal dispositions.
113 The arguments
114 .I idx1
115 and
116 .I idx2
117 are ignored.
118 See the discussion of the
119 .B CLONE_SIGHAND
120 flag in
121 .BR clone (2).
122 .TP
123 .B KCMP_SYSVSEM
124 Check whether the processes share the same
125 list of System\ V semaphore undo operations.
126 The arguments
127 .I idx1
128 and
129 .I idx2
130 are ignored.
131 See the discussion of the
132 .B CLONE_SYSVSEM
133 flag in
134 .BR clone (2).
135 .TP
136 .B KCMP_VM
137 Check whether the processes share the same address space.
138 The arguments
139 .I idx1
140 and
141 .I idx2
142 are ignored.
143 See the discussion of the
144 .B CLONE_VM
145 flag in
146 .BR clone (2).
147 .TP
148 .BR KCMP_EPOLL_TFD " (since Linux 4.13)"
149 .\" commit 0791e3644e5ef21646fe565b9061788d05ec71d4
150 Check whether the file descriptor
151 .I idx1
152 of the process
153 .I pid1
154 is present in the
155 .BR epoll (7)
156 instance described by
157 .I idx2
158 of the process
159 .IR pid2 .
160 The argument
161 .I idx2
162 is a pointer to a structure where the target file is described.
163 This structure has the form:
164 .PP
165 .in +4n
166 .EX
167 struct kcmp_epoll_slot {
168 __u32 efd;
169 __u32 tfd;
170 __u64 toff;
171 };
172 .EE
173 .in
174 .PP
175 Within this structure,
176 .I efd
177 is an epoll file descriptor returned from
178 .BR epoll_create (2),
179 .I tfd
180 is a target file descriptor number, and
181 .I toff
182 is a target file offset counted from zero.
183 Several different targets may be registered with
184 the same file descriptor number and setting a specific
185 offset helps to investigate each of them.
186 .PP
187 Note the
188 .BR kcmp ()
189 is not protected against false positives which may occur if
190 the processes are currently running.
191 One should stop the processes by sending
192 .B SIGSTOP
193 (see
194 .BR signal (7))
195 prior to inspection with this system call to obtain meaningful results.
196 .SH RETURN VALUE
197 The return value of a successful call to
198 .BR kcmp ()
199 is simply the result of arithmetic comparison
200 of kernel pointers (when the kernel compares resources, it uses their
201 memory addresses).
202 .PP
203 The easiest way to explain is to consider an example.
204 Suppose that
205 .I v1
206 and
207 .I v2
208 are the addresses of appropriate resources, then the return value
209 is one of the following:
210 .RS
211 .TP
212 .B 0
213 .I v1
214 is equal to
215 .IR v2 ;
216 in other words, the two processes share the resource.
217 .TP
218 .B 1
219 .I v1
220 is less than
221 .IR v2 .
222 .TP
223 .B 2
224 .I v1
225 is greater than
226 .IR v2 .
227 .TP
228 .B 3
229 .I v1
230 is not equal to
231 .IR v2 ,
232 but ordering information is unavailable.
233 .RE
234 .PP
235 On error, \-1 is returned, and
236 .I errno
237 is set to indicate the error.
238 .PP
239 .BR kcmp ()
240 was designed to return values suitable for sorting.
241 This is particularly handy if one needs to compare
242 a large number of file descriptors.
243 .SH ERRORS
244 .TP
245 .B EBADF
246 .I type
247 is
248 .B KCMP_FILE
249 and
250 .I fd1
251 or
252 .I fd2
253 is not an open file descriptor.
254 .TP
255 .B EFAULT
256 The epoll slot addressed by
257 .I idx2
258 is outside of the user's address space.
259 .TP
260 .B EINVAL
261 .I type
262 is invalid.
263 .TP
264 .B ENOENT
265 The target file is not present in
266 .BR epoll (7)
267 instance.
268 .TP
269 .B EPERM
270 Insufficient permission to inspect process resources.
271 The
272 .B CAP_SYS_PTRACE
273 capability is required to inspect processes that you do not own.
274 Other ptrace limitations may also apply, such as
275 .BR CONFIG_SECURITY_YAMA ,
276 which, when
277 .I /proc/sys/kernel/yama/ptrace_scope
278 is 2, limits
279 .BR kcmp ()
280 to child processes;
281 see
282 .BR ptrace (2).
283 .TP
284 .B ESRCH
285 Process
286 .I pid1
287 or
288 .I pid2
289 does not exist.
290 .SH VERSIONS
291 The
292 .BR kcmp ()
293 system call first appeared in Linux 3.5.
294 .SH STANDARDS
295 .BR kcmp ()
296 is Linux-specific and should not be used in programs intended to be portable.
297 .SH NOTES
298 Before Linux 5.12,
299 this system call is available only if the kernel is configured with
300 .BR CONFIG_CHECKPOINT_RESTORE ,
301 since the original purpose of the system call was for the
302 checkpoint/restore in user space (CRIU) feature.
303 (The alternative to this system call would have been to expose suitable
304 process information via the
305 .BR proc (5)
306 filesystem; this was deemed to be unsuitable for security reasons.)
307 Since Linux 5.12,
308 this system call is also available if the kernel is configured with
309 .BR CONFIG_KCMP .
310 .PP
311 See
312 .BR clone (2)
313 for some background information on the shared resources
314 referred to on this page.
315 .SH EXAMPLES
316 The program below uses
317 .BR kcmp ()
318 to test whether pairs of file descriptors refer to
319 the same open file description.
320 The program tests different cases for the file descriptor pairs,
321 as described in the program output.
322 An example run of the program is as follows:
323 .PP
324 .in +4n
325 .EX
326 $ \fB./a.out\fP
327 Parent PID is 1144
328 Parent opened file on FD 3
329
330 PID of child of fork() is 1145
331 Compare duplicate FDs from different processes:
332 kcmp(1145, 1144, KCMP_FILE, 3, 3) ==> same
333 Child opened file on FD 4
334 Compare FDs from distinct open()s in same process:
335 kcmp(1145, 1145, KCMP_FILE, 3, 4) ==> different
336 Child duplicated FD 3 to create FD 5
337 Compare duplicated FDs in same process:
338 kcmp(1145, 1145, KCMP_FILE, 3, 5) ==> same
339 .EE
340 .in
341 .SS Program source
342 \&
343 .\" SRC BEGIN (kcmp.c)
344 .EX
345 #define _GNU_SOURCE
346 #include <err.h>
347 #include <fcntl.h>
348 #include <linux/kcmp.h>
349 #include <stdint.h>
350 #include <stdio.h>
351 #include <stdlib.h>
352 #include <sys/syscall.h>
353 #include <sys/wait.h>
354 #include <unistd.h>
355
356 static int
357 kcmp(pid_t pid1, pid_t pid2, int type,
358 unsigned long idx1, unsigned long idx2)
359 {
360 return syscall(SYS_kcmp, pid1, pid2, type, idx1, idx2);
361 }
362
363 static void
364 test_kcmp(char *msg, pid_t pid1, pid_t pid2, int fd_a, int fd_b)
365 {
366 printf("\et%s\en", msg);
367 printf("\et\etkcmp(%jd, %jd, KCMP_FILE, %d, %d) ==> %s\en",
368 (intmax_t) pid1, (intmax_t) pid2, fd_a, fd_b,
369 (kcmp(pid1, pid2, KCMP_FILE, fd_a, fd_b) == 0) ?
370 "same" : "different");
371 }
372
373 int
374 main(void)
375 {
376 int fd1, fd2, fd3;
377 static const char pathname[] = "/tmp/kcmp.test";
378
379 fd1 = open(pathname, O_CREAT | O_RDWR, 0600);
380 if (fd1 == \-1)
381 err(EXIT_FAILURE, "open");
382
383 printf("Parent PID is %jd\en", (intmax_t) getpid());
384 printf("Parent opened file on FD %d\en\en", fd1);
385
386 switch (fork()) {
387 case \-1:
388 err(EXIT_FAILURE, "fork");
389
390 case 0:
391 printf("PID of child of fork() is %jd\en", (intmax_t) getpid());
392
393 test_kcmp("Compare duplicate FDs from different processes:",
394 getpid(), getppid(), fd1, fd1);
395
396 fd2 = open(pathname, O_CREAT | O_RDWR, 0600);
397 if (fd2 == \-1)
398 err(EXIT_FAILURE, "open");
399 printf("Child opened file on FD %d\en", fd2);
400
401 test_kcmp("Compare FDs from distinct open()s in same process:",
402 getpid(), getpid(), fd1, fd2);
403
404 fd3 = dup(fd1);
405 if (fd3 == \-1)
406 err(EXIT_FAILURE, "dup");
407 printf("Child duplicated FD %d to create FD %d\en", fd1, fd3);
408
409 test_kcmp("Compare duplicated FDs in same process:",
410 getpid(), getpid(), fd1, fd3);
411 break;
412
413 default:
414 wait(NULL);
415 }
416
417 exit(EXIT_SUCCESS);
418 }
419 .EE
420 .\" SRC END
421 .SH SEE ALSO
422 .BR clone (2),
423 .BR unshare (2)