1*19261079SEd Maste /* $OpenBSD: monitor_fdpass.c,v 1.22 2020/10/18 11:32:01 djm Exp $ */
2545d5ecaSDag-Erling Smørgrav /*
3545d5ecaSDag-Erling Smørgrav * Copyright 2001 Niels Provos <provos@citi.umich.edu>
4545d5ecaSDag-Erling Smørgrav * All rights reserved.
5545d5ecaSDag-Erling Smørgrav *
6545d5ecaSDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without
7545d5ecaSDag-Erling Smørgrav * modification, are permitted provided that the following conditions
8545d5ecaSDag-Erling Smørgrav * are met:
9545d5ecaSDag-Erling Smørgrav * 1. Redistributions of source code must retain the above copyright
10545d5ecaSDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer.
11545d5ecaSDag-Erling Smørgrav * 2. Redistributions in binary form must reproduce the above copyright
12545d5ecaSDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer in the
13545d5ecaSDag-Erling Smørgrav * documentation and/or other materials provided with the distribution.
14545d5ecaSDag-Erling Smørgrav *
15545d5ecaSDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16545d5ecaSDag-Erling Smørgrav * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17545d5ecaSDag-Erling Smørgrav * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18545d5ecaSDag-Erling Smørgrav * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19545d5ecaSDag-Erling Smørgrav * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20545d5ecaSDag-Erling Smørgrav * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21545d5ecaSDag-Erling Smørgrav * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22545d5ecaSDag-Erling Smørgrav * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23545d5ecaSDag-Erling Smørgrav * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24545d5ecaSDag-Erling Smørgrav * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25545d5ecaSDag-Erling Smørgrav */
26545d5ecaSDag-Erling Smørgrav
27545d5ecaSDag-Erling Smørgrav #include "includes.h"
28545d5ecaSDag-Erling Smørgrav
29761efaa7SDag-Erling Smørgrav #include <sys/types.h>
30761efaa7SDag-Erling Smørgrav #include <sys/socket.h>
31545d5ecaSDag-Erling Smørgrav #include <sys/uio.h>
3292eb0aa1SDag-Erling Smørgrav #ifdef HAVE_SYS_UN_H
3392eb0aa1SDag-Erling Smørgrav #include <sys/un.h>
3492eb0aa1SDag-Erling Smørgrav #endif
35545d5ecaSDag-Erling Smørgrav
36761efaa7SDag-Erling Smørgrav #include <errno.h>
37761efaa7SDag-Erling Smørgrav #include <string.h>
38761efaa7SDag-Erling Smørgrav #include <stdarg.h>
39761efaa7SDag-Erling Smørgrav
40a0ee8cc6SDag-Erling Smørgrav #ifdef HAVE_POLL_H
41a0ee8cc6SDag-Erling Smørgrav # include <poll.h>
42a0ee8cc6SDag-Erling Smørgrav #else
43a0ee8cc6SDag-Erling Smørgrav # ifdef HAVE_SYS_POLL_H
44a0ee8cc6SDag-Erling Smørgrav # include <sys/poll.h>
45a0ee8cc6SDag-Erling Smørgrav # endif
46a0ee8cc6SDag-Erling Smørgrav #endif
47a0ee8cc6SDag-Erling Smørgrav
48545d5ecaSDag-Erling Smørgrav #include "log.h"
49545d5ecaSDag-Erling Smørgrav #include "monitor_fdpass.h"
50545d5ecaSDag-Erling Smørgrav
51d4af9e69SDag-Erling Smørgrav int
mm_send_fd(int sock,int fd)52d74d50a8SDag-Erling Smørgrav mm_send_fd(int sock, int fd)
53545d5ecaSDag-Erling Smørgrav {
5483d2307dSDag-Erling Smørgrav #if defined(HAVE_SENDMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR))
55545d5ecaSDag-Erling Smørgrav struct msghdr msg;
5683d2307dSDag-Erling Smørgrav #ifndef HAVE_ACCRIGHTS_IN_MSGHDR
57882ff9f5SDag-Erling Smørgrav union {
58882ff9f5SDag-Erling Smørgrav struct cmsghdr hdr;
59882ff9f5SDag-Erling Smørgrav char buf[CMSG_SPACE(sizeof(int))];
60882ff9f5SDag-Erling Smørgrav } cmsgbuf;
6183d2307dSDag-Erling Smørgrav struct cmsghdr *cmsg;
6283d2307dSDag-Erling Smørgrav #endif
63cce7d346SDag-Erling Smørgrav struct iovec vec;
64cce7d346SDag-Erling Smørgrav char ch = '\0';
65cce7d346SDag-Erling Smørgrav ssize_t n;
66b15c8340SDag-Erling Smørgrav struct pollfd pfd;
67545d5ecaSDag-Erling Smørgrav
68545d5ecaSDag-Erling Smørgrav memset(&msg, 0, sizeof(msg));
6983d2307dSDag-Erling Smørgrav #ifdef HAVE_ACCRIGHTS_IN_MSGHDR
7083d2307dSDag-Erling Smørgrav msg.msg_accrights = (caddr_t)&fd;
7183d2307dSDag-Erling Smørgrav msg.msg_accrightslen = sizeof(fd);
7283d2307dSDag-Erling Smørgrav #else
73bc5531deSDag-Erling Smørgrav memset(&cmsgbuf, 0, sizeof(cmsgbuf));
74882ff9f5SDag-Erling Smørgrav msg.msg_control = (caddr_t)&cmsgbuf.buf;
75882ff9f5SDag-Erling Smørgrav msg.msg_controllen = sizeof(cmsgbuf.buf);
76545d5ecaSDag-Erling Smørgrav cmsg = CMSG_FIRSTHDR(&msg);
77545d5ecaSDag-Erling Smørgrav cmsg->cmsg_len = CMSG_LEN(sizeof(int));
78545d5ecaSDag-Erling Smørgrav cmsg->cmsg_level = SOL_SOCKET;
79545d5ecaSDag-Erling Smørgrav cmsg->cmsg_type = SCM_RIGHTS;
80545d5ecaSDag-Erling Smørgrav *(int *)CMSG_DATA(cmsg) = fd;
8183d2307dSDag-Erling Smørgrav #endif
82545d5ecaSDag-Erling Smørgrav
83545d5ecaSDag-Erling Smørgrav vec.iov_base = &ch;
84545d5ecaSDag-Erling Smørgrav vec.iov_len = 1;
85545d5ecaSDag-Erling Smørgrav msg.msg_iov = &vec;
86545d5ecaSDag-Erling Smørgrav msg.msg_iovlen = 1;
87545d5ecaSDag-Erling Smørgrav
88b15c8340SDag-Erling Smørgrav pfd.fd = sock;
89b15c8340SDag-Erling Smørgrav pfd.events = POLLOUT;
90b15c8340SDag-Erling Smørgrav while ((n = sendmsg(sock, &msg, 0)) == -1 &&
91b15c8340SDag-Erling Smørgrav (errno == EAGAIN || errno == EINTR)) {
92*19261079SEd Maste debug3_f("sendmsg(%d): %s", fd, strerror(errno));
93b15c8340SDag-Erling Smørgrav (void)poll(&pfd, 1, -1);
94b15c8340SDag-Erling Smørgrav }
95cce7d346SDag-Erling Smørgrav if (n == -1) {
96*19261079SEd Maste error_f("sendmsg(%d): %s", fd, strerror(errno));
97d4af9e69SDag-Erling Smørgrav return -1;
98d4af9e69SDag-Erling Smørgrav }
99d4af9e69SDag-Erling Smørgrav
100d4af9e69SDag-Erling Smørgrav if (n != 1) {
101*19261079SEd Maste error_f("sendmsg: expected sent 1 got %zd", n);
102d4af9e69SDag-Erling Smørgrav return -1;
103d4af9e69SDag-Erling Smørgrav }
104d4af9e69SDag-Erling Smørgrav return 0;
10583d2307dSDag-Erling Smørgrav #else
106d4af9e69SDag-Erling Smørgrav error("%s: file descriptor passing not supported", __func__);
107d4af9e69SDag-Erling Smørgrav return -1;
10883d2307dSDag-Erling Smørgrav #endif
109545d5ecaSDag-Erling Smørgrav }
110545d5ecaSDag-Erling Smørgrav
111545d5ecaSDag-Erling Smørgrav int
mm_receive_fd(int sock)112d74d50a8SDag-Erling Smørgrav mm_receive_fd(int sock)
113545d5ecaSDag-Erling Smørgrav {
11483d2307dSDag-Erling Smørgrav #if defined(HAVE_RECVMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR))
115545d5ecaSDag-Erling Smørgrav struct msghdr msg;
11683d2307dSDag-Erling Smørgrav #ifndef HAVE_ACCRIGHTS_IN_MSGHDR
117882ff9f5SDag-Erling Smørgrav union {
118882ff9f5SDag-Erling Smørgrav struct cmsghdr hdr;
119882ff9f5SDag-Erling Smørgrav char buf[CMSG_SPACE(sizeof(int))];
120882ff9f5SDag-Erling Smørgrav } cmsgbuf;
12183d2307dSDag-Erling Smørgrav struct cmsghdr *cmsg;
12283d2307dSDag-Erling Smørgrav #endif
123cce7d346SDag-Erling Smørgrav struct iovec vec;
124cce7d346SDag-Erling Smørgrav ssize_t n;
125cce7d346SDag-Erling Smørgrav char ch;
126cce7d346SDag-Erling Smørgrav int fd;
127b15c8340SDag-Erling Smørgrav struct pollfd pfd;
128545d5ecaSDag-Erling Smørgrav
129545d5ecaSDag-Erling Smørgrav memset(&msg, 0, sizeof(msg));
130545d5ecaSDag-Erling Smørgrav vec.iov_base = &ch;
131545d5ecaSDag-Erling Smørgrav vec.iov_len = 1;
132545d5ecaSDag-Erling Smørgrav msg.msg_iov = &vec;
133545d5ecaSDag-Erling Smørgrav msg.msg_iovlen = 1;
13483d2307dSDag-Erling Smørgrav #ifdef HAVE_ACCRIGHTS_IN_MSGHDR
13583d2307dSDag-Erling Smørgrav msg.msg_accrights = (caddr_t)&fd;
13683d2307dSDag-Erling Smørgrav msg.msg_accrightslen = sizeof(fd);
13783d2307dSDag-Erling Smørgrav #else
138bc5531deSDag-Erling Smørgrav memset(&cmsgbuf, 0, sizeof(cmsgbuf));
139882ff9f5SDag-Erling Smørgrav msg.msg_control = &cmsgbuf.buf;
140882ff9f5SDag-Erling Smørgrav msg.msg_controllen = sizeof(cmsgbuf.buf);
14183d2307dSDag-Erling Smørgrav #endif
142545d5ecaSDag-Erling Smørgrav
143b15c8340SDag-Erling Smørgrav pfd.fd = sock;
144b15c8340SDag-Erling Smørgrav pfd.events = POLLIN;
145b15c8340SDag-Erling Smørgrav while ((n = recvmsg(sock, &msg, 0)) == -1 &&
146b15c8340SDag-Erling Smørgrav (errno == EAGAIN || errno == EINTR)) {
147*19261079SEd Maste debug3_f("recvmsg: %s", strerror(errno));
148b15c8340SDag-Erling Smørgrav (void)poll(&pfd, 1, -1);
149b15c8340SDag-Erling Smørgrav }
150cce7d346SDag-Erling Smørgrav if (n == -1) {
151*19261079SEd Maste error_f("recvmsg: %s", strerror(errno));
152d4af9e69SDag-Erling Smørgrav return -1;
153d4af9e69SDag-Erling Smørgrav }
154cce7d346SDag-Erling Smørgrav
155d4af9e69SDag-Erling Smørgrav if (n != 1) {
156*19261079SEd Maste error_f("recvmsg: expected received 1 got %zd", n);
157d4af9e69SDag-Erling Smørgrav return -1;
158d4af9e69SDag-Erling Smørgrav }
159545d5ecaSDag-Erling Smørgrav
16083d2307dSDag-Erling Smørgrav #ifdef HAVE_ACCRIGHTS_IN_MSGHDR
161d4af9e69SDag-Erling Smørgrav if (msg.msg_accrightslen != sizeof(fd)) {
162*19261079SEd Maste error_f("no fd");
163d4af9e69SDag-Erling Smørgrav return -1;
164d4af9e69SDag-Erling Smørgrav }
16583d2307dSDag-Erling Smørgrav #else
166545d5ecaSDag-Erling Smørgrav cmsg = CMSG_FIRSTHDR(&msg);
167d4af9e69SDag-Erling Smørgrav if (cmsg == NULL) {
168*19261079SEd Maste error_f("no message header");
169d4af9e69SDag-Erling Smørgrav return -1;
170d4af9e69SDag-Erling Smørgrav }
171cce7d346SDag-Erling Smørgrav
172d95e11bfSDag-Erling Smørgrav #ifndef BROKEN_CMSG_TYPE
173d4af9e69SDag-Erling Smørgrav if (cmsg->cmsg_type != SCM_RIGHTS) {
174*19261079SEd Maste error_f("expected %d got %d", SCM_RIGHTS, cmsg->cmsg_type);
175d4af9e69SDag-Erling Smørgrav return -1;
176d4af9e69SDag-Erling Smørgrav }
177d95e11bfSDag-Erling Smørgrav #endif
178545d5ecaSDag-Erling Smørgrav fd = (*(int *)CMSG_DATA(cmsg));
17983d2307dSDag-Erling Smørgrav #endif
180545d5ecaSDag-Erling Smørgrav return fd;
18183d2307dSDag-Erling Smørgrav #else
182*19261079SEd Maste error_f("file descriptor passing not supported");
183d4af9e69SDag-Erling Smørgrav return -1;
18483d2307dSDag-Erling Smørgrav #endif
185545d5ecaSDag-Erling Smørgrav }
186