ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libptytty/src/fdpass.C
Revision: 1.20
Committed: Fri Oct 31 07:57:54 2014 UTC (11 years, 10 months ago) by sf-exg
Content type: text/plain
Branch: MAIN
CVS Tags: rxvt-unicode-rel-9_26, rxvt-unicode-rel-9_25, rxvt-unicode-rel-9_22, rxvt-unicode-rel-9_21, rel-1_8, rel-1_7
Changes since 1.19: +5 -5 lines
Log Message:
Check CMSG_FIRSTHDR instead of msg_controllen to verify the validity of the buffer returned by recvmsg.

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 ayin 1.9 #include <sys/types.h>
29 root 1.2 #include <sys/uio.h>
30 root 1.1 #include <sys/socket.h>
31    
32 root 1.3 #include "libptytty.h"
33 root 1.1
34 root 1.10 // CMSG_SPACE & CMSG_LEN are rfc2292 extensions to unix
35     #ifndef CMSG_SPACE
36     # define CMSG_SPACE(len) (sizeof (cmsghdr) + len)
37     #endif
38    
39     #ifndef CMSG_LEN
40 root 1.1 # define CMSG_LEN(len) (sizeof (cmsghdr) + len)
41     #endif
42    
43 root 1.5 bool
44 root 1.3 ptytty::send_fd (int socket, int fd)
45 root 1.1 {
46 root 1.10 void *buf = malloc (CMSG_SPACE (sizeof (int)));
47    
48     if (!buf)
49     return 0;
50    
51 root 1.1 msghdr msg;
52     iovec iov;
53 root 1.10 cmsghdr *cmsg;
54 root 1.1 char data = 0;
55    
56     iov.iov_base = &data;
57     iov.iov_len = 1;
58    
59     msg.msg_name = 0;
60     msg.msg_namelen = 0;
61     msg.msg_iov = &iov;
62     msg.msg_iovlen = 1;
63 root 1.10 msg.msg_control = buf;
64     msg.msg_controllen = CMSG_SPACE (sizeof (int));
65 root 1.1
66 root 1.10 cmsg = CMSG_FIRSTHDR (&msg);
67 root 1.1 cmsg->cmsg_level = SOL_SOCKET;
68     cmsg->cmsg_type = SCM_RIGHTS;
69     cmsg->cmsg_len = CMSG_LEN (sizeof (int));
70    
71     *(int *)CMSG_DATA (cmsg) = fd;
72    
73 root 1.10 ssize_t result = sendmsg (socket, &msg, 0);
74    
75     free (buf);
76 root 1.1
77 root 1.10 return result >= 0;
78 root 1.1 }
79    
80     int
81 root 1.3 ptytty::recv_fd (int socket)
82 root 1.1 {
83 root 1.10 void *buf = malloc (CMSG_SPACE (sizeof (int)));
84    
85     if (!buf)
86     return -1;
87    
88 root 1.1 msghdr msg;
89     iovec iov;
90     char data = 1;
91    
92     iov.iov_base = &data;
93     iov.iov_len = 1;
94    
95     msg.msg_name = 0;
96     msg.msg_namelen = 0;
97     msg.msg_iov = &iov;
98     msg.msg_iovlen = 1;
99     msg.msg_control = buf;
100 root 1.10 msg.msg_controllen = CMSG_SPACE (sizeof (int));
101 root 1.1
102 root 1.10 int fd = -1;
103    
104     if (recvmsg (socket, &msg, 0) > 0
105 sf-exg 1.20 && data == 0)
106 root 1.10 {
107     cmsghdr *cmsg = CMSG_FIRSTHDR (&msg);
108 root 1.1
109 sf-exg 1.20 if (cmsg
110     && cmsg->cmsg_level == SOL_SOCKET
111     && cmsg->cmsg_type == SCM_RIGHTS
112     && cmsg->cmsg_len >= CMSG_LEN (sizeof (int)))
113 root 1.10 fd = *(int *)CMSG_DATA (cmsg);
114     }
115 root 1.1
116 root 1.10 free (buf);
117 root 1.1
118 root 1.10 return fd;
119 root 1.1 }
120