Skip to content

Commit c558e6f

Browse files
committed
Acquire ControlFileLock in relevant SQL functions.
Commit dc7d70e 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
1 parent 5f27b5f commit c558e6f

File tree

1 file changed

+9
-0
lines changed

1 file changed

+9
-0
lines changed

src/backend/utils/misc/pg_controldata.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "common/controldata_utils.h"
2525
#include "funcapi.h"
2626
#include "miscadmin.h"
27+
#include "storage/lwlock.h"
2728
#include "utils/builtins.h"
2829
#include "utils/pg_lsn.h"
2930
#include "utils/timestamp.h"
@@ -42,7 +43,9 @@ pg_control_system(PG_FUNCTION_ARGS)
4243
elog(ERROR, "return type must be a row type");
4344

4445
/* read the control file */
46+
LWLockAcquire(ControlFileLock, LW_SHARED);
4547
ControlFile = get_controlfile(DataDir, &crc_ok);
48+
LWLockRelease(ControlFileLock);
4649
if (!crc_ok)
4750
ereport(ERROR,
4851
(errmsg("calculated CRC checksum does not match value stored in file")));
@@ -80,7 +83,9 @@ pg_control_checkpoint(PG_FUNCTION_ARGS)
8083
elog(ERROR, "return type must be a row type");
8184

8285
/* Read the control file. */
86+
LWLockAcquire(ControlFileLock, LW_SHARED);
8387
ControlFile = get_controlfile(DataDir, &crc_ok);
88+
LWLockRelease(ControlFileLock);
8489
if (!crc_ok)
8590
ereport(ERROR,
8691
(errmsg("calculated CRC checksum does not match value stored in file")));
@@ -169,7 +174,9 @@ pg_control_recovery(PG_FUNCTION_ARGS)
169174
elog(ERROR, "return type must be a row type");
170175

171176
/* read the control file */
177+
LWLockAcquire(ControlFileLock, LW_SHARED);
172178
ControlFile = get_controlfile(DataDir, &crc_ok);
179+
LWLockRelease(ControlFileLock);
173180
if (!crc_ok)
174181
ereport(ERROR,
175182
(errmsg("calculated CRC checksum does not match value stored in file")));
@@ -208,7 +215,9 @@ pg_control_init(PG_FUNCTION_ARGS)
208215
elog(ERROR, "return type must be a row type");
209216

210217
/* read the control file */
218+
LWLockAcquire(ControlFileLock, LW_SHARED);
211219
ControlFile = get_controlfile(DataDir, &crc_ok);
220+
LWLockRelease(ControlFileLock);
212221
if (!crc_ok)
213222
ereport(ERROR,
214223
(errmsg("calculated CRC checksum does not match value stored in file")));

0 commit comments

Comments
 (0)