ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/libptytty/src/fdpass.C
Revision: 1.24
Committed: Tue Sep 6 10:45:36 2022 UTC (4 years ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.23: +12 -1 lines
Log Message:
close extra fd's

File Contents

# User Rev Content
1 root 1.4 /*----------------------------------------------------------------------*
2 root 1.1 * File: fdpass.C
3     *----------------------------------------------------------------------*
4     *
5     * All portions of code are copyright by their respective author/s.
6 root 1.14 * Copyright (c) 2005-2006,2012 Marc Lehmann <schmorp@schmorp.de>
7 root 1.1 *
8     * This program is free software; you can redistribute it and/or modify
9     * it under the terms of the GNU General Public License as published by
10 sf-exg 1.19 * the Free Software Foundation; either version 2 of the License, or
11 root 1.1 * (at your option) any later version.
12     *
13     * This program is distributed in the hope that it will be useful,
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     * GNU General Public License for more details.
17     *
18     * You should have received a copy of the GNU General Public License
19     * along with this program; if not, write to the Free Software
20     * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21     *----------------------------------------------------------------------*/
22    
23 sf-exg 1.11 #include "config.h"
24 root 1.1
25 sf-exg 1.17 #include <stddef.h> // needed by broken bsds for NULL used in sys/uio.h
26 sf-exg 1.16 #include <stdlib.h>
27 root 1.6
28 root 1.24 #include <unistd.h>
29 ayin 1.9 #include <sys/types.h>
30 root 1.2 #include <sys/uio.h>
31 root 1.1 #include <sys/socket.h>
32    
33 root 1.3 #include "libptytty.h"
34 root 1.1
35 root 1.10 // CMSG_SPACE & CMSG_LEN are rfc2292 extensions to unix
36     #ifndef CMSG_SPACE
37     # define CMSG_SPACE(len) (sizeof (cmsghdr) + len)
38     #endif
39    
40     #ifndef CMSG_LEN
41 root 1.1 # define CMSG_LEN(len) (sizeof (cmsghdr) + len)
42     #endif
43    
44 root 1.5 bool
45 root 1.3 ptytty::send_fd (int socket, int fd)
46 root 1.1 {
47 root 1.10 void *buf = malloc (CMSG_SPACE (sizeof (int)));
48    
49     if (!buf)
50     return 0;
51    
52 root 1.1 msghdr msg;
53     iovec iov;
54 root 1.10 cmsghdr *cmsg;
55 root 1.1 char data = 0;
56    
57     iov.iov_base = &data;
58     iov.iov_len = 1;
59    
60     msg.msg_name = 0;
61     msg.msg_namelen = 0;
62     msg.msg_iov = &iov;
63     msg.msg_iovlen = 1;
64 root 1.10 msg.msg_control = buf;
65     msg.msg_controllen = CMSG_SPACE (sizeof (int));
66 root 1.1
67 root 1.10 cmsg = CMSG_FIRSTHDR (&msg);
68 root 1.1 cmsg->cmsg_level = SOL_SOCKET;
69     cmsg->cmsg_type = SCM_RIGHTS;
70     cmsg->cmsg_len = CMSG_LEN (sizeof (int));
71    
72     *(int *)CMSG_DATA (cmsg) = fd;
73    
74 root 1.10 ssize_t result = sendmsg (socket, &msg, 0);
75    
76     free (buf);
77 root 1.1
78 root 1.10 return result >= 0;
79 root 1.1 }
80    
81     int
82 root 1.3 ptytty::recv_fd (int socket)
83 root 1.1 {
84 root 1.10 void *buf = malloc (CMSG_SPACE (sizeof (int)));
85    
86     if (!buf)
87     return -1;
88    
89 root 1.1 msghdr msg;
90     iovec iov;
91     char data = 1;
92    
93     iov.iov_base = &data;
94     iov.iov_len = 1;
95    
96     msg.msg_name = 0;
97     msg.msg_namelen = 0;
98     msg.msg_iov = &iov;
99     msg.msg_iovlen = 1;
100     msg.msg_control = buf;
101 root 1.10 msg.msg_controllen = CMSG_SPACE (sizeof (int));
102 root 1.1
103 root 1.10 int fd = -1;
104    
105 root 1.23 if (recvmsg (socket, &msg, 0) > 0)
106 root 1.10 {
107     cmsghdr *cmsg = CMSG_FIRSTHDR (&msg);
108 root 1.1
109 root 1.22 if (cmsg)
110     {
111     // some operating systems (i.e. osx) allow msg->cmsg_len to be larger than
112     // msg.msg_controllen, so limit the size here
113     if (cmsg->cmsg_len > CMSG_SPACE (sizeof (int)))
114     cmsg->cmsg_len = CMSG_SPACE (sizeof (int));
115 root 1.21
116 root 1.22 if ( cmsg->cmsg_level == SOL_SOCKET
117     && cmsg->cmsg_type == SCM_RIGHTS
118     && cmsg->cmsg_len >= CMSG_LEN (sizeof (int)))
119 root 1.24 {
120     // close any extra fd's that might have been passed.
121     // this does not work around osx/freebsad bugs where a malicious sender
122     // can send usw more fds than we can receive, leaking the extra fds,
123     // which must be fixed in the kernel, really.
124     for (fd = 1; cmsg->cmsg_len >= CMSG_LEN (sizeof (int) * (fd + 1)); ++fd)
125     close (((int *)CMSG_DATA (cmsg))[fd]);
126    
127     // we are only interested in the first fd
128     fd = *(int *)CMSG_DATA (cmsg);
129     }
130 root 1.22 }
131 root 1.10 }
132 root 1.1
133 root 1.10 free (buf);
134 root 1.1
135 root 1.23 if (data != 0)
136     {
137     close (fd);
138     fd = -1;
139     }
140    
141 root 1.10 return fd;
142 root 1.1 }
143