Path: blob/main/tools/regression/sockets/unix_cmsg/t_sockcred.c
96317 views
/*-1* Copyright (c) 2005 Andrey Simonenko2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12*13* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND14* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE15* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE16* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE17* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL18* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS19* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)20* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT21* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY22* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF23* SUCH DAMAGE.24*/2526#include <sys/types.h>27#include <sys/socket.h>28#include <sys/un.h>29#include <inttypes.h>30#include <stdarg.h>31#include <stdbool.h>32#include <stdlib.h>3334#include "uc_common.h"35#include "t_generic.h"36#include "t_sockcred.h"3738static int39t_sockcred_client(int type, int fd)40{41struct msghdr msghdr;42struct iovec iov[1];43int rv;4445if (uc_sync_recv() < 0)46return (-2);4748rv = -2;4950uc_msghdr_init_client(&msghdr, iov, NULL, 0, 0, 0);5152if (uc_socket_connect(fd) < 0)53goto done;5455if (type == 2)56if (uc_sync_recv() < 0)57goto done;5859if (uc_message_sendn(fd, &msghdr) < 0)60goto done;6162rv = 0;63done:64return (rv);65}6667static int68t_sockcred_server(int type, int fd1)69{70struct msghdr msghdr;71struct iovec iov[1];72struct cmsghdr *cmsghdr;73void *cmsg_data;74size_t cmsg_size;75u_int i;76int fd2, rv, val;7778fd2 = -1;79rv = -2;8081cmsg_size = CMSG_SPACE(SOCKCREDSIZE(uc_cfg.proc_cred.gid_num));82cmsg_data = malloc(cmsg_size);83if (cmsg_data == NULL) {84uc_logmsg("malloc");85goto done;86}8788if (type == 1) {89uc_dbgmsg("setting LOCAL_CREDS");90val = 1;91if (setsockopt(fd1, 0, LOCAL_CREDS, &val, sizeof(val)) < 0) {92uc_logmsg("setsockopt(LOCAL_CREDS)");93goto done;94}95}9697if (uc_sync_send() < 0)98goto done;99100if (uc_cfg.sock_type == SOCK_STREAM) {101fd2 = uc_socket_accept(fd1);102if (fd2 < 0)103goto done;104} else105fd2 = fd1;106107if (type == 2) {108uc_dbgmsg("setting LOCAL_CREDS");109val = 1;110if (setsockopt(fd2, 0, LOCAL_CREDS, &val, sizeof(val)) < 0) {111uc_logmsg("setsockopt(LOCAL_CREDS)");112goto done;113}114if (uc_sync_send() < 0)115goto done;116}117118rv = -1;119for (i = 1; i <= uc_cfg.ipc_msg.msg_num; ++i) {120uc_dbgmsg("message #%u", i);121122uc_msghdr_init_server(&msghdr, iov, cmsg_data, cmsg_size);123if (uc_message_recv(fd2, &msghdr) < 0) {124rv = -2;125break;126}127128if (i > 1 && uc_cfg.sock_type == SOCK_STREAM) {129if (uc_check_msghdr(&msghdr, 0) < 0)130break;131} else {132if (uc_check_msghdr(&msghdr, sizeof(*cmsghdr)) < 0)133break;134135cmsghdr = CMSG_FIRSTHDR(&msghdr);136if (uc_check_scm_creds_sockcred(cmsghdr) < 0)137break;138}139}140if (i > uc_cfg.ipc_msg.msg_num)141rv = 0;142done:143free(cmsg_data);144if (uc_cfg.sock_type == SOCK_STREAM && fd2 >= 0)145if (uc_socket_close(fd2) < 0)146rv = -2;147return (rv);148}149150int151t_sockcred_1(void)152{153u_int i;154int fd, rv, rv_client;155156switch (uc_client_fork()) {157case 0:158for (i = 1; i <= 2; ++i) {159uc_dbgmsg("client #%u", i);160fd = uc_socket_create();161if (fd < 0)162rv = -2;163else {164rv = t_sockcred_client(1, fd);165if (uc_socket_close(fd) < 0)166rv = -2;167}168if (rv != 0)169break;170}171uc_client_exit(rv);172break;173case 1:174fd = uc_socket_create();175if (fd < 0)176rv = -2;177else {178rv = t_sockcred_server(1, fd);179if (rv == 0)180rv = t_sockcred_server(3, fd);181rv_client = uc_client_wait();182if (rv == 0 || (rv == -2 && rv_client != 0))183rv = rv_client;184if (uc_socket_close(fd) < 0)185rv = -2;186}187break;188default:189rv = -2;190}191192return (rv);193}194195static int196t_sockcred_2_client(int fd)197{198return (t_sockcred_client(2, fd));199}200201static int202t_sockcred_2_server(int fd)203{204return (t_sockcred_server(2, fd));205}206207int208t_sockcred_2(void)209{210return (t_generic(t_sockcred_2_client, t_sockcred_2_server));211}212213214