summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYossi Gottlieb <yossigo@gmail.com>2021-01-20 21:57:24 +0200
committerGitHub <noreply@github.com>2021-01-20 21:57:24 +0200
commitb548ffabbecca073e241882c22192f682a086242 (patch)
treef4a060c647062ea93175c782b8301a0d707ca28f
parentac5f21d613bf4a4883e767389ac5651a4118a5af (diff)
downloadredis-b548ffabbecca073e241882c22192f682a086242.tar.gz
CONFIG REWRITE should honor umask settings. (#8371)
Fixes a regression introduced due to a new (safer) way of rewriting configuration files. In the past the file was simply overwritten (same inode), but now Redis creates a new temporary file and later renames it over the old one. The temp file typically gets created with 0600 permissions so we later fchmod it to fix that. Unlike open with O_CREAT, fchmod doesn't consider umask so we have to do that explicitly. Fixes #8369
-rw-r--r--src/config.c2
-rw-r--r--src/server.c6
-rw-r--r--src/server.h1
3 files changed, 8 insertions, 1 deletions
diff --git a/src/config.c b/src/config.c
index 2442ace8e..2f9721f58 100644
--- a/src/config.c
+++ b/src/config.c
@@ -1683,7 +1683,7 @@ int rewriteConfigOverwriteFile(char *configfile, sds content) {
if (fsync(fd))
serverLog(LL_WARNING, "Could not sync tmp config file to disk (%s)", strerror(errno));
- else if (fchmod(fd, 0644) == -1)
+ else if (fchmod(fd, 0644 & ~server.umask) == -1)
serverLog(LL_WARNING, "Could not chmod config file (%s)", strerror(errno));
else if (rename(tmp_conffile, configfile) == -1)
serverLog(LL_WARNING, "Could not rename tmp config file (%s)", strerror(errno));
diff --git a/src/server.c b/src/server.c
index 1b8bc0c42..dc661b6e2 100644
--- a/src/server.c
+++ b/src/server.c
@@ -5753,6 +5753,12 @@ int main(int argc, char **argv) {
init_genrand64(((long long) tv.tv_sec * 1000000 + tv.tv_usec) ^ getpid());
crc64_init();
+ /* Store umask value. Because umask(2) only offers a set-and-get API we have
+ * to reset it and restore it back. We do this early to avoid a potential
+ * race condition with threads that could be creating files or directories.
+ */
+ umask(server.umask = umask(0777));
+
uint8_t hashseed[16];
getRandomBytes(hashseed,sizeof(hashseed));
dictSetHashFunctionSeed(hashseed);
diff --git a/src/server.h b/src/server.h
index 0de7b3a1e..13144ce32 100644
--- a/src/server.h
+++ b/src/server.h
@@ -1124,6 +1124,7 @@ struct redisServer {
int config_hz; /* Configured HZ value. May be different than
the actual 'hz' field value if dynamic-hz
is enabled. */
+ mode_t umask; /* The umask value of the process on startup */
int hz; /* serverCron() calls frequency in hertz */
int in_fork_child; /* indication that this is a fork child */
redisDb *db;