summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Munro <tmunro@postgresql.org>2023-10-16 10:43:47 +1300
committerThomas Munro <tmunro@postgresql.org>2023-10-16 10:45:05 +1300
commit2371432cd6b93415ef99e7ef35598f4f85436163 (patch)
tree6b12b015a913a4df797d54cd9920ee337dabd75a /src
parentbf1c21c4fad033414a99d6205118fbc4d75efa62 (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 <david@pgmasters.net> Reviewed-by: Anton A. Melnikov <aamelnikov@inbox.ru> Reviewed-by: Michael Paquier <michael@paquier.xyz> Discussion: https://postgr.es/m/20221123014224.xisi44byq3cf5psi%40awork3.anarazel.de
Diffstat (limited to 'src')
-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")));