11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* $OpenBSD: monitor_fdpass.c,v 1.19 2010/01/12 00:58:25 djm Exp $ */ 21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright 2001 Niels Provos <provos@citi.umich.edu> 41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * All rights reserved. 51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Redistribution and use in source and binary forms, with or without 71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * modification, are permitted provided that the following conditions 81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * are met: 91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 1. Redistributions of source code must retain the above copyright 101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer. 111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 2. Redistributions in binary form must reproduce the above copyright 121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer in the 131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * documentation and/or other materials provided with the distribution. 141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h" 281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/types.h> 301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/socket.h> 311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/uio.h> 321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_SYS_UN_H 331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/un.h> 341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <errno.h> 371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_POLL_H 381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <poll.h> 391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <string.h> 411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdarg.h> 421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "log.h" 441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "monitor_fdpass.h" 451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodmm_send_fd(int sock, int fd) 481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if defined(HAVE_SENDMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR)) 501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct msghdr msg; 511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifndef HAVE_ACCRIGHTS_IN_MSGHDR 521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood union { 531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct cmsghdr hdr; 541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char buf[CMSG_SPACE(sizeof(int))]; 551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } cmsgbuf; 561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct cmsghdr *cmsg; 571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct iovec vec; 591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char ch = '\0'; 601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ssize_t n; 611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct pollfd pfd; 621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(&msg, 0, sizeof(msg)); 641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_ACCRIGHTS_IN_MSGHDR 651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood msg.msg_accrights = (caddr_t)&fd; 661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood msg.msg_accrightslen = sizeof(fd); 671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else 681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood msg.msg_control = (caddr_t)&cmsgbuf.buf; 691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood msg.msg_controllen = sizeof(cmsgbuf.buf); 701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cmsg = CMSG_FIRSTHDR(&msg); 711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cmsg->cmsg_len = CMSG_LEN(sizeof(int)); 721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cmsg->cmsg_level = SOL_SOCKET; 731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cmsg->cmsg_type = SCM_RIGHTS; 741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *(int *)CMSG_DATA(cmsg) = fd; 751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood vec.iov_base = &ch; 781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood vec.iov_len = 1; 791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood msg.msg_iov = &vec; 801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood msg.msg_iovlen = 1; 811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pfd.fd = sock; 831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pfd.events = POLLOUT; 841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while ((n = sendmsg(sock, &msg, 0)) == -1 && 851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (errno == EAGAIN || errno == EINTR)) { 861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("%s: sendmsg(%d): %s", __func__, fd, strerror(errno)); 871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (void)poll(&pfd, 1, -1); 881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (n == -1) { 901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: sendmsg(%d): %s", __func__, fd, 911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strerror(errno)); 921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (n != 1) { 961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: sendmsg: expected sent 1 got %ld", 971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __func__, (long)n); 981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else 1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: file descriptor passing not supported", __func__); 1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodmm_receive_fd(int sock) 1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if defined(HAVE_RECVMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR)) 1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct msghdr msg; 1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifndef HAVE_ACCRIGHTS_IN_MSGHDR 1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood union { 1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct cmsghdr hdr; 1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char buf[CMSG_SPACE(sizeof(int))]; 1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } cmsgbuf; 1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct cmsghdr *cmsg; 1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct iovec vec; 1201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ssize_t n; 1211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char ch; 1221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int fd; 1231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct pollfd pfd; 1241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(&msg, 0, sizeof(msg)); 1261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood vec.iov_base = &ch; 1271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood vec.iov_len = 1; 1281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood msg.msg_iov = &vec; 1291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood msg.msg_iovlen = 1; 1301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_ACCRIGHTS_IN_MSGHDR 1311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood msg.msg_accrights = (caddr_t)&fd; 1321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood msg.msg_accrightslen = sizeof(fd); 1331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else 1341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood msg.msg_control = &cmsgbuf.buf; 1351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood msg.msg_controllen = sizeof(cmsgbuf.buf); 1361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 1371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pfd.fd = sock; 1391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pfd.events = POLLIN; 1401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while ((n = recvmsg(sock, &msg, 0)) == -1 && 1411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (errno == EAGAIN || errno == EINTR)) { 1421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("%s: recvmsg: %s", __func__, strerror(errno)); 1431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (void)poll(&pfd, 1, -1); 1441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (n == -1) { 1461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: recvmsg: %s", __func__, strerror(errno)); 1471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 1481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (n != 1) { 1511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: recvmsg: expected received 1 got %ld", 1521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __func__, (long)n); 1531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 1541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_ACCRIGHTS_IN_MSGHDR 1571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (msg.msg_accrightslen != sizeof(fd)) { 1581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: no fd", __func__); 1591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 1601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else 1621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cmsg = CMSG_FIRSTHDR(&msg); 1631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (cmsg == NULL) { 1641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: no message header", __func__); 1651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 1661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifndef BROKEN_CMSG_TYPE 1691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (cmsg->cmsg_type != SCM_RIGHTS) { 1701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: expected type %d got %d", __func__, 1711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SCM_RIGHTS, cmsg->cmsg_type); 1721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 1731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 1751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fd = (*(int *)CMSG_DATA(cmsg)); 1761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 1771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return fd; 1781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else 1791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: file descriptor passing not supported", __func__); 1801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 1811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 1821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 183