xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/getsockopt/getsockopt02.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2017 Red Hat, Inc.
4  */
5 
6 /*\
7  * [Description]
8  *
9  * Test getsockopt(2) for retrieving peer credentials (SO_PEERCRED).
10  */
11 
12 #define _GNU_SOURCE
13 
14 #include <errno.h>
15 #include <stdlib.h>
16 #include "tst_test.h"
17 
18 static int socket_fd, accepted;
19 static struct sockaddr_un sun;
20 
21 #define SOCKNAME	"testsocket"
22 
setup(void)23 static void setup(void)
24 {
25 	sun.sun_family = AF_UNIX;
26 	(void)strcpy(sun.sun_path, SOCKNAME);
27 	socket_fd = SAFE_SOCKET(sun.sun_family, SOCK_STREAM, 0);
28 	SAFE_BIND(socket_fd, (struct sockaddr *)&sun, sizeof(sun));
29 	SAFE_LISTEN(socket_fd, SOMAXCONN);
30 }
31 
fork_func(void)32 static void fork_func(void)
33 {
34 	int fork_socket_fd = SAFE_SOCKET(sun.sun_family, SOCK_STREAM, 0);
35 
36 	SAFE_CONNECT(fork_socket_fd, (struct sockaddr *)&sun, sizeof(sun));
37 	TST_CHECKPOINT_WAIT(0);
38 	SAFE_CLOSE(fork_socket_fd);
39 	exit(0);
40 }
41 
test_function(void)42 static void test_function(void)
43 {
44 	pid_t fork_id;
45 	struct ucred cred;
46 	socklen_t cred_len = sizeof(cred);
47 
48 	fork_id = SAFE_FORK();
49 	if (!fork_id)
50 		fork_func();
51 
52 	accepted = accept(socket_fd, NULL, NULL);
53 	if (accepted < 0) {
54 		tst_res(TFAIL | TERRNO, "Error with accepting connection");
55 		goto clean;
56 	}
57 
58 	if (getsockopt(accepted, SOL_SOCKET,
59 				SO_PEERCRED, &cred, &cred_len) < 0) {
60 		tst_res(TFAIL | TERRNO, "Error while getting socket option");
61 		goto clean;
62 	}
63 
64 	if (fork_id != cred.pid)
65 		tst_res(TFAIL, "Received wrong PID %d, expected %d",
66 				cred.pid, getpid());
67 	else
68 		tst_res(TPASS, "Test passed");
69 clean:
70 	if (accepted >= 0)
71 		SAFE_CLOSE(accepted);
72 
73 	TST_CHECKPOINT_WAKE(0);
74 }
75 
cleanup(void)76 static void cleanup(void)
77 {
78 	if (accepted >= 0)
79 		SAFE_CLOSE(accepted);
80 
81 	if (socket_fd >= 0)
82 		SAFE_CLOSE(socket_fd);
83 }
84 
85 static struct tst_test test = {
86 	.test_all = test_function,
87 	.setup = setup,
88 	.cleanup = cleanup,
89 	.forks_child = 1,
90 	.needs_checkpoints = 1,
91 };
92