Compare commits
6 Commits
cafb33d5f0
...
a820bbf933
| Author | SHA1 | Date | |
|---|---|---|---|
| a820bbf933 | |||
| 7e12382248 | |||
| 59da5998b8 | |||
| 20bf3b8fba | |||
| a0a8bd0de4 | |||
| d5c2503150 |
@@ -50,29 +50,60 @@ int open_socket(char * pathname) {
|
||||
return fd;
|
||||
}
|
||||
|
||||
int * fds_from_msg(struct msghdr *msg, size_t peer_fds_count) {
|
||||
int *peer_fds = (int *) calloc(peer_fds_count, sizeof(int));
|
||||
int * fds_from_msg(struct msghdr *msg, int * peer_fds) {
|
||||
// * there may be multiple SCM_RIGHTS messages
|
||||
// * we expect three fds
|
||||
// * if we get some number other than three, we should
|
||||
// close all of them and return NULL because someone is up to no good
|
||||
int i = 0;
|
||||
peer_fds[0] = -1;
|
||||
peer_fds[1] = -1;
|
||||
peer_fds[2] = -1;
|
||||
|
||||
for (struct cmsghdr* cmsg = CMSG_FIRSTHDR(msg);
|
||||
cmsg != NULL;
|
||||
cmsg = CMSG_NXTHDR(msg, cmsg)) {
|
||||
if(cmsg->cmsg_level == SOL_SOCKET &&
|
||||
cmsg->cmsg_type == SCM_RIGHTS) {
|
||||
memcpy(peer_fds, CMSG_DATA(cmsg), peer_fds_count * sizeof(int));
|
||||
int passed_fd_count = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof (int);
|
||||
if(i <= 3) {
|
||||
memcpy(&peer_fds[i], CMSG_DATA(cmsg), passed_fd_count * sizeof(int));
|
||||
|
||||
} else {
|
||||
int * reject_fds = (int *) CMSG_DATA(cmsg);
|
||||
for(int fd = 0; fd < passed_fd_count; fd++) {
|
||||
close(reject_fds[fd]);
|
||||
}
|
||||
}
|
||||
i += passed_fd_count;
|
||||
}
|
||||
}
|
||||
return peer_fds;
|
||||
if(i != 3) {
|
||||
/* if the peer sent too many fds, we closed the excess ones
|
||||
* in the reject_fds clause above and now we'll close the
|
||||
* first three.
|
||||
* if they sent too few, we'll close whatever they sent
|
||||
*/
|
||||
|
||||
if(peer_fds[0] >=0) close(peer_fds[0]);
|
||||
if(peer_fds[1] >=0) close(peer_fds[1]);
|
||||
if(peer_fds[2] >=0) close(peer_fds[2]);
|
||||
return NULL;
|
||||
} else {
|
||||
return peer_fds;
|
||||
}
|
||||
}
|
||||
|
||||
int start_lua_child(lua_State *L,
|
||||
char * command_line, int command_line_length,
|
||||
int * fds, int fds_count) {
|
||||
int * fds) {
|
||||
char * word = command_line;
|
||||
char * command_line_end = command_line + command_line_length;
|
||||
char * pathname = NULL;
|
||||
int i = 0;
|
||||
|
||||
fflush(stdout); fflush(stderr);
|
||||
for(int i=0; i < fds_count; i++) {
|
||||
for(int i=0; i < 3; i++) {
|
||||
if(fds[i] > 0) dup2(fds[i], i);
|
||||
}
|
||||
|
||||
@@ -98,11 +129,11 @@ int start_lua_child(lua_State *L,
|
||||
|
||||
pid_t fork_lua(lua_State *L,
|
||||
char * command_line, int command_line_length,
|
||||
int * fds, int fds_count) {
|
||||
int * fds) {
|
||||
pid_t pid = fork();
|
||||
if(pid == 0) {
|
||||
exit(start_lua_child(L, command_line, command_line_length,
|
||||
fds, fds_count));
|
||||
fds));
|
||||
} else if(pid > 0) {
|
||||
free(command_line);
|
||||
return pid;
|
||||
@@ -213,16 +244,22 @@ int main(int argc, char **argv)
|
||||
if(pollfds[0].revents) {
|
||||
if(find_peer(0)) {
|
||||
int len = recvmsg(socket, &msg , 0);
|
||||
int *peer_fds = fds_from_msg(&msg, 5);
|
||||
char *argline = malloc(len);
|
||||
if(! argline) {
|
||||
die("malloc failed");
|
||||
}
|
||||
memmove(argline, buf, len);
|
||||
int peer_fds[3];
|
||||
if(fds_from_msg(&msg, peer_fds)) {
|
||||
char *argline = malloc(len);
|
||||
if(! argline) {
|
||||
die("malloc failed");
|
||||
}
|
||||
memmove(argline, buf, len);
|
||||
|
||||
pid_t child_pid = fork_lua(L, argline, len, peer_fds, 5);
|
||||
if(child_pid >= 0) {
|
||||
register_peer(child_pid, &peer_addr, msg.msg_namelen);
|
||||
pid_t child_pid = fork_lua(L, argline, len, peer_fds);
|
||||
if(child_pid >= 0) {
|
||||
register_peer(child_pid, &peer_addr, msg.msg_namelen);
|
||||
}
|
||||
/* close peer fds in parent */
|
||||
close(peer_fds[0]);
|
||||
close(peer_fds[1]);
|
||||
close(peer_fds[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user