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