-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
merge pr #3599 into opencontainers/runc:main
Cory Snider (5): libct/nsenter: namespace the bindfd shuffle libct/nsenter: set FD_CLOEXEC on received fd libct/nsenter: refactor ipc funcs for reusability libct/nsenter: annotate write_log() prototype chore(libct/nsenter): extract utility code LGTMs: AkihiroSuda kolyshkin cyphar Closes #3599
- Loading branch information
Showing
8 changed files
with
433 additions
and
244 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#define _GNU_SOURCE | ||
#include <errno.h> | ||
#include <stdlib.h> | ||
#include "getenv.h" | ||
#include "log.h" | ||
|
||
int getenv_int(const char *name) | ||
{ | ||
char *val, *endptr; | ||
int ret; | ||
|
||
val = getenv(name); | ||
/* Treat empty value as unset variable. */ | ||
if (val == NULL || *val == '\0') | ||
return -ENOENT; | ||
|
||
ret = strtol(val, &endptr, 10); | ||
if (val == endptr || *endptr != '\0') | ||
bail("unable to parse %s=%s", name, val); | ||
/* | ||
* Sanity check: this must be a non-negative number. | ||
*/ | ||
if (ret < 0) | ||
bail("bad value for %s=%s (%d)", name, val, ret); | ||
|
||
return ret; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#ifndef NSENTER_GETENV_H | ||
#define NSENTER_GETENV_H | ||
|
||
/* | ||
* Returns an environment variable value as a non-negative integer, or -ENOENT | ||
* if the variable was not found or has an empty value. | ||
* | ||
* If the value can not be converted to an integer, or the result is out of | ||
* range, the function bails out. | ||
*/ | ||
int getenv_int(const char *name); | ||
|
||
#endif /* NSENTER_GETENV_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
#define _GNU_SOURCE | ||
#include <alloca.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <sys/socket.h> | ||
#include "ipc.h" | ||
#include "log.h" | ||
|
||
int receive_fd(int sockfd) | ||
{ | ||
int bytes_read; | ||
struct msghdr msg = { }; | ||
struct cmsghdr *cmsg; | ||
struct iovec iov = { }; | ||
char null_byte = '\0'; | ||
int ret; | ||
int fd_count; | ||
|
||
iov.iov_base = &null_byte; | ||
iov.iov_len = 1; | ||
|
||
msg.msg_iov = &iov; | ||
msg.msg_iovlen = 1; | ||
|
||
msg.msg_controllen = CMSG_SPACE(sizeof(int)); | ||
msg.msg_control = malloc(msg.msg_controllen); | ||
if (msg.msg_control == NULL) { | ||
bail("Can't allocate memory to receive fd."); | ||
} | ||
|
||
memset(msg.msg_control, 0, msg.msg_controllen); | ||
|
||
bytes_read = recvmsg(sockfd, &msg, MSG_CMSG_CLOEXEC); | ||
if (bytes_read != 1) | ||
bail("failed to receive fd from unix socket %d", sockfd); | ||
if (msg.msg_flags & MSG_CTRUNC) | ||
bail("received truncated control message from unix socket %d", sockfd); | ||
|
||
cmsg = CMSG_FIRSTHDR(&msg); | ||
if (!cmsg) | ||
bail("received message from unix socket %d without control message", sockfd); | ||
|
||
if (cmsg->cmsg_level != SOL_SOCKET) | ||
bail("received unknown control message from unix socket %d: cmsg_level=%d", sockfd, cmsg->cmsg_level); | ||
|
||
if (cmsg->cmsg_type != SCM_RIGHTS) | ||
bail("received unknown control message from unix socket %d: cmsg_type=%d", sockfd, cmsg->cmsg_type); | ||
|
||
fd_count = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int); | ||
if (fd_count != 1) | ||
bail("received control message from unix socket %d with too many fds: %d", sockfd, fd_count); | ||
|
||
ret = *(int *)CMSG_DATA(cmsg); | ||
free(msg.msg_control); | ||
return ret; | ||
} | ||
|
||
int send_fd(int sockfd, int fd) | ||
{ | ||
struct msghdr msg = { }; | ||
struct cmsghdr *cmsg; | ||
struct iovec iov[1] = { }; | ||
char null_byte = '\0'; | ||
|
||
iov[0].iov_base = &null_byte; | ||
iov[0].iov_len = 1; | ||
|
||
msg.msg_iov = iov; | ||
msg.msg_iovlen = 1; | ||
|
||
/* We send only one fd as specified by cmsg->cmsg_len below, even | ||
* though msg.msg_controllen might have more space due to alignment. */ | ||
msg.msg_controllen = CMSG_SPACE(sizeof(int)); | ||
msg.msg_control = alloca(msg.msg_controllen); | ||
memset(msg.msg_control, 0, msg.msg_controllen); | ||
|
||
cmsg = CMSG_FIRSTHDR(&msg); | ||
cmsg->cmsg_level = SOL_SOCKET; | ||
cmsg->cmsg_type = SCM_RIGHTS; | ||
cmsg->cmsg_len = CMSG_LEN(sizeof(int)); | ||
memcpy(CMSG_DATA(cmsg), &fd, sizeof(int)); | ||
|
||
return sendmsg(sockfd, &msg, 0); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#ifndef NSENTER_IPC_H | ||
#define NSENTER_IPC_H | ||
|
||
int receive_fd(int sockfd); | ||
|
||
/* | ||
* send_fd passes the open file descriptor fd to another process via the UNIX | ||
* domain socket sockfd. The return value of the sendmsg(2) call is returned. | ||
*/ | ||
int send_fd(int sockfd, int fd); | ||
|
||
#endif /* NSENTER_IPC_H */ |
Oops, something went wrong.