/* * Copyright (C) 2017 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, see <http://www.gnu.org/licenses/>. */ /* * Test description: Test retrieving of peer credentials (SO_PEERCRED) * */ #define _GNU_SOURCE #include <errno.h> #include <stdlib.h> #include "tst_test.h" static int socket_fd, accepted; static struct sockaddr_un sun; #define SOCKNAME "testsocket" static void setup(void) { sun.sun_family = AF_UNIX; (void)strcpy(sun.sun_path, SOCKNAME); socket_fd = SAFE_SOCKET(sun.sun_family, SOCK_STREAM, 0); SAFE_BIND(socket_fd, (struct sockaddr *)&sun, sizeof(sun)); SAFE_LISTEN(socket_fd, SOMAXCONN); } static void fork_func(void) { int fork_socket_fd = SAFE_SOCKET(sun.sun_family, SOCK_STREAM, 0); SAFE_CONNECT(fork_socket_fd, (struct sockaddr *)&sun, sizeof(sun)); TST_CHECKPOINT_WAIT(0); SAFE_CLOSE(fork_socket_fd); exit(0); } static void test_function(void) { pid_t fork_id; struct ucred cred; socklen_t cred_len = sizeof(cred); fork_id = SAFE_FORK(); if (!fork_id) fork_func(); accepted = accept(socket_fd, NULL, NULL); if (accepted < 0) { tst_res(TFAIL | TERRNO, "Error with accepting connection"); goto clean; } if (getsockopt(accepted, SOL_SOCKET, SO_PEERCRED, &cred, &cred_len) < 0) { tst_res(TFAIL | TERRNO, "Error while getting socket option"); goto clean; } if (fork_id != cred.pid) tst_res(TFAIL, "Received wrong PID %d, expected %d", cred.pid, getpid()); else tst_res(TPASS, "Test passed"); clean: if (accepted >= 0) SAFE_CLOSE(accepted); TST_CHECKPOINT_WAKE(0); } static void cleanup(void) { if (accepted >= 0) SAFE_CLOSE(accepted); if (socket_fd >= 0) SAFE_CLOSE(socket_fd); } static struct tst_test test = { .test_all = test_function, .setup = setup, .cleanup = cleanup, .forks_child = 1, .needs_checkpoints = 1, };