xref: /linux/tools/testing/selftests/coredump/stackdump_test.c (revision 260f6f4fda93c8485c8037865c941b42b9cba5d2)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 #include <assert.h>
4 #include <fcntl.h>
5 #include <inttypes.h>
6 #include <libgen.h>
7 #include <limits.h>
8 #include <linux/coredump.h>
9 #include <linux/fs.h>
10 #include <linux/limits.h>
11 #include <pthread.h>
12 #include <string.h>
13 #include <sys/mount.h>
14 #include <poll.h>
15 #include <sys/epoll.h>
16 #include <sys/resource.h>
17 #include <sys/stat.h>
18 #include <sys/socket.h>
19 #include <sys/un.h>
20 #include <unistd.h>
21 
22 #include "../kselftest_harness.h"
23 #include "../filesystems/wrappers.h"
24 #include "../pidfd/pidfd.h"
25 
26 #define STACKDUMP_FILE "stack_values"
27 #define STACKDUMP_SCRIPT "stackdump"
28 #define NUM_THREAD_SPAWN 128
29 
30 #ifndef PAGE_SIZE
31 #define PAGE_SIZE 4096
32 #endif
33 
34 static void *do_nothing(void *)
35 {
36 	while (1)
37 		pause();
38 
39 	return NULL;
40 }
41 
42 static void crashing_child(void)
43 {
44 	pthread_t thread;
45 	int i;
46 
47 	for (i = 0; i < NUM_THREAD_SPAWN; ++i)
48 		pthread_create(&thread, NULL, do_nothing, NULL);
49 
50 	/* crash on purpose */
51 	i = *(int *)NULL;
52 }
53 
54 FIXTURE(coredump)
55 {
56 	char original_core_pattern[256];
57 	pid_t pid_coredump_server;
58 	int fd_tmpfs_detached;
59 };
60 
61 static int create_detached_tmpfs(void)
62 {
63 	int fd_context, fd_tmpfs;
64 
65 	fd_context = sys_fsopen("tmpfs", 0);
66 	if (fd_context < 0)
67 		return -1;
68 
69 	if (sys_fsconfig(fd_context, FSCONFIG_CMD_CREATE, NULL, NULL, 0) < 0)
70 		return -1;
71 
72 	fd_tmpfs = sys_fsmount(fd_context, 0, 0);
73 	close(fd_context);
74 	return fd_tmpfs;
75 }
76 
77 FIXTURE_SETUP(coredump)
78 {
79 	FILE *file;
80 	int ret;
81 
82 	self->pid_coredump_server = -ESRCH;
83 	self->fd_tmpfs_detached = -1;
84 	file = fopen("/proc/sys/kernel/core_pattern", "r");
85 	ASSERT_NE(NULL, file);
86 
87 	ret = fread(self->original_core_pattern, 1, sizeof(self->original_core_pattern), file);
88 	ASSERT_TRUE(ret || feof(file));
89 	ASSERT_LT(ret, sizeof(self->original_core_pattern));
90 
91 	self->original_core_pattern[ret] = '\0';
92 	self->fd_tmpfs_detached = create_detached_tmpfs();
93 	ASSERT_GE(self->fd_tmpfs_detached, 0);
94 
95 	ret = fclose(file);
96 	ASSERT_EQ(0, ret);
97 }
98 
99 FIXTURE_TEARDOWN(coredump)
100 {
101 	const char *reason;
102 	FILE *file;
103 	int ret, status;
104 
105 	unlink(STACKDUMP_FILE);
106 
107 	if (self->pid_coredump_server > 0) {
108 		kill(self->pid_coredump_server, SIGTERM);
109 		waitpid(self->pid_coredump_server, &status, 0);
110 	}
111 	unlink("/tmp/coredump.file");
112 	unlink("/tmp/coredump.socket");
113 
114 	file = fopen("/proc/sys/kernel/core_pattern", "w");
115 	if (!file) {
116 		reason = "Unable to open core_pattern";
117 		goto fail;
118 	}
119 
120 	ret = fprintf(file, "%s", self->original_core_pattern);
121 	if (ret < 0) {
122 		reason = "Unable to write to core_pattern";
123 		goto fail;
124 	}
125 
126 	ret = fclose(file);
127 	if (ret) {
128 		reason = "Unable to close core_pattern";
129 		goto fail;
130 	}
131 
132 	if (self->fd_tmpfs_detached >= 0) {
133 		ret = close(self->fd_tmpfs_detached);
134 		if (ret < 0) {
135 			reason = "Unable to close detached tmpfs";
136 			goto fail;
137 		}
138 		self->fd_tmpfs_detached = -1;
139 	}
140 
141 	return;
142 fail:
143 	/* This should never happen */
144 	fprintf(stderr, "Failed to cleanup stackdump test: %s\n", reason);
145 }
146 
147 TEST_F_TIMEOUT(coredump, stackdump, 120)
148 {
149 	unsigned long long stack;
150 	char *test_dir, *line;
151 	size_t line_length;
152 	char buf[PAGE_SIZE];
153 	int ret, i, status;
154 	FILE *file;
155 	pid_t pid;
156 
157 	/*
158 	 * Step 1: Setup core_pattern so that the stackdump script is executed when the child
159 	 * process crashes
160 	 */
161 	ret = readlink("/proc/self/exe", buf, sizeof(buf));
162 	ASSERT_NE(-1, ret);
163 	ASSERT_LT(ret, sizeof(buf));
164 	buf[ret] = '\0';
165 
166 	test_dir = dirname(buf);
167 
168 	file = fopen("/proc/sys/kernel/core_pattern", "w");
169 	ASSERT_NE(NULL, file);
170 
171 	ret = fprintf(file, "|%1$s/%2$s %%P %1$s/%3$s", test_dir, STACKDUMP_SCRIPT, STACKDUMP_FILE);
172 	ASSERT_LT(0, ret);
173 
174 	ret = fclose(file);
175 	ASSERT_EQ(0, ret);
176 
177 	/* Step 2: Create a process who spawns some threads then crashes */
178 	pid = fork();
179 	ASSERT_TRUE(pid >= 0);
180 	if (pid == 0)
181 		crashing_child();
182 
183 	/*
184 	 * Step 3: Wait for the stackdump script to write the stack pointers to the stackdump file
185 	 */
186 	waitpid(pid, &status, 0);
187 	ASSERT_TRUE(WIFSIGNALED(status));
188 	ASSERT_TRUE(WCOREDUMP(status));
189 
190 	for (i = 0; i < 10; ++i) {
191 		file = fopen(STACKDUMP_FILE, "r");
192 		if (file)
193 			break;
194 		sleep(1);
195 	}
196 	ASSERT_NE(file, NULL);
197 
198 	/* Step 4: Make sure all stack pointer values are non-zero */
199 	line = NULL;
200 	for (i = 0; -1 != getline(&line, &line_length, file); ++i) {
201 		stack = strtoull(line, NULL, 10);
202 		ASSERT_NE(stack, 0);
203 	}
204 	free(line);
205 
206 	ASSERT_EQ(i, 1 + NUM_THREAD_SPAWN);
207 
208 	fclose(file);
209 }
210 
211 static int create_and_listen_unix_socket(const char *path)
212 {
213 	struct sockaddr_un addr = {
214 		.sun_family = AF_UNIX,
215 	};
216 	assert(strlen(path) < sizeof(addr.sun_path) - 1);
217 	strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
218 	size_t addr_len =
219 		offsetof(struct sockaddr_un, sun_path) + strlen(path) + 1;
220 	int fd, ret;
221 
222 	fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
223 	if (fd < 0)
224 		goto out;
225 
226 	ret = bind(fd, (const struct sockaddr *)&addr, addr_len);
227 	if (ret < 0)
228 		goto out;
229 
230 	ret = listen(fd, 128);
231 	if (ret < 0)
232 		goto out;
233 
234 	return fd;
235 
236 out:
237 	if (fd >= 0)
238 		close(fd);
239 	return -1;
240 }
241 
242 static bool set_core_pattern(const char *pattern)
243 {
244 	int fd;
245 	ssize_t ret;
246 
247 	fd = open("/proc/sys/kernel/core_pattern", O_WRONLY | O_CLOEXEC);
248 	if (fd < 0)
249 		return false;
250 
251 	ret = write(fd, pattern, strlen(pattern));
252 	close(fd);
253 	if (ret < 0)
254 		return false;
255 
256 	fprintf(stderr, "Set core_pattern to '%s' | %zu == %zu\n", pattern, ret, strlen(pattern));
257 	return ret == strlen(pattern);
258 }
259 
260 static int get_peer_pidfd(int fd)
261 {
262 	int fd_peer_pidfd;
263 	socklen_t fd_peer_pidfd_len = sizeof(fd_peer_pidfd);
264 	int ret = getsockopt(fd, SOL_SOCKET, SO_PEERPIDFD, &fd_peer_pidfd,
265 			     &fd_peer_pidfd_len);
266 	if (ret < 0) {
267 		fprintf(stderr, "%m - Failed to retrieve peer pidfd for coredump socket connection\n");
268 		return -1;
269 	}
270 	return fd_peer_pidfd;
271 }
272 
273 static bool get_pidfd_info(int fd_peer_pidfd, struct pidfd_info *info)
274 {
275 	memset(info, 0, sizeof(*info));
276 	info->mask = PIDFD_INFO_EXIT | PIDFD_INFO_COREDUMP;
277 	return ioctl(fd_peer_pidfd, PIDFD_GET_INFO, info) == 0;
278 }
279 
280 static void
281 wait_and_check_coredump_server(pid_t pid_coredump_server,
282 			       struct __test_metadata *const _metadata,
283 			       FIXTURE_DATA(coredump)* self)
284 {
285 	int status;
286 	waitpid(pid_coredump_server, &status, 0);
287 	self->pid_coredump_server = -ESRCH;
288 	ASSERT_TRUE(WIFEXITED(status));
289 	ASSERT_EQ(WEXITSTATUS(status), 0);
290 }
291 
292 TEST_F(coredump, socket)
293 {
294 	int pidfd, ret, status;
295 	pid_t pid, pid_coredump_server;
296 	struct stat st;
297 	struct pidfd_info info = {};
298 	int ipc_sockets[2];
299 	char c;
300 
301 	ASSERT_TRUE(set_core_pattern("@/tmp/coredump.socket"));
302 
303 	ret = socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
304 	ASSERT_EQ(ret, 0);
305 
306 	pid_coredump_server = fork();
307 	ASSERT_GE(pid_coredump_server, 0);
308 	if (pid_coredump_server == 0) {
309 		int fd_server = -1, fd_coredump = -1, fd_peer_pidfd = -1, fd_core_file = -1;
310 		int exit_code = EXIT_FAILURE;
311 
312 		close(ipc_sockets[0]);
313 
314 		fd_server = create_and_listen_unix_socket("/tmp/coredump.socket");
315 		if (fd_server < 0)
316 			goto out;
317 
318 		if (write_nointr(ipc_sockets[1], "1", 1) < 0)
319 			goto out;
320 
321 		close(ipc_sockets[1]);
322 
323 		fd_coredump = accept4(fd_server, NULL, NULL, SOCK_CLOEXEC);
324 		if (fd_coredump < 0)
325 			goto out;
326 
327 		fd_peer_pidfd = get_peer_pidfd(fd_coredump);
328 		if (fd_peer_pidfd < 0)
329 			goto out;
330 
331 		if (!get_pidfd_info(fd_peer_pidfd, &info))
332 			goto out;
333 
334 		if (!(info.mask & PIDFD_INFO_COREDUMP))
335 			goto out;
336 
337 		if (!(info.coredump_mask & PIDFD_COREDUMPED))
338 			goto out;
339 
340 		fd_core_file = creat("/tmp/coredump.file", 0644);
341 		if (fd_core_file < 0)
342 			goto out;
343 
344 		for (;;) {
345 			char buffer[4096];
346 			ssize_t bytes_read, bytes_write;
347 
348 			bytes_read = read(fd_coredump, buffer, sizeof(buffer));
349 			if (bytes_read < 0)
350 				goto out;
351 
352 			if (bytes_read == 0)
353 				break;
354 
355 			bytes_write = write(fd_core_file, buffer, bytes_read);
356 			if (bytes_read != bytes_write)
357 				goto out;
358 		}
359 
360 		exit_code = EXIT_SUCCESS;
361 out:
362 		if (fd_core_file >= 0)
363 			close(fd_core_file);
364 		if (fd_peer_pidfd >= 0)
365 			close(fd_peer_pidfd);
366 		if (fd_coredump >= 0)
367 			close(fd_coredump);
368 		if (fd_server >= 0)
369 			close(fd_server);
370 		_exit(exit_code);
371 	}
372 	self->pid_coredump_server = pid_coredump_server;
373 
374 	EXPECT_EQ(close(ipc_sockets[1]), 0);
375 	ASSERT_EQ(read_nointr(ipc_sockets[0], &c, 1), 1);
376 	EXPECT_EQ(close(ipc_sockets[0]), 0);
377 
378 	pid = fork();
379 	ASSERT_GE(pid, 0);
380 	if (pid == 0)
381 		crashing_child();
382 
383 	pidfd = sys_pidfd_open(pid, 0);
384 	ASSERT_GE(pidfd, 0);
385 
386 	waitpid(pid, &status, 0);
387 	ASSERT_TRUE(WIFSIGNALED(status));
388 	ASSERT_TRUE(WCOREDUMP(status));
389 
390 	ASSERT_TRUE(get_pidfd_info(pidfd, &info));
391 	ASSERT_GT((info.mask & PIDFD_INFO_COREDUMP), 0);
392 	ASSERT_GT((info.coredump_mask & PIDFD_COREDUMPED), 0);
393 
394 	wait_and_check_coredump_server(pid_coredump_server, _metadata, self);
395 
396 	ASSERT_EQ(stat("/tmp/coredump.file", &st), 0);
397 	ASSERT_GT(st.st_size, 0);
398 	system("file /tmp/coredump.file");
399 }
400 
401 TEST_F(coredump, socket_detect_userspace_client)
402 {
403 	int pidfd, ret, status;
404 	pid_t pid, pid_coredump_server;
405 	struct stat st;
406 	struct pidfd_info info = {};
407 	int ipc_sockets[2];
408 	char c;
409 
410 	ASSERT_TRUE(set_core_pattern("@/tmp/coredump.socket"));
411 
412 	ret = socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
413 	ASSERT_EQ(ret, 0);
414 
415 	pid_coredump_server = fork();
416 	ASSERT_GE(pid_coredump_server, 0);
417 	if (pid_coredump_server == 0) {
418 		int fd_server = -1, fd_coredump = -1, fd_peer_pidfd = -1;
419 		int exit_code = EXIT_FAILURE;
420 
421 		close(ipc_sockets[0]);
422 
423 		fd_server = create_and_listen_unix_socket("/tmp/coredump.socket");
424 		if (fd_server < 0)
425 			goto out;
426 
427 		if (write_nointr(ipc_sockets[1], "1", 1) < 0)
428 			goto out;
429 
430 		close(ipc_sockets[1]);
431 
432 		fd_coredump = accept4(fd_server, NULL, NULL, SOCK_CLOEXEC);
433 		if (fd_coredump < 0)
434 			goto out;
435 
436 		fd_peer_pidfd = get_peer_pidfd(fd_coredump);
437 		if (fd_peer_pidfd < 0)
438 			goto out;
439 
440 		if (!get_pidfd_info(fd_peer_pidfd, &info))
441 			goto out;
442 
443 		if (!(info.mask & PIDFD_INFO_COREDUMP))
444 			goto out;
445 
446 		if (info.coredump_mask & PIDFD_COREDUMPED)
447 			goto out;
448 
449 		if (read(fd_coredump, &c, 1) < 1)
450 			goto out;
451 
452 		exit_code = EXIT_SUCCESS;
453 out:
454 		if (fd_peer_pidfd >= 0)
455 			close(fd_peer_pidfd);
456 		if (fd_coredump >= 0)
457 			close(fd_coredump);
458 		if (fd_server >= 0)
459 			close(fd_server);
460 		_exit(exit_code);
461 	}
462 	self->pid_coredump_server = pid_coredump_server;
463 
464 	EXPECT_EQ(close(ipc_sockets[1]), 0);
465 	ASSERT_EQ(read_nointr(ipc_sockets[0], &c, 1), 1);
466 	EXPECT_EQ(close(ipc_sockets[0]), 0);
467 
468 	pid = fork();
469 	ASSERT_GE(pid, 0);
470 	if (pid == 0) {
471 		int fd_socket;
472 		ssize_t ret;
473 		const struct sockaddr_un coredump_sk = {
474 			.sun_family = AF_UNIX,
475 			.sun_path = "/tmp/coredump.socket",
476 		};
477 		size_t coredump_sk_len =
478 			offsetof(struct sockaddr_un, sun_path) +
479 			sizeof("/tmp/coredump.socket");
480 
481 		fd_socket = socket(AF_UNIX, SOCK_STREAM, 0);
482 		if (fd_socket < 0)
483 			_exit(EXIT_FAILURE);
484 
485 		ret = connect(fd_socket, (const struct sockaddr *)&coredump_sk, coredump_sk_len);
486 		if (ret < 0)
487 			_exit(EXIT_FAILURE);
488 
489 		close(fd_socket);
490 		_exit(EXIT_SUCCESS);
491 	}
492 
493 	pidfd = sys_pidfd_open(pid, 0);
494 	ASSERT_GE(pidfd, 0);
495 
496 	waitpid(pid, &status, 0);
497 	ASSERT_TRUE(WIFEXITED(status));
498 	ASSERT_EQ(WEXITSTATUS(status), 0);
499 
500 	ASSERT_TRUE(get_pidfd_info(pidfd, &info));
501 	ASSERT_GT((info.mask & PIDFD_INFO_COREDUMP), 0);
502 	ASSERT_EQ((info.coredump_mask & PIDFD_COREDUMPED), 0);
503 
504 	wait_and_check_coredump_server(pid_coredump_server, _metadata, self);
505 
506 	ASSERT_NE(stat("/tmp/coredump.file", &st), 0);
507 	ASSERT_EQ(errno, ENOENT);
508 }
509 
510 TEST_F(coredump, socket_enoent)
511 {
512 	int pidfd, status;
513 	pid_t pid;
514 
515 	ASSERT_TRUE(set_core_pattern("@/tmp/coredump.socket"));
516 
517 	pid = fork();
518 	ASSERT_GE(pid, 0);
519 	if (pid == 0)
520 		crashing_child();
521 
522 	pidfd = sys_pidfd_open(pid, 0);
523 	ASSERT_GE(pidfd, 0);
524 
525 	waitpid(pid, &status, 0);
526 	ASSERT_TRUE(WIFSIGNALED(status));
527 	ASSERT_FALSE(WCOREDUMP(status));
528 }
529 
530 TEST_F(coredump, socket_no_listener)
531 {
532 	int pidfd, ret, status;
533 	pid_t pid, pid_coredump_server;
534 	int ipc_sockets[2];
535 	char c;
536 	const struct sockaddr_un coredump_sk = {
537 		.sun_family = AF_UNIX,
538 		.sun_path = "/tmp/coredump.socket",
539 	};
540 	size_t coredump_sk_len = offsetof(struct sockaddr_un, sun_path) +
541 				 sizeof("/tmp/coredump.socket");
542 
543 	ASSERT_TRUE(set_core_pattern("@/tmp/coredump.socket"));
544 
545 	ret = socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
546 	ASSERT_EQ(ret, 0);
547 
548 	pid_coredump_server = fork();
549 	ASSERT_GE(pid_coredump_server, 0);
550 	if (pid_coredump_server == 0) {
551 		int fd_server = -1;
552 		int exit_code = EXIT_FAILURE;
553 
554 		close(ipc_sockets[0]);
555 
556 		fd_server = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
557 		if (fd_server < 0)
558 			goto out;
559 
560 		ret = bind(fd_server, (const struct sockaddr *)&coredump_sk, coredump_sk_len);
561 		if (ret < 0)
562 			goto out;
563 
564 		if (write_nointr(ipc_sockets[1], "1", 1) < 0)
565 			goto out;
566 
567 		exit_code = EXIT_SUCCESS;
568 out:
569 		if (fd_server >= 0)
570 			close(fd_server);
571 		close(ipc_sockets[1]);
572 		_exit(exit_code);
573 	}
574 	self->pid_coredump_server = pid_coredump_server;
575 
576 	EXPECT_EQ(close(ipc_sockets[1]), 0);
577 	ASSERT_EQ(read_nointr(ipc_sockets[0], &c, 1), 1);
578 	EXPECT_EQ(close(ipc_sockets[0]), 0);
579 
580 	pid = fork();
581 	ASSERT_GE(pid, 0);
582 	if (pid == 0)
583 		crashing_child();
584 
585 	pidfd = sys_pidfd_open(pid, 0);
586 	ASSERT_GE(pidfd, 0);
587 
588 	waitpid(pid, &status, 0);
589 	ASSERT_TRUE(WIFSIGNALED(status));
590 	ASSERT_FALSE(WCOREDUMP(status));
591 
592 	wait_and_check_coredump_server(pid_coredump_server, _metadata, self);
593 }
594 
595 static ssize_t recv_marker(int fd)
596 {
597 	enum coredump_mark mark = COREDUMP_MARK_REQACK;
598 	ssize_t ret;
599 
600 	ret = recv(fd, &mark, sizeof(mark), MSG_WAITALL);
601 	if (ret != sizeof(mark))
602 		return -1;
603 
604 	switch (mark) {
605 	case COREDUMP_MARK_REQACK:
606 		fprintf(stderr, "Received marker: ReqAck\n");
607 		return COREDUMP_MARK_REQACK;
608 	case COREDUMP_MARK_MINSIZE:
609 		fprintf(stderr, "Received marker: MinSize\n");
610 		return COREDUMP_MARK_MINSIZE;
611 	case COREDUMP_MARK_MAXSIZE:
612 		fprintf(stderr, "Received marker: MaxSize\n");
613 		return COREDUMP_MARK_MAXSIZE;
614 	case COREDUMP_MARK_UNSUPPORTED:
615 		fprintf(stderr, "Received marker: Unsupported\n");
616 		return COREDUMP_MARK_UNSUPPORTED;
617 	case COREDUMP_MARK_CONFLICTING:
618 		fprintf(stderr, "Received marker: Conflicting\n");
619 		return COREDUMP_MARK_CONFLICTING;
620 	default:
621 		fprintf(stderr, "Received unknown marker: %u\n", mark);
622 		break;
623 	}
624 	return -1;
625 }
626 
627 static bool read_marker(int fd, enum coredump_mark mark)
628 {
629 	ssize_t ret;
630 
631 	ret = recv_marker(fd);
632 	if (ret < 0)
633 		return false;
634 	return ret == mark;
635 }
636 
637 static bool read_coredump_req(int fd, struct coredump_req *req)
638 {
639 	ssize_t ret;
640 	size_t field_size, user_size, ack_size, kernel_size, remaining_size;
641 
642 	memset(req, 0, sizeof(*req));
643 	field_size = sizeof(req->size);
644 
645 	/* Peek the size of the coredump request. */
646 	ret = recv(fd, req, field_size, MSG_PEEK | MSG_WAITALL);
647 	if (ret != field_size)
648 		return false;
649 	kernel_size = req->size;
650 
651 	if (kernel_size < COREDUMP_ACK_SIZE_VER0)
652 		return false;
653 	if (kernel_size >= PAGE_SIZE)
654 		return false;
655 
656 	/* Use the minimum of user and kernel size to read the full request. */
657 	user_size = sizeof(struct coredump_req);
658 	ack_size = user_size < kernel_size ? user_size : kernel_size;
659 	ret = recv(fd, req, ack_size, MSG_WAITALL);
660 	if (ret != ack_size)
661 		return false;
662 
663 	fprintf(stderr, "Read coredump request with size %u and mask 0x%llx\n",
664 		req->size, (unsigned long long)req->mask);
665 
666 	if (user_size > kernel_size)
667 		remaining_size = user_size - kernel_size;
668 	else
669 		remaining_size = kernel_size - user_size;
670 
671 	if (PAGE_SIZE <= remaining_size)
672 		return false;
673 
674 	/*
675 	 * Discard any additional data if the kernel's request was larger than
676 	 * what we knew about or cared about.
677 	 */
678 	if (remaining_size) {
679 		char buffer[PAGE_SIZE];
680 
681 		ret = recv(fd, buffer, sizeof(buffer), MSG_WAITALL);
682 		if (ret != remaining_size)
683 			return false;
684 		fprintf(stderr, "Discarded %zu bytes of data after coredump request\n", remaining_size);
685 	}
686 
687 	return true;
688 }
689 
690 static bool send_coredump_ack(int fd, const struct coredump_req *req,
691 			      __u64 mask, size_t size_ack)
692 {
693 	ssize_t ret;
694 	/*
695 	 * Wrap struct coredump_ack in a larger struct so we can
696 	 * simulate sending to much data to the kernel.
697 	 */
698 	struct large_ack_for_size_testing {
699 		struct coredump_ack ack;
700 		char buffer[PAGE_SIZE];
701 	} large_ack = {};
702 
703 	if (!size_ack)
704 		size_ack = sizeof(struct coredump_ack) < req->size_ack ?
705 				   sizeof(struct coredump_ack) :
706 				   req->size_ack;
707 	large_ack.ack.mask = mask;
708 	large_ack.ack.size = size_ack;
709 	ret = send(fd, &large_ack, size_ack, MSG_NOSIGNAL);
710 	if (ret != size_ack)
711 		return false;
712 
713 	fprintf(stderr, "Sent coredump ack with size %zu and mask 0x%llx\n",
714 		size_ack, (unsigned long long)mask);
715 	return true;
716 }
717 
718 static bool check_coredump_req(const struct coredump_req *req, size_t min_size,
719 			       __u64 required_mask)
720 {
721 	if (req->size < min_size)
722 		return false;
723 	if ((req->mask & required_mask) != required_mask)
724 		return false;
725 	if (req->mask & ~required_mask)
726 		return false;
727 	return true;
728 }
729 
730 TEST_F(coredump, socket_request_kernel)
731 {
732 	int pidfd, ret, status;
733 	pid_t pid, pid_coredump_server;
734 	struct stat st;
735 	struct pidfd_info info = {};
736 	int ipc_sockets[2];
737 	char c;
738 
739 	ASSERT_TRUE(set_core_pattern("@@/tmp/coredump.socket"));
740 
741 	ret = socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
742 	ASSERT_EQ(ret, 0);
743 
744 	pid_coredump_server = fork();
745 	ASSERT_GE(pid_coredump_server, 0);
746 	if (pid_coredump_server == 0) {
747 		struct coredump_req req = {};
748 		int fd_server = -1, fd_coredump = -1, fd_core_file = -1, fd_peer_pidfd = -1;
749 		int exit_code = EXIT_FAILURE;
750 
751 		close(ipc_sockets[0]);
752 
753 		fd_server = create_and_listen_unix_socket("/tmp/coredump.socket");
754 		if (fd_server < 0)
755 			goto out;
756 
757 		if (write_nointr(ipc_sockets[1], "1", 1) < 0)
758 			goto out;
759 
760 		close(ipc_sockets[1]);
761 
762 		fd_coredump = accept4(fd_server, NULL, NULL, SOCK_CLOEXEC);
763 		if (fd_coredump < 0)
764 			goto out;
765 
766 		fd_peer_pidfd = get_peer_pidfd(fd_coredump);
767 		if (fd_peer_pidfd < 0)
768 			goto out;
769 
770 		if (!get_pidfd_info(fd_peer_pidfd, &info))
771 			goto out;
772 
773 		if (!(info.mask & PIDFD_INFO_COREDUMP))
774 			goto out;
775 
776 		if (!(info.coredump_mask & PIDFD_COREDUMPED))
777 			goto out;
778 
779 		fd_core_file = creat("/tmp/coredump.file", 0644);
780 		if (fd_core_file < 0)
781 			goto out;
782 
783 		if (!read_coredump_req(fd_coredump, &req))
784 			goto out;
785 
786 		if (!check_coredump_req(&req, COREDUMP_ACK_SIZE_VER0,
787 					COREDUMP_KERNEL | COREDUMP_USERSPACE |
788 					COREDUMP_REJECT | COREDUMP_WAIT))
789 			goto out;
790 
791 		if (!send_coredump_ack(fd_coredump, &req,
792 				       COREDUMP_KERNEL | COREDUMP_WAIT, 0))
793 			goto out;
794 
795 		if (!read_marker(fd_coredump, COREDUMP_MARK_REQACK))
796 			goto out;
797 
798 		for (;;) {
799 			char buffer[4096];
800 			ssize_t bytes_read, bytes_write;
801 
802 			bytes_read = read(fd_coredump, buffer, sizeof(buffer));
803 			if (bytes_read < 0)
804 				goto out;
805 
806 			if (bytes_read == 0)
807 				break;
808 
809 			bytes_write = write(fd_core_file, buffer, bytes_read);
810 			if (bytes_read != bytes_write)
811 				goto out;
812 		}
813 
814 		exit_code = EXIT_SUCCESS;
815 out:
816 		if (fd_core_file >= 0)
817 			close(fd_core_file);
818 		if (fd_peer_pidfd >= 0)
819 			close(fd_peer_pidfd);
820 		if (fd_coredump >= 0)
821 			close(fd_coredump);
822 		if (fd_server >= 0)
823 			close(fd_server);
824 		_exit(exit_code);
825 	}
826 	self->pid_coredump_server = pid_coredump_server;
827 
828 	EXPECT_EQ(close(ipc_sockets[1]), 0);
829 	ASSERT_EQ(read_nointr(ipc_sockets[0], &c, 1), 1);
830 	EXPECT_EQ(close(ipc_sockets[0]), 0);
831 
832 	pid = fork();
833 	ASSERT_GE(pid, 0);
834 	if (pid == 0)
835 		crashing_child();
836 
837 	pidfd = sys_pidfd_open(pid, 0);
838 	ASSERT_GE(pidfd, 0);
839 
840 	waitpid(pid, &status, 0);
841 	ASSERT_TRUE(WIFSIGNALED(status));
842 	ASSERT_TRUE(WCOREDUMP(status));
843 
844 	ASSERT_TRUE(get_pidfd_info(pidfd, &info));
845 	ASSERT_GT((info.mask & PIDFD_INFO_COREDUMP), 0);
846 	ASSERT_GT((info.coredump_mask & PIDFD_COREDUMPED), 0);
847 
848 	wait_and_check_coredump_server(pid_coredump_server, _metadata, self);
849 
850 	ASSERT_EQ(stat("/tmp/coredump.file", &st), 0);
851 	ASSERT_GT(st.st_size, 0);
852 	system("file /tmp/coredump.file");
853 }
854 
855 TEST_F(coredump, socket_request_userspace)
856 {
857 	int pidfd, ret, status;
858 	pid_t pid, pid_coredump_server;
859 	struct pidfd_info info = {};
860 	int ipc_sockets[2];
861 	char c;
862 
863 	ASSERT_TRUE(set_core_pattern("@@/tmp/coredump.socket"));
864 
865 	ret = socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
866 	ASSERT_EQ(ret, 0);
867 
868 	pid_coredump_server = fork();
869 	ASSERT_GE(pid_coredump_server, 0);
870 	if (pid_coredump_server == 0) {
871 		struct coredump_req req = {};
872 		int fd_server = -1, fd_coredump = -1, fd_peer_pidfd = -1;
873 		int exit_code = EXIT_FAILURE;
874 
875 		close(ipc_sockets[0]);
876 
877 		fd_server = create_and_listen_unix_socket("/tmp/coredump.socket");
878 		if (fd_server < 0)
879 			goto out;
880 
881 		if (write_nointr(ipc_sockets[1], "1", 1) < 0)
882 			goto out;
883 
884 		close(ipc_sockets[1]);
885 
886 		fd_coredump = accept4(fd_server, NULL, NULL, SOCK_CLOEXEC);
887 		if (fd_coredump < 0)
888 			goto out;
889 
890 		fd_peer_pidfd = get_peer_pidfd(fd_coredump);
891 		if (fd_peer_pidfd < 0)
892 			goto out;
893 
894 		if (!get_pidfd_info(fd_peer_pidfd, &info))
895 			goto out;
896 
897 		if (!(info.mask & PIDFD_INFO_COREDUMP))
898 			goto out;
899 
900 		if (!(info.coredump_mask & PIDFD_COREDUMPED))
901 			goto out;
902 
903 		if (!read_coredump_req(fd_coredump, &req))
904 			goto out;
905 
906 		if (!check_coredump_req(&req, COREDUMP_ACK_SIZE_VER0,
907 					COREDUMP_KERNEL | COREDUMP_USERSPACE |
908 					COREDUMP_REJECT | COREDUMP_WAIT))
909 			goto out;
910 
911 		if (!send_coredump_ack(fd_coredump, &req,
912 				       COREDUMP_USERSPACE | COREDUMP_WAIT, 0))
913 			goto out;
914 
915 		if (!read_marker(fd_coredump, COREDUMP_MARK_REQACK))
916 			goto out;
917 
918 		for (;;) {
919 			char buffer[4096];
920 			ssize_t bytes_read;
921 
922 			bytes_read = read(fd_coredump, buffer, sizeof(buffer));
923 			if (bytes_read > 0)
924 				goto out;
925 
926 			if (bytes_read < 0)
927 				goto out;
928 
929 			if (bytes_read == 0)
930 				break;
931 		}
932 
933 		exit_code = EXIT_SUCCESS;
934 out:
935 		if (fd_peer_pidfd >= 0)
936 			close(fd_peer_pidfd);
937 		if (fd_coredump >= 0)
938 			close(fd_coredump);
939 		if (fd_server >= 0)
940 			close(fd_server);
941 		_exit(exit_code);
942 	}
943 	self->pid_coredump_server = pid_coredump_server;
944 
945 	EXPECT_EQ(close(ipc_sockets[1]), 0);
946 	ASSERT_EQ(read_nointr(ipc_sockets[0], &c, 1), 1);
947 	EXPECT_EQ(close(ipc_sockets[0]), 0);
948 
949 	pid = fork();
950 	ASSERT_GE(pid, 0);
951 	if (pid == 0)
952 		crashing_child();
953 
954 	pidfd = sys_pidfd_open(pid, 0);
955 	ASSERT_GE(pidfd, 0);
956 
957 	waitpid(pid, &status, 0);
958 	ASSERT_TRUE(WIFSIGNALED(status));
959 	ASSERT_TRUE(WCOREDUMP(status));
960 
961 	ASSERT_TRUE(get_pidfd_info(pidfd, &info));
962 	ASSERT_GT((info.mask & PIDFD_INFO_COREDUMP), 0);
963 	ASSERT_GT((info.coredump_mask & PIDFD_COREDUMPED), 0);
964 
965 	wait_and_check_coredump_server(pid_coredump_server, _metadata, self);
966 }
967 
968 TEST_F(coredump, socket_request_reject)
969 {
970 	int pidfd, ret, status;
971 	pid_t pid, pid_coredump_server;
972 	struct pidfd_info info = {};
973 	int ipc_sockets[2];
974 	char c;
975 
976 	ASSERT_TRUE(set_core_pattern("@@/tmp/coredump.socket"));
977 
978 	ret = socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
979 	ASSERT_EQ(ret, 0);
980 
981 	pid_coredump_server = fork();
982 	ASSERT_GE(pid_coredump_server, 0);
983 	if (pid_coredump_server == 0) {
984 		struct coredump_req req = {};
985 		int fd_server = -1, fd_coredump = -1, fd_peer_pidfd = -1;
986 		int exit_code = EXIT_FAILURE;
987 
988 		close(ipc_sockets[0]);
989 
990 		fd_server = create_and_listen_unix_socket("/tmp/coredump.socket");
991 		if (fd_server < 0)
992 			goto out;
993 
994 		if (write_nointr(ipc_sockets[1], "1", 1) < 0)
995 			goto out;
996 
997 		close(ipc_sockets[1]);
998 
999 		fd_coredump = accept4(fd_server, NULL, NULL, SOCK_CLOEXEC);
1000 		if (fd_coredump < 0)
1001 			goto out;
1002 
1003 		fd_peer_pidfd = get_peer_pidfd(fd_coredump);
1004 		if (fd_peer_pidfd < 0)
1005 			goto out;
1006 
1007 		if (!get_pidfd_info(fd_peer_pidfd, &info))
1008 			goto out;
1009 
1010 		if (!(info.mask & PIDFD_INFO_COREDUMP))
1011 			goto out;
1012 
1013 		if (!(info.coredump_mask & PIDFD_COREDUMPED))
1014 			goto out;
1015 
1016 		if (!read_coredump_req(fd_coredump, &req))
1017 			goto out;
1018 
1019 		if (!check_coredump_req(&req, COREDUMP_ACK_SIZE_VER0,
1020 					COREDUMP_KERNEL | COREDUMP_USERSPACE |
1021 					COREDUMP_REJECT | COREDUMP_WAIT))
1022 			goto out;
1023 
1024 		if (!send_coredump_ack(fd_coredump, &req,
1025 				       COREDUMP_REJECT | COREDUMP_WAIT, 0))
1026 			goto out;
1027 
1028 		if (!read_marker(fd_coredump, COREDUMP_MARK_REQACK))
1029 			goto out;
1030 
1031 		for (;;) {
1032 			char buffer[4096];
1033 			ssize_t bytes_read;
1034 
1035 			bytes_read = read(fd_coredump, buffer, sizeof(buffer));
1036 			if (bytes_read > 0)
1037 				goto out;
1038 
1039 			if (bytes_read < 0)
1040 				goto out;
1041 
1042 			if (bytes_read == 0)
1043 				break;
1044 		}
1045 
1046 		exit_code = EXIT_SUCCESS;
1047 out:
1048 		if (fd_peer_pidfd >= 0)
1049 			close(fd_peer_pidfd);
1050 		if (fd_coredump >= 0)
1051 			close(fd_coredump);
1052 		if (fd_server >= 0)
1053 			close(fd_server);
1054 		_exit(exit_code);
1055 	}
1056 	self->pid_coredump_server = pid_coredump_server;
1057 
1058 	EXPECT_EQ(close(ipc_sockets[1]), 0);
1059 	ASSERT_EQ(read_nointr(ipc_sockets[0], &c, 1), 1);
1060 	EXPECT_EQ(close(ipc_sockets[0]), 0);
1061 
1062 	pid = fork();
1063 	ASSERT_GE(pid, 0);
1064 	if (pid == 0)
1065 		crashing_child();
1066 
1067 	pidfd = sys_pidfd_open(pid, 0);
1068 	ASSERT_GE(pidfd, 0);
1069 
1070 	waitpid(pid, &status, 0);
1071 	ASSERT_TRUE(WIFSIGNALED(status));
1072 	ASSERT_FALSE(WCOREDUMP(status));
1073 
1074 	ASSERT_TRUE(get_pidfd_info(pidfd, &info));
1075 	ASSERT_GT((info.mask & PIDFD_INFO_COREDUMP), 0);
1076 	ASSERT_GT((info.coredump_mask & PIDFD_COREDUMPED), 0);
1077 
1078 	wait_and_check_coredump_server(pid_coredump_server, _metadata, self);
1079 }
1080 
1081 TEST_F(coredump, socket_request_invalid_flag_combination)
1082 {
1083 	int pidfd, ret, status;
1084 	pid_t pid, pid_coredump_server;
1085 	struct pidfd_info info = {};
1086 	int ipc_sockets[2];
1087 	char c;
1088 
1089 	ASSERT_TRUE(set_core_pattern("@@/tmp/coredump.socket"));
1090 
1091 	ret = socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
1092 	ASSERT_EQ(ret, 0);
1093 
1094 	pid_coredump_server = fork();
1095 	ASSERT_GE(pid_coredump_server, 0);
1096 	if (pid_coredump_server == 0) {
1097 		struct coredump_req req = {};
1098 		int fd_server = -1, fd_coredump = -1, fd_peer_pidfd = -1;
1099 		int exit_code = EXIT_FAILURE;
1100 
1101 		close(ipc_sockets[0]);
1102 
1103 		fd_server = create_and_listen_unix_socket("/tmp/coredump.socket");
1104 		if (fd_server < 0)
1105 			goto out;
1106 
1107 		if (write_nointr(ipc_sockets[1], "1", 1) < 0)
1108 			goto out;
1109 
1110 		close(ipc_sockets[1]);
1111 
1112 		fd_coredump = accept4(fd_server, NULL, NULL, SOCK_CLOEXEC);
1113 		if (fd_coredump < 0)
1114 			goto out;
1115 
1116 		fd_peer_pidfd = get_peer_pidfd(fd_coredump);
1117 		if (fd_peer_pidfd < 0)
1118 			goto out;
1119 
1120 		if (!get_pidfd_info(fd_peer_pidfd, &info))
1121 			goto out;
1122 
1123 		if (!(info.mask & PIDFD_INFO_COREDUMP))
1124 			goto out;
1125 
1126 		if (!(info.coredump_mask & PIDFD_COREDUMPED))
1127 			goto out;
1128 
1129 		if (!read_coredump_req(fd_coredump, &req))
1130 			goto out;
1131 
1132 		if (!check_coredump_req(&req, COREDUMP_ACK_SIZE_VER0,
1133 					COREDUMP_KERNEL | COREDUMP_USERSPACE |
1134 					COREDUMP_REJECT | COREDUMP_WAIT))
1135 			goto out;
1136 
1137 		if (!send_coredump_ack(fd_coredump, &req,
1138 				       COREDUMP_KERNEL | COREDUMP_REJECT | COREDUMP_WAIT, 0))
1139 			goto out;
1140 
1141 		if (!read_marker(fd_coredump, COREDUMP_MARK_CONFLICTING))
1142 			goto out;
1143 
1144 		exit_code = EXIT_SUCCESS;
1145 out:
1146 		if (fd_peer_pidfd >= 0)
1147 			close(fd_peer_pidfd);
1148 		if (fd_coredump >= 0)
1149 			close(fd_coredump);
1150 		if (fd_server >= 0)
1151 			close(fd_server);
1152 		_exit(exit_code);
1153 	}
1154 	self->pid_coredump_server = pid_coredump_server;
1155 
1156 	EXPECT_EQ(close(ipc_sockets[1]), 0);
1157 	ASSERT_EQ(read_nointr(ipc_sockets[0], &c, 1), 1);
1158 	EXPECT_EQ(close(ipc_sockets[0]), 0);
1159 
1160 	pid = fork();
1161 	ASSERT_GE(pid, 0);
1162 	if (pid == 0)
1163 		crashing_child();
1164 
1165 	pidfd = sys_pidfd_open(pid, 0);
1166 	ASSERT_GE(pidfd, 0);
1167 
1168 	waitpid(pid, &status, 0);
1169 	ASSERT_TRUE(WIFSIGNALED(status));
1170 	ASSERT_FALSE(WCOREDUMP(status));
1171 
1172 	ASSERT_TRUE(get_pidfd_info(pidfd, &info));
1173 	ASSERT_GT((info.mask & PIDFD_INFO_COREDUMP), 0);
1174 	ASSERT_GT((info.coredump_mask & PIDFD_COREDUMPED), 0);
1175 
1176 	wait_and_check_coredump_server(pid_coredump_server, _metadata, self);
1177 }
1178 
1179 TEST_F(coredump, socket_request_unknown_flag)
1180 {
1181 	int pidfd, ret, status;
1182 	pid_t pid, pid_coredump_server;
1183 	struct pidfd_info info = {};
1184 	int ipc_sockets[2];
1185 	char c;
1186 
1187 	ASSERT_TRUE(set_core_pattern("@@/tmp/coredump.socket"));
1188 
1189 	ret = socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
1190 	ASSERT_EQ(ret, 0);
1191 
1192 	pid_coredump_server = fork();
1193 	ASSERT_GE(pid_coredump_server, 0);
1194 	if (pid_coredump_server == 0) {
1195 		struct coredump_req req = {};
1196 		int fd_server = -1, fd_coredump = -1, fd_peer_pidfd = -1;
1197 		int exit_code = EXIT_FAILURE;
1198 
1199 		close(ipc_sockets[0]);
1200 
1201 		fd_server = create_and_listen_unix_socket("/tmp/coredump.socket");
1202 		if (fd_server < 0)
1203 			goto out;
1204 
1205 		if (write_nointr(ipc_sockets[1], "1", 1) < 0)
1206 			goto out;
1207 
1208 		close(ipc_sockets[1]);
1209 
1210 		fd_coredump = accept4(fd_server, NULL, NULL, SOCK_CLOEXEC);
1211 		if (fd_coredump < 0)
1212 			goto out;
1213 
1214 		fd_peer_pidfd = get_peer_pidfd(fd_coredump);
1215 		if (fd_peer_pidfd < 0)
1216 			goto out;
1217 
1218 		if (!get_pidfd_info(fd_peer_pidfd, &info))
1219 			goto out;
1220 
1221 		if (!(info.mask & PIDFD_INFO_COREDUMP))
1222 			goto out;
1223 
1224 		if (!(info.coredump_mask & PIDFD_COREDUMPED))
1225 			goto out;
1226 
1227 		if (!read_coredump_req(fd_coredump, &req))
1228 			goto out;
1229 
1230 		if (!check_coredump_req(&req, COREDUMP_ACK_SIZE_VER0,
1231 					COREDUMP_KERNEL | COREDUMP_USERSPACE |
1232 					COREDUMP_REJECT | COREDUMP_WAIT))
1233 			goto out;
1234 
1235 		if (!send_coredump_ack(fd_coredump, &req, (1ULL << 63), 0))
1236 			goto out;
1237 
1238 		if (!read_marker(fd_coredump, COREDUMP_MARK_UNSUPPORTED))
1239 			goto out;
1240 
1241 		exit_code = EXIT_SUCCESS;
1242 out:
1243 		if (fd_peer_pidfd >= 0)
1244 			close(fd_peer_pidfd);
1245 		if (fd_coredump >= 0)
1246 			close(fd_coredump);
1247 		if (fd_server >= 0)
1248 			close(fd_server);
1249 		_exit(exit_code);
1250 	}
1251 	self->pid_coredump_server = pid_coredump_server;
1252 
1253 	EXPECT_EQ(close(ipc_sockets[1]), 0);
1254 	ASSERT_EQ(read_nointr(ipc_sockets[0], &c, 1), 1);
1255 	EXPECT_EQ(close(ipc_sockets[0]), 0);
1256 
1257 	pid = fork();
1258 	ASSERT_GE(pid, 0);
1259 	if (pid == 0)
1260 		crashing_child();
1261 
1262 	pidfd = sys_pidfd_open(pid, 0);
1263 	ASSERT_GE(pidfd, 0);
1264 
1265 	waitpid(pid, &status, 0);
1266 	ASSERT_TRUE(WIFSIGNALED(status));
1267 	ASSERT_FALSE(WCOREDUMP(status));
1268 
1269 	ASSERT_TRUE(get_pidfd_info(pidfd, &info));
1270 	ASSERT_GT((info.mask & PIDFD_INFO_COREDUMP), 0);
1271 	ASSERT_GT((info.coredump_mask & PIDFD_COREDUMPED), 0);
1272 
1273 	wait_and_check_coredump_server(pid_coredump_server, _metadata, self);
1274 }
1275 
1276 TEST_F(coredump, socket_request_invalid_size_small)
1277 {
1278 	int pidfd, ret, status;
1279 	pid_t pid, pid_coredump_server;
1280 	struct pidfd_info info = {};
1281 	int ipc_sockets[2];
1282 	char c;
1283 
1284 	ASSERT_TRUE(set_core_pattern("@@/tmp/coredump.socket"));
1285 
1286 	ret = socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
1287 	ASSERT_EQ(ret, 0);
1288 
1289 	pid_coredump_server = fork();
1290 	ASSERT_GE(pid_coredump_server, 0);
1291 	if (pid_coredump_server == 0) {
1292 		struct coredump_req req = {};
1293 		int fd_server = -1, fd_coredump = -1, fd_peer_pidfd = -1;
1294 		int exit_code = EXIT_FAILURE;
1295 
1296 		close(ipc_sockets[0]);
1297 
1298 		fd_server = create_and_listen_unix_socket("/tmp/coredump.socket");
1299 		if (fd_server < 0)
1300 			goto out;
1301 
1302 		if (write_nointr(ipc_sockets[1], "1", 1) < 0)
1303 			goto out;
1304 
1305 		close(ipc_sockets[1]);
1306 
1307 		fd_coredump = accept4(fd_server, NULL, NULL, SOCK_CLOEXEC);
1308 		if (fd_coredump < 0)
1309 			goto out;
1310 
1311 		fd_peer_pidfd = get_peer_pidfd(fd_coredump);
1312 		if (fd_peer_pidfd < 0)
1313 			goto out;
1314 
1315 		if (!get_pidfd_info(fd_peer_pidfd, &info))
1316 			goto out;
1317 
1318 		if (!(info.mask & PIDFD_INFO_COREDUMP))
1319 			goto out;
1320 
1321 		if (!(info.coredump_mask & PIDFD_COREDUMPED))
1322 			goto out;
1323 
1324 		if (!read_coredump_req(fd_coredump, &req))
1325 			goto out;
1326 
1327 		if (!check_coredump_req(&req, COREDUMP_ACK_SIZE_VER0,
1328 					COREDUMP_KERNEL | COREDUMP_USERSPACE |
1329 					COREDUMP_REJECT | COREDUMP_WAIT))
1330 			goto out;
1331 
1332 		if (!send_coredump_ack(fd_coredump, &req,
1333 				       COREDUMP_REJECT | COREDUMP_WAIT,
1334 				       COREDUMP_ACK_SIZE_VER0 / 2))
1335 			goto out;
1336 
1337 		if (!read_marker(fd_coredump, COREDUMP_MARK_MINSIZE))
1338 			goto out;
1339 
1340 		exit_code = EXIT_SUCCESS;
1341 out:
1342 		if (fd_peer_pidfd >= 0)
1343 			close(fd_peer_pidfd);
1344 		if (fd_coredump >= 0)
1345 			close(fd_coredump);
1346 		if (fd_server >= 0)
1347 			close(fd_server);
1348 		_exit(exit_code);
1349 	}
1350 	self->pid_coredump_server = pid_coredump_server;
1351 
1352 	EXPECT_EQ(close(ipc_sockets[1]), 0);
1353 	ASSERT_EQ(read_nointr(ipc_sockets[0], &c, 1), 1);
1354 	EXPECT_EQ(close(ipc_sockets[0]), 0);
1355 
1356 	pid = fork();
1357 	ASSERT_GE(pid, 0);
1358 	if (pid == 0)
1359 		crashing_child();
1360 
1361 	pidfd = sys_pidfd_open(pid, 0);
1362 	ASSERT_GE(pidfd, 0);
1363 
1364 	waitpid(pid, &status, 0);
1365 	ASSERT_TRUE(WIFSIGNALED(status));
1366 	ASSERT_FALSE(WCOREDUMP(status));
1367 
1368 	ASSERT_TRUE(get_pidfd_info(pidfd, &info));
1369 	ASSERT_GT((info.mask & PIDFD_INFO_COREDUMP), 0);
1370 	ASSERT_GT((info.coredump_mask & PIDFD_COREDUMPED), 0);
1371 
1372 	wait_and_check_coredump_server(pid_coredump_server, _metadata, self);
1373 }
1374 
1375 TEST_F(coredump, socket_request_invalid_size_large)
1376 {
1377 	int pidfd, ret, status;
1378 	pid_t pid, pid_coredump_server;
1379 	struct pidfd_info info = {};
1380 	int ipc_sockets[2];
1381 	char c;
1382 
1383 	ASSERT_TRUE(set_core_pattern("@@/tmp/coredump.socket"));
1384 
1385 	ret = socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
1386 	ASSERT_EQ(ret, 0);
1387 
1388 	pid_coredump_server = fork();
1389 	ASSERT_GE(pid_coredump_server, 0);
1390 	if (pid_coredump_server == 0) {
1391 		struct coredump_req req = {};
1392 		int fd_server = -1, fd_coredump = -1, fd_peer_pidfd = -1;
1393 		int exit_code = EXIT_FAILURE;
1394 
1395 		close(ipc_sockets[0]);
1396 
1397 		fd_server = create_and_listen_unix_socket("/tmp/coredump.socket");
1398 		if (fd_server < 0)
1399 			goto out;
1400 
1401 		if (write_nointr(ipc_sockets[1], "1", 1) < 0)
1402 			goto out;
1403 
1404 		close(ipc_sockets[1]);
1405 
1406 		fd_coredump = accept4(fd_server, NULL, NULL, SOCK_CLOEXEC);
1407 		if (fd_coredump < 0)
1408 			goto out;
1409 
1410 		fd_peer_pidfd = get_peer_pidfd(fd_coredump);
1411 		if (fd_peer_pidfd < 0)
1412 			goto out;
1413 
1414 		if (!get_pidfd_info(fd_peer_pidfd, &info))
1415 			goto out;
1416 
1417 		if (!(info.mask & PIDFD_INFO_COREDUMP))
1418 			goto out;
1419 
1420 		if (!(info.coredump_mask & PIDFD_COREDUMPED))
1421 			goto out;
1422 
1423 		if (!read_coredump_req(fd_coredump, &req))
1424 			goto out;
1425 
1426 		if (!check_coredump_req(&req, COREDUMP_ACK_SIZE_VER0,
1427 					COREDUMP_KERNEL | COREDUMP_USERSPACE |
1428 					COREDUMP_REJECT | COREDUMP_WAIT))
1429 			goto out;
1430 
1431 		if (!send_coredump_ack(fd_coredump, &req,
1432 				       COREDUMP_REJECT | COREDUMP_WAIT,
1433 				       COREDUMP_ACK_SIZE_VER0 + PAGE_SIZE))
1434 			goto out;
1435 
1436 		if (!read_marker(fd_coredump, COREDUMP_MARK_MAXSIZE))
1437 			goto out;
1438 
1439 		exit_code = EXIT_SUCCESS;
1440 out:
1441 		if (fd_peer_pidfd >= 0)
1442 			close(fd_peer_pidfd);
1443 		if (fd_coredump >= 0)
1444 			close(fd_coredump);
1445 		if (fd_server >= 0)
1446 			close(fd_server);
1447 		_exit(exit_code);
1448 	}
1449 	self->pid_coredump_server = pid_coredump_server;
1450 
1451 	EXPECT_EQ(close(ipc_sockets[1]), 0);
1452 	ASSERT_EQ(read_nointr(ipc_sockets[0], &c, 1), 1);
1453 	EXPECT_EQ(close(ipc_sockets[0]), 0);
1454 
1455 	pid = fork();
1456 	ASSERT_GE(pid, 0);
1457 	if (pid == 0)
1458 		crashing_child();
1459 
1460 	pidfd = sys_pidfd_open(pid, 0);
1461 	ASSERT_GE(pidfd, 0);
1462 
1463 	waitpid(pid, &status, 0);
1464 	ASSERT_TRUE(WIFSIGNALED(status));
1465 	ASSERT_FALSE(WCOREDUMP(status));
1466 
1467 	ASSERT_TRUE(get_pidfd_info(pidfd, &info));
1468 	ASSERT_GT((info.mask & PIDFD_INFO_COREDUMP), 0);
1469 	ASSERT_GT((info.coredump_mask & PIDFD_COREDUMPED), 0);
1470 
1471 	wait_and_check_coredump_server(pid_coredump_server, _metadata, self);
1472 }
1473 
1474 static int open_coredump_tmpfile(int fd_tmpfs_detached)
1475 {
1476 	return openat(fd_tmpfs_detached, ".", O_TMPFILE | O_RDWR | O_EXCL, 0600);
1477 }
1478 
1479 #define NUM_CRASHING_COREDUMPS 5
1480 
1481 TEST_F_TIMEOUT(coredump, socket_multiple_crashing_coredumps, 500)
1482 {
1483 	int pidfd[NUM_CRASHING_COREDUMPS], status[NUM_CRASHING_COREDUMPS];
1484 	pid_t pid[NUM_CRASHING_COREDUMPS], pid_coredump_server;
1485 	struct pidfd_info info = {};
1486 	int ipc_sockets[2];
1487 	char c;
1488 
1489 	ASSERT_TRUE(set_core_pattern("@@/tmp/coredump.socket"));
1490 
1491 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets), 0);
1492 
1493 	pid_coredump_server = fork();
1494 	ASSERT_GE(pid_coredump_server, 0);
1495 	if (pid_coredump_server == 0) {
1496 		int fd_server = -1, fd_coredump = -1, fd_peer_pidfd = -1, fd_core_file = -1;
1497 		int exit_code = EXIT_FAILURE;
1498 		struct coredump_req req = {};
1499 
1500 		close(ipc_sockets[0]);
1501 		fd_server = create_and_listen_unix_socket("/tmp/coredump.socket");
1502 		if (fd_server < 0) {
1503 			fprintf(stderr, "Failed to create and listen on unix socket\n");
1504 			goto out;
1505 		}
1506 
1507 		if (write_nointr(ipc_sockets[1], "1", 1) < 0) {
1508 			fprintf(stderr, "Failed to notify parent via ipc socket\n");
1509 			goto out;
1510 		}
1511 		close(ipc_sockets[1]);
1512 
1513 		for (int i = 0; i < NUM_CRASHING_COREDUMPS; i++) {
1514 			fd_coredump = accept4(fd_server, NULL, NULL, SOCK_CLOEXEC);
1515 			if (fd_coredump < 0) {
1516 				fprintf(stderr, "accept4 failed: %m\n");
1517 				goto out;
1518 			}
1519 
1520 			fd_peer_pidfd = get_peer_pidfd(fd_coredump);
1521 			if (fd_peer_pidfd < 0) {
1522 				fprintf(stderr, "get_peer_pidfd failed for fd %d: %m\n", fd_coredump);
1523 				goto out;
1524 			}
1525 
1526 			if (!get_pidfd_info(fd_peer_pidfd, &info)) {
1527 				fprintf(stderr, "get_pidfd_info failed for fd %d\n", fd_peer_pidfd);
1528 				goto out;
1529 			}
1530 
1531 			if (!(info.mask & PIDFD_INFO_COREDUMP)) {
1532 				fprintf(stderr, "pidfd info missing PIDFD_INFO_COREDUMP for fd %d\n", fd_peer_pidfd);
1533 				goto out;
1534 			}
1535 			if (!(info.coredump_mask & PIDFD_COREDUMPED)) {
1536 				fprintf(stderr, "pidfd info missing PIDFD_COREDUMPED for fd %d\n", fd_peer_pidfd);
1537 				goto out;
1538 			}
1539 
1540 			if (!read_coredump_req(fd_coredump, &req)) {
1541 				fprintf(stderr, "read_coredump_req failed for fd %d\n", fd_coredump);
1542 				goto out;
1543 			}
1544 
1545 			if (!check_coredump_req(&req, COREDUMP_ACK_SIZE_VER0,
1546 						COREDUMP_KERNEL | COREDUMP_USERSPACE |
1547 						COREDUMP_REJECT | COREDUMP_WAIT)) {
1548 				fprintf(stderr, "check_coredump_req failed for fd %d\n", fd_coredump);
1549 				goto out;
1550 			}
1551 
1552 			if (!send_coredump_ack(fd_coredump, &req,
1553 					       COREDUMP_KERNEL | COREDUMP_WAIT, 0)) {
1554 				fprintf(stderr, "send_coredump_ack failed for fd %d\n", fd_coredump);
1555 				goto out;
1556 			}
1557 
1558 			if (!read_marker(fd_coredump, COREDUMP_MARK_REQACK)) {
1559 				fprintf(stderr, "read_marker failed for fd %d\n", fd_coredump);
1560 				goto out;
1561 			}
1562 
1563 			fd_core_file = open_coredump_tmpfile(self->fd_tmpfs_detached);
1564 			if (fd_core_file < 0) {
1565 				fprintf(stderr, "%m - open_coredump_tmpfile failed for fd %d\n", fd_coredump);
1566 				goto out;
1567 			}
1568 
1569 			for (;;) {
1570 				char buffer[4096];
1571 				ssize_t bytes_read, bytes_write;
1572 
1573 				bytes_read = read(fd_coredump, buffer, sizeof(buffer));
1574 				if (bytes_read < 0) {
1575 					fprintf(stderr, "read failed for fd %d: %m\n", fd_coredump);
1576 					goto out;
1577 				}
1578 
1579 				if (bytes_read == 0)
1580 					break;
1581 
1582 				bytes_write = write(fd_core_file, buffer, bytes_read);
1583 				if (bytes_read != bytes_write) {
1584 					fprintf(stderr, "write failed for fd %d: %m\n", fd_core_file);
1585 					goto out;
1586 				}
1587 			}
1588 
1589 			close(fd_core_file);
1590 			close(fd_peer_pidfd);
1591 			close(fd_coredump);
1592 			fd_peer_pidfd = -1;
1593 			fd_coredump = -1;
1594 		}
1595 
1596 		exit_code = EXIT_SUCCESS;
1597 out:
1598 		if (fd_core_file >= 0)
1599 			close(fd_core_file);
1600 		if (fd_peer_pidfd >= 0)
1601 			close(fd_peer_pidfd);
1602 		if (fd_coredump >= 0)
1603 			close(fd_coredump);
1604 		if (fd_server >= 0)
1605 			close(fd_server);
1606 		_exit(exit_code);
1607 	}
1608 	self->pid_coredump_server = pid_coredump_server;
1609 
1610 	EXPECT_EQ(close(ipc_sockets[1]), 0);
1611 	ASSERT_EQ(read_nointr(ipc_sockets[0], &c, 1), 1);
1612 	EXPECT_EQ(close(ipc_sockets[0]), 0);
1613 
1614 	for (int i = 0; i < NUM_CRASHING_COREDUMPS; i++) {
1615 		pid[i] = fork();
1616 		ASSERT_GE(pid[i], 0);
1617 		if (pid[i] == 0)
1618 			crashing_child();
1619 		pidfd[i] = sys_pidfd_open(pid[i], 0);
1620 		ASSERT_GE(pidfd[i], 0);
1621 	}
1622 
1623 	for (int i = 0; i < NUM_CRASHING_COREDUMPS; i++) {
1624 		waitpid(pid[i], &status[i], 0);
1625 		ASSERT_TRUE(WIFSIGNALED(status[i]));
1626 		ASSERT_TRUE(WCOREDUMP(status[i]));
1627 	}
1628 
1629 	for (int i = 0; i < NUM_CRASHING_COREDUMPS; i++) {
1630 		info.mask = PIDFD_INFO_EXIT | PIDFD_INFO_COREDUMP;
1631 		ASSERT_EQ(ioctl(pidfd[i], PIDFD_GET_INFO, &info), 0);
1632 		ASSERT_GT((info.mask & PIDFD_INFO_COREDUMP), 0);
1633 		ASSERT_GT((info.coredump_mask & PIDFD_COREDUMPED), 0);
1634 	}
1635 
1636 	wait_and_check_coredump_server(pid_coredump_server, _metadata, self);
1637 }
1638 
1639 #define MAX_EVENTS 128
1640 
1641 static void process_coredump_worker(int fd_coredump, int fd_peer_pidfd, int fd_core_file)
1642 {
1643 	int epfd = -1;
1644 	int exit_code = EXIT_FAILURE;
1645 
1646 	epfd = epoll_create1(0);
1647 	if (epfd < 0)
1648 		goto out;
1649 
1650 	struct epoll_event ev;
1651 	ev.events = EPOLLIN | EPOLLRDHUP | EPOLLET;
1652 	ev.data.fd = fd_coredump;
1653 	if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd_coredump, &ev) < 0)
1654 		goto out;
1655 
1656 	for (;;) {
1657 		struct epoll_event events[1];
1658 		int n = epoll_wait(epfd, events, 1, -1);
1659 		if (n < 0)
1660 			break;
1661 
1662 		if (events[0].events & (EPOLLIN | EPOLLRDHUP)) {
1663 			for (;;) {
1664 				char buffer[4096];
1665 				ssize_t bytes_read = read(fd_coredump, buffer, sizeof(buffer));
1666 				if (bytes_read < 0) {
1667 					if (errno == EAGAIN || errno == EWOULDBLOCK)
1668 						break;
1669 					goto out;
1670 				}
1671 				if (bytes_read == 0)
1672 					goto done;
1673 				ssize_t bytes_write = write(fd_core_file, buffer, bytes_read);
1674 				if (bytes_write != bytes_read)
1675 					goto out;
1676 			}
1677 		}
1678 	}
1679 
1680 done:
1681 	exit_code = EXIT_SUCCESS;
1682 out:
1683 	if (epfd >= 0)
1684 		close(epfd);
1685 	if (fd_core_file >= 0)
1686 		close(fd_core_file);
1687 	if (fd_peer_pidfd >= 0)
1688 		close(fd_peer_pidfd);
1689 	if (fd_coredump >= 0)
1690 		close(fd_coredump);
1691 	_exit(exit_code);
1692 }
1693 
1694 TEST_F_TIMEOUT(coredump, socket_multiple_crashing_coredumps_epoll_workers, 500)
1695 {
1696 	int pidfd[NUM_CRASHING_COREDUMPS], status[NUM_CRASHING_COREDUMPS];
1697 	pid_t pid[NUM_CRASHING_COREDUMPS], pid_coredump_server, worker_pids[NUM_CRASHING_COREDUMPS];
1698 	struct pidfd_info info = {};
1699 	int ipc_sockets[2];
1700 	char c;
1701 
1702 	ASSERT_TRUE(set_core_pattern("@@/tmp/coredump.socket"));
1703 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets), 0);
1704 
1705 	pid_coredump_server = fork();
1706 	ASSERT_GE(pid_coredump_server, 0);
1707 	if (pid_coredump_server == 0) {
1708 		int fd_server = -1, exit_code = EXIT_FAILURE, n_conns = 0;
1709 		fd_server = -1;
1710 		exit_code = EXIT_FAILURE;
1711 		n_conns = 0;
1712 		close(ipc_sockets[0]);
1713 		fd_server = create_and_listen_unix_socket("/tmp/coredump.socket");
1714 		if (fd_server < 0)
1715 			goto out;
1716 
1717 		if (write_nointr(ipc_sockets[1], "1", 1) < 0)
1718 			goto out;
1719 		close(ipc_sockets[1]);
1720 
1721 		while (n_conns < NUM_CRASHING_COREDUMPS) {
1722 			int fd_coredump = -1, fd_peer_pidfd = -1, fd_core_file = -1;
1723 			struct coredump_req req = {};
1724 			fd_coredump = accept4(fd_server, NULL, NULL, SOCK_CLOEXEC);
1725 			if (fd_coredump < 0) {
1726 				if (errno == EAGAIN || errno == EWOULDBLOCK)
1727 					continue;
1728 				goto out;
1729 			}
1730 			fd_peer_pidfd = get_peer_pidfd(fd_coredump);
1731 			if (fd_peer_pidfd < 0)
1732 				goto out;
1733 			if (!get_pidfd_info(fd_peer_pidfd, &info))
1734 				goto out;
1735 			if (!(info.mask & PIDFD_INFO_COREDUMP) || !(info.coredump_mask & PIDFD_COREDUMPED))
1736 				goto out;
1737 			if (!read_coredump_req(fd_coredump, &req))
1738 				goto out;
1739 			if (!check_coredump_req(&req, COREDUMP_ACK_SIZE_VER0,
1740 						COREDUMP_KERNEL | COREDUMP_USERSPACE |
1741 						COREDUMP_REJECT | COREDUMP_WAIT))
1742 				goto out;
1743 			if (!send_coredump_ack(fd_coredump, &req, COREDUMP_KERNEL | COREDUMP_WAIT, 0))
1744 				goto out;
1745 			if (!read_marker(fd_coredump, COREDUMP_MARK_REQACK))
1746 				goto out;
1747 			fd_core_file = open_coredump_tmpfile(self->fd_tmpfs_detached);
1748 			if (fd_core_file < 0)
1749 				goto out;
1750 			pid_t worker = fork();
1751 			if (worker == 0) {
1752 				close(fd_server);
1753 				process_coredump_worker(fd_coredump, fd_peer_pidfd, fd_core_file);
1754 			}
1755 			worker_pids[n_conns] = worker;
1756 			if (fd_coredump >= 0)
1757 				close(fd_coredump);
1758 			if (fd_peer_pidfd >= 0)
1759 				close(fd_peer_pidfd);
1760 			if (fd_core_file >= 0)
1761 				close(fd_core_file);
1762 			n_conns++;
1763 		}
1764 		exit_code = EXIT_SUCCESS;
1765 out:
1766 		if (fd_server >= 0)
1767 			close(fd_server);
1768 
1769 		// Reap all worker processes
1770 		for (int i = 0; i < n_conns; i++) {
1771 			int wstatus;
1772 			if (waitpid(worker_pids[i], &wstatus, 0) < 0) {
1773 				fprintf(stderr, "Failed to wait for worker %d: %m\n", worker_pids[i]);
1774 			} else if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) != EXIT_SUCCESS) {
1775 				fprintf(stderr, "Worker %d exited with error code %d\n", worker_pids[i], WEXITSTATUS(wstatus));
1776 				exit_code = EXIT_FAILURE;
1777 			}
1778 		}
1779 
1780 		_exit(exit_code);
1781 	}
1782 	self->pid_coredump_server = pid_coredump_server;
1783 
1784 	EXPECT_EQ(close(ipc_sockets[1]), 0);
1785 	ASSERT_EQ(read_nointr(ipc_sockets[0], &c, 1), 1);
1786 	EXPECT_EQ(close(ipc_sockets[0]), 0);
1787 
1788 	for (int i = 0; i < NUM_CRASHING_COREDUMPS; i++) {
1789 		pid[i] = fork();
1790 		ASSERT_GE(pid[i], 0);
1791 		if (pid[i] == 0)
1792 			crashing_child();
1793 		pidfd[i] = sys_pidfd_open(pid[i], 0);
1794 		ASSERT_GE(pidfd[i], 0);
1795 	}
1796 
1797 	for (int i = 0; i < NUM_CRASHING_COREDUMPS; i++) {
1798 		ASSERT_GE(waitpid(pid[i], &status[i], 0), 0);
1799 		ASSERT_TRUE(WIFSIGNALED(status[i]));
1800 		ASSERT_TRUE(WCOREDUMP(status[i]));
1801 	}
1802 
1803 	for (int i = 0; i < NUM_CRASHING_COREDUMPS; i++) {
1804 		info.mask = PIDFD_INFO_EXIT | PIDFD_INFO_COREDUMP;
1805 		ASSERT_EQ(ioctl(pidfd[i], PIDFD_GET_INFO, &info), 0);
1806 		ASSERT_GT((info.mask & PIDFD_INFO_COREDUMP), 0);
1807 		ASSERT_GT((info.coredump_mask & PIDFD_COREDUMPED), 0);
1808 	}
1809 
1810 	wait_and_check_coredump_server(pid_coredump_server, _metadata, self);
1811 }
1812 
1813 TEST_F(coredump, socket_invalid_paths)
1814 {
1815 	ASSERT_FALSE(set_core_pattern("@ /tmp/coredump.socket"));
1816 	ASSERT_FALSE(set_core_pattern("@/tmp/../coredump.socket"));
1817 	ASSERT_FALSE(set_core_pattern("@../coredump.socket"));
1818 	ASSERT_FALSE(set_core_pattern("@/tmp/coredump.socket/.."));
1819 	ASSERT_FALSE(set_core_pattern("@.."));
1820 
1821 	ASSERT_FALSE(set_core_pattern("@@ /tmp/coredump.socket"));
1822 	ASSERT_FALSE(set_core_pattern("@@/tmp/../coredump.socket"));
1823 	ASSERT_FALSE(set_core_pattern("@@../coredump.socket"));
1824 	ASSERT_FALSE(set_core_pattern("@@/tmp/coredump.socket/.."));
1825 	ASSERT_FALSE(set_core_pattern("@@.."));
1826 
1827 	ASSERT_FALSE(set_core_pattern("@@@/tmp/coredump.socket"));
1828 }
1829 
1830 TEST_HARNESS_MAIN
1831