Home | History | Annotate | Download | only in getsockopt
      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 
     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 
     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 
     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 
     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