33
44#include < csignal>
55#include < string>
6+ #include < cstring>
67#include < unordered_map>
78#include < vector>
89#include < exception>
910#include < cstdlib>
1011
1112#include < sys/syscall.h>
13+ #include < sys/socket.h>
14+ #include < sys/un.h>
1215#include < unistd.h>
1316#include < execinfo.h>
1417
@@ -19,7 +22,6 @@ using namespace std;
1922
2023
2124typedef unsigned int Filedescriptor_t;
22- typedef unsigned int pidfd_t ;
2325
2426typedef uint16_t HTTPVersionType_t;
2527typedef uint16_t HTTPMethodType_t;
@@ -53,7 +55,7 @@ class Signal {
5355
5456public:
5557
56- // - disable unwanted signal handlers (SIGINT, SIGPIPE)
58+ // disable unwanted signal handlers (SIGINT, SIGPIPE)
5759 static void disableSignals ()
5860 {
5961 signal (SIGINT, SIG_IGN);
@@ -67,16 +69,118 @@ class Syscall {
6769
6870public:
6971
70- // - wrapper function for pidfd_open
71- static int pidfd_open ( pid_t pid, unsigned int flags )
72+ // unix domain socket for FD passing - server side (parent process)
73+ static int createFDPassingServer ( const char * socket_path )
7274 {
73- return syscall (SYS_pidfd_open, pid, flags);
75+ int server_fd = socket (AF_UNIX, SOCK_SEQPACKET, 0 );
76+ if (server_fd < 0 ) {
77+ return -1 ;
78+ }
79+
80+ // remove any existing socket file
81+ unlink (socket_path);
82+
83+ struct sockaddr_un server_addr;
84+ memset (&server_addr, 0 , sizeof (server_addr));
85+ server_addr.sun_family = AF_UNIX;
86+ strncpy (server_addr.sun_path , socket_path, sizeof (server_addr.sun_path ) - 1 );
87+
88+ if (bind (server_fd, (struct sockaddr *)&server_addr, sizeof (server_addr)) < 0 ) {
89+ close (server_fd);
90+ return -1 ;
91+ }
92+
93+ if (listen (server_fd, 50 ) < 0 ) {
94+ close (server_fd);
95+ return -1 ;
96+ }
97+
98+ return server_fd;
7499 }
75100
76- // - wrapper function for pidfd_getfd
77- static int pidfd_getfd ( int pidfd, int targetfd, unsigned int flags )
101+ // unix domain socket for FD passing - client side (child process)
102+ static int connectFDPassingClient ( const char * socket_path )
78103 {
79- return syscall (SYS_pidfd_getfd, pidfd, targetfd, flags);
104+ int client_fd = socket (AF_UNIX, SOCK_SEQPACKET, 0 );
105+ if (client_fd < 0 ) {
106+ return -1 ;
107+ }
108+
109+ struct sockaddr_un server_addr;
110+ memset (&server_addr, 0 , sizeof (server_addr));
111+ server_addr.sun_family = AF_UNIX;
112+ strncpy (server_addr.sun_path , socket_path, sizeof (server_addr.sun_path ) - 1 );
113+
114+ if (connect (client_fd, (struct sockaddr *)&server_addr, sizeof (server_addr)) < 0 ) {
115+ close (client_fd);
116+ return -1 ;
117+ }
118+
119+ return client_fd;
120+ }
121+
122+ // send a file descriptor over Unix domain socket
123+ static int sendFD (int socket_fd, int fd_to_send)
124+ {
125+ struct msghdr msg;
126+ struct iovec iov[1 ];
127+ char ctrl_buf[CMSG_SPACE (sizeof (int ))];
128+ char data[1 ] = {0 };
129+
130+ memset (&msg, 0 , sizeof (msg));
131+ memset (ctrl_buf, 0 , sizeof (ctrl_buf));
132+
133+ // Setup iovec for dummy data
134+ iov[0 ].iov_base = data;
135+ iov[0 ].iov_len = sizeof (data);
136+
137+ msg.msg_iov = iov;
138+ msg.msg_iovlen = 1 ;
139+ msg.msg_control = ctrl_buf;
140+ msg.msg_controllen = sizeof (ctrl_buf);
141+
142+ struct cmsghdr *cmsg = CMSG_FIRSTHDR (&msg);
143+ cmsg->cmsg_level = SOL_SOCKET;
144+ cmsg->cmsg_type = SCM_RIGHTS;
145+ cmsg->cmsg_len = CMSG_LEN (sizeof (int ));
146+ *((int *)CMSG_DATA (cmsg)) = fd_to_send;
147+
148+ if (sendmsg (socket_fd, &msg, 0 ) < 0 ) {
149+ return -1 ;
150+ }
151+
152+ return 0 ;
153+ }
154+
155+ // receive a file descriptor over Unix domain socket
156+ static int recvFD (int socket_fd)
157+ {
158+ struct msghdr msg;
159+ struct iovec iov[1 ];
160+ char ctrl_buf[CMSG_SPACE (sizeof (int ))];
161+ char data[1 ];
162+
163+ memset (&msg, 0 , sizeof (msg));
164+ memset (ctrl_buf, 0 , sizeof (ctrl_buf));
165+
166+ iov[0 ].iov_base = data;
167+ iov[0 ].iov_len = sizeof (data);
168+
169+ msg.msg_iov = iov;
170+ msg.msg_iovlen = 1 ;
171+ msg.msg_control = ctrl_buf;
172+ msg.msg_controllen = sizeof (ctrl_buf);
173+
174+ if (recvmsg (socket_fd, &msg, 0 ) < 0 ) {
175+ return -1 ;
176+ }
177+
178+ struct cmsghdr *cmsg = CMSG_FIRSTHDR (&msg);
179+ if (cmsg == NULL || cmsg->cmsg_type != SCM_RIGHTS) {
180+ return -1 ;
181+ }
182+
183+ return *((int *)CMSG_DATA (cmsg));
80184 }
81185
82186};
@@ -88,7 +192,7 @@ class Permission {
88192
89193 static void dropPrivileges (uint GroupID, uint UserID)
90194 {
91- // - in case of being root, drop privileges
195+ // in case of being root, drop privileges
92196 if (getuid () == 0 ) {
93197
94198 if (setgid (GroupID) != 0 ) {
0 commit comments