summaryrefslogtreecommitdiff
path: root/src/anet.c
diff options
context:
space:
mode:
authorAndy Pan <panjf2000@gmail.com>2021-01-20 04:57:30 +0800
committerGitHub <noreply@github.com>2021-01-19 22:57:30 +0200
commitfb66e2e24943018961321d13e46ee2ab66de882a (patch)
tree04075a8d909bc1eba249ecb1aaf1b4705fc84823 /src/anet.c
parentaaf71b380ed5ef8d5d63f8a60733c35202c5b838 (diff)
downloadredis-fb66e2e24943018961321d13e46ee2ab66de882a.tar.gz
Use FD_CLOEXEC in Sentinel, so that FDs don't leak to the scripts it runs (#8242)
Sentinel uses execve to run scripts, so it needs to use FD_CLOEXEC on all file descriptors, so that they're not accessible by the script it runs. This commit includes a change to the sentinel tests, which verifies no FDs are left opened when the script is executed.
Diffstat (limited to 'src/anet.c')
-rw-r--r--src/anet.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/anet.c b/src/anet.c
index 4e2e6be88..f2c39b200 100644
--- a/src/anet.c
+++ b/src/anet.c
@@ -94,6 +94,29 @@ int anetBlock(char *err, int fd) {
return anetSetBlock(err,fd,0);
}
+/* Enable the FD_CLOEXEC on the given fd to avoid fd leaks.
+ * This function should be invoked for fd's on specific places
+ * where fork + execve system calls are called. */
+int anetCloexec(int fd) {
+ int r;
+ int flags;
+
+ do {
+ r = fcntl(fd, F_GETFD);
+ } while (r == -1 && errno == EINTR);
+
+ if (r == -1 || (r & FD_CLOEXEC))
+ return r;
+
+ flags = r | FD_CLOEXEC;
+
+ do {
+ r = fcntl(fd, F_SETFD, flags);
+ } while (r == -1 && errno == EINTR);
+
+ return r;
+}
+
/* Set TCP keep alive option to detect dead peers. The interval option
* is only used for Linux as we are using Linux-specific APIs to set
* the probe send time, interval, and count. */