• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 Red Hat, Inc.
3  *
4  * This program is free software;  you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the Free
6  * Software Foundation; either version 2 of the License, or (at your option)
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 /*
19  * Test description: Test retrieving of peer credentials (SO_PEERCRED)
20  *
21  */
22 
23 #define _GNU_SOURCE
24 
25 #include <errno.h>
26 #include <stdlib.h>
27 #include "tst_test.h"
28 
29 static int socket_fd, accepted;
30 static struct sockaddr_un sun;
31 
32 #define SOCKNAME	"testsocket"
33 
setup(void)34 static void setup(void)
35 {
36 	sun.sun_family = AF_UNIX;
37 	(void)strcpy(sun.sun_path, SOCKNAME);
38 	socket_fd = SAFE_SOCKET(sun.sun_family, SOCK_STREAM, 0);
39 	SAFE_BIND(socket_fd, (struct sockaddr *)&sun, sizeof(sun));
40 	SAFE_LISTEN(socket_fd, SOMAXCONN);
41 }
42 
fork_func(void)43 static void fork_func(void)
44 {
45 	int fork_socket_fd = SAFE_SOCKET(sun.sun_family, SOCK_STREAM, 0);
46 
47 	SAFE_CONNECT(fork_socket_fd, (struct sockaddr *)&sun, sizeof(sun));
48 	TST_CHECKPOINT_WAIT(0);
49 	SAFE_CLOSE(fork_socket_fd);
50 	exit(0);
51 }
52 
test_function(void)53 static void test_function(void)
54 {
55 	pid_t fork_id;
56 	struct ucred cred;
57 	socklen_t cred_len = sizeof(cred);
58 
59 	fork_id = SAFE_FORK();
60 	if (!fork_id)
61 		fork_func();
62 
63 	accepted = accept(socket_fd, NULL, NULL);
64 	if (accepted < 0) {
65 		tst_res(TFAIL | TERRNO, "Error with accepting connection");
66 		goto clean;
67 	}
68 	if (getsockopt(accepted, SOL_SOCKET,
69 				SO_PEERCRED, &cred, &cred_len) < 0) {
70 		tst_res(TFAIL | TERRNO, "Error while getting socket option");
71 		goto clean;
72 	}
73 
74 	if (fork_id != cred.pid)
75 		tst_res(TFAIL, "Received wrong PID %d, expected %d",
76 				cred.pid, getpid());
77 	else
78 		tst_res(TPASS, "Test passed");
79 clean:
80 	if (accepted >= 0)
81 		SAFE_CLOSE(accepted);
82 	TST_CHECKPOINT_WAKE(0);
83 }
84 
cleanup(void)85 static void cleanup(void)
86 {
87 	if (accepted >= 0)
88 		SAFE_CLOSE(accepted);
89 	if (socket_fd >= 0)
90 		SAFE_CLOSE(socket_fd);
91 }
92 
93 static struct tst_test test = {
94 	.test_all = test_function,
95 	.setup = setup,
96 	.cleanup = cleanup,
97 	.forks_child = 1,
98 	.needs_checkpoints = 1,
99 };
100