Skip to content

Commit 82dd719

Browse files
committed
rpc: Write authcookie atomically
Use POSIX rename atomicity at the `bitcoind` side to create a working cookie atomically: - Write `.cookie.tmp`, close file - Rename `.cookie.tmp` to `.cookie` This avoids clients reading invalid/partial cookies as in #11129.
1 parent 3f726c9 commit 82dd719

File tree

2 files changed

+16
-7
lines changed

2 files changed

+16
-7
lines changed

src/rpc/protocol.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,14 @@ static const std::string COOKIEAUTH_USER = "__cookie__";
6666
/** Default name for auth cookie file */
6767
static const std::string COOKIEAUTH_FILE = ".cookie";
6868

69-
fs::path GetAuthCookieFile()
69+
/** Get name of RPC authentication cookie file */
70+
static fs::path GetAuthCookieFile(bool temp=false)
7071
{
71-
fs::path path(gArgs.GetArg("-rpccookiefile", COOKIEAUTH_FILE));
72+
std::string arg = gArgs.GetArg("-rpccookiefile", COOKIEAUTH_FILE);
73+
if (temp) {
74+
arg += ".tmp";
75+
}
76+
fs::path path(arg);
7277
if (!path.is_complete()) path = GetDataDir() / path;
7378
return path;
7479
}
@@ -84,14 +89,20 @@ bool GenerateAuthCookie(std::string *cookie_out)
8489
* these are set to 077 in init.cpp unless overridden with -sysperms.
8590
*/
8691
std::ofstream file;
87-
fs::path filepath = GetAuthCookieFile();
88-
file.open(filepath.string().c_str());
92+
fs::path filepath_tmp = GetAuthCookieFile(true);
93+
file.open(filepath_tmp.string().c_str());
8994
if (!file.is_open()) {
90-
LogPrintf("Unable to open cookie authentication file %s for writing\n", filepath.string());
95+
LogPrintf("Unable to open cookie authentication file %s for writing\n", filepath_tmp.string());
9196
return false;
9297
}
9398
file << cookie;
9499
file.close();
100+
101+
fs::path filepath = GetAuthCookieFile(false);
102+
if (!RenameOver(filepath_tmp, filepath)) {
103+
LogPrintf("Unable to rename cookie authentication file %s to %s\n", filepath_tmp.string(), filepath.string());
104+
return false;
105+
}
95106
LogPrintf("Generated RPC authentication cookie %s\n", filepath.string());
96107

97108
if (cookie_out)

src/rpc/protocol.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,6 @@ UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const Un
9191
std::string JSONRPCReply(const UniValue& result, const UniValue& error, const UniValue& id);
9292
UniValue JSONRPCError(int code, const std::string& message);
9393

94-
/** Get name of RPC authentication cookie file */
95-
fs::path GetAuthCookieFile();
9694
/** Generate a new RPC authentication cookie and write it to disk */
9795
bool GenerateAuthCookie(std::string *cookie_out);
9896
/** Read the RPC authentication cookie from disk */

0 commit comments

Comments
 (0)