summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Munro2023-10-15 21:43:47 +0000
committerThomas Munro2023-10-15 21:43:47 +0000
commitc558e6fd92ffeb85d5f52e32ccbcf8a5b5eb7bf3 (patch)
tree831c52b55350e691f1eea16447a80ed7ba92d98e
parent5f27b5f848a433ba54c521ccb889788b8f4d6ba7 (diff)
Acquire ControlFileLock in relevant SQL functions.
Commit dc7d70ea added functions that read the control file, but didn't acquire ControlFileLock. With unlucky timing, file systems that have weak interlocking like ext4 and ntfs could expose partially overwritten contents, and the checksum would fail. Back-patch to all supported releases. Reviewed-by: David Steele <[email protected]> Reviewed-by: Anton A. Melnikov <[email protected]> Reviewed-by: Michael Paquier <[email protected]> Discussion: https://postgr.es/m/20221123014224.xisi44byq3cf5psi%40awork3.anarazel.de
-rw-r--r--src/backend/utils/misc/pg_controldata.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/src/backend/utils/misc/pg_controldata.c b/src/backend/utils/misc/pg_controldata.c
index f2c1084797b..a1003a464dc 100644
--- a/src/backend/utils/misc/pg_controldata.c
+++ b/src/backend/utils/misc/pg_controldata.c
@@ -24,6 +24,7 @@
#include "common/controldata_utils.h"
#include "funcapi.h"
#include "miscadmin.h"
+#include "storage/lwlock.h"
#include "utils/builtins.h"
#include "utils/pg_lsn.h"
#include "utils/timestamp.h"
@@ -42,7 +43,9 @@ pg_control_system(PG_FUNCTION_ARGS)
elog(ERROR, "return type must be a row type");
/* read the control file */
+ LWLockAcquire(ControlFileLock, LW_SHARED);
ControlFile = get_controlfile(DataDir, &crc_ok);
+ LWLockRelease(ControlFileLock);
if (!crc_ok)
ereport(ERROR,
(errmsg("calculated CRC checksum does not match value stored in file")));
@@ -80,7 +83,9 @@ pg_control_checkpoint(PG_FUNCTION_ARGS)
elog(ERROR, "return type must be a row type");
/* Read the control file. */
+ LWLockAcquire(ControlFileLock, LW_SHARED);
ControlFile = get_controlfile(DataDir, &crc_ok);
+ LWLockRelease(ControlFileLock);
if (!crc_ok)
ereport(ERROR,
(errmsg("calculated CRC checksum does not match value stored in file")));
@@ -169,7 +174,9 @@ pg_control_recovery(PG_FUNCTION_ARGS)
elog(ERROR, "return type must be a row type");
/* read the control file */
+ LWLockAcquire(ControlFileLock, LW_SHARED);
ControlFile = get_controlfile(DataDir, &crc_ok);
+ LWLockRelease(ControlFileLock);
if (!crc_ok)
ereport(ERROR,
(errmsg("calculated CRC checksum does not match value stored in file")));
@@ -208,7 +215,9 @@ pg_control_init(PG_FUNCTION_ARGS)
elog(ERROR, "return type must be a row type");
/* read the control file */
+ LWLockAcquire(ControlFileLock, LW_SHARED);
ControlFile = get_controlfile(DataDir, &crc_ok);
+ LWLockRelease(ControlFileLock);
if (!crc_ok)
ereport(ERROR,
(errmsg("calculated CRC checksum does not match value stored in file")));