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