From b548ffabbecca073e241882c22192f682a086242 Mon Sep 17 00:00:00 2001 From: Yossi Gottlieb Date: Wed, 20 Jan 2021 21:57:24 +0200 Subject: [PATCH] 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 --- src/config.c | 2 +- src/server.c | 6 ++++++ src/server.h | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) 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;