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

# Content
1 /*----------------------------------------------------------------------*
2 * File: fdpass.C
3 *----------------------------------------------------------------------*
4 *
5 * All portions of code are copyright by their respective author/s.
6 * Copyright (c) 2005-2006,2012 Marc Lehmann <schmorp@schmorp.de>
7 *
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 * the Free Software Foundation; either version 2 of the License, or
11 * (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 #include "config.h"
24
25 #include <stddef.h> // needed by broken bsds for NULL used in sys/uio.h
26 #include <stdlib.h>
27
28 #include <sys/types.h>
29 #include <sys/uio.h>
30 #include <sys/socket.h>
31
32 #include "libptytty.h"
33
34 // 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 # define CMSG_LEN(len) (sizeof (cmsghdr) + len)
41 #endif
42
43 bool
44 ptytty::send_fd (int socket, int fd)
45 {
46 void *buf = malloc (CMSG_SPACE (sizeof (int)));
47
48 if (!buf)
49 return 0;
50
51 msghdr msg;
52 iovec iov;
53 cmsghdr *cmsg;
54 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 msg.msg_control = buf;
64 msg.msg_controllen = CMSG_SPACE (sizeof (int));
65
66 cmsg = CMSG_FIRSTHDR (&msg);
67 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 ssize_t result = sendmsg (socket, &msg, 0);
74
75 free (buf);
76
77 return result >= 0;
78 }
79
80 int
81 ptytty::recv_fd (int socket)
82 {
83 void *buf = malloc (CMSG_SPACE (sizeof (int)));
84
85 if (!buf)
86 return -1;
87
88 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 msg.msg_controllen = CMSG_SPACE (sizeof (int));
101
102 int fd = -1;
103
104 if (recvmsg (socket, &msg, 0) > 0
105 && data == 0)
106 {
107 cmsghdr *cmsg = CMSG_FIRSTHDR (&msg);
108
109 if (cmsg
110 && cmsg->cmsg_level == SOL_SOCKET
111 && cmsg->cmsg_type == SCM_RIGHTS
112 && cmsg->cmsg_len >= CMSG_LEN (sizeof (int)))
113 fd = *(int *)CMSG_DATA (cmsg);
114 }
115
116 free (buf);
117
118 return fd;
119 }
120