mirror of
https://github.com/postgres/postgres.git
synced 2025-06-16 06:01:02 +03:00
Add defenses against running with a wrong selection of LOBLKSIZE.
It's critical that the backend's idea of LOBLKSIZE match the way data has actually been divided up in pg_largeobject. While we don't provide any direct way to adjust that value, doing so is a one-line source code change and various people have expressed interest recently in changing it. So, just as with TOAST_MAX_CHUNK_SIZE, it seems prudent to record the value in pg_control and cross-check that the backend's compiled-in setting matches the on-disk data. Also tweak the code in inv_api.c so that fetches from pg_largeobject explicitly verify that the length of the data field is not more than LOBLKSIZE. Formerly we just had Asserts() for that, which is no protection at all in production builds. In some of the call sites an overlength data value would translate directly to a security-relevant stack clobber, so it seems worth one extra runtime comparison to be sure. In the back branches, we can't change the contents of pg_control; but we can still make the extra checks in inv_api.c, which will offer some amount of protection against running with the wrong value of LOBLKSIZE.
This commit is contained in:
@ -49,6 +49,7 @@
|
||||
#include "storage/bufmgr.h"
|
||||
#include "storage/fd.h"
|
||||
#include "storage/ipc.h"
|
||||
#include "storage/large_object.h"
|
||||
#include "storage/latch.h"
|
||||
#include "storage/pmsignal.h"
|
||||
#include "storage/predicate.h"
|
||||
@ -4352,6 +4353,7 @@ WriteControlFile(void)
|
||||
ControlFile->indexMaxKeys = INDEX_MAX_KEYS;
|
||||
|
||||
ControlFile->toast_max_chunk_size = TOAST_MAX_CHUNK_SIZE;
|
||||
ControlFile->loblksize = LOBLKSIZE;
|
||||
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
ControlFile->enableIntTimes = true;
|
||||
@ -4545,6 +4547,13 @@ ReadControlFile(void)
|
||||
" but the server was compiled with TOAST_MAX_CHUNK_SIZE %d.",
|
||||
ControlFile->toast_max_chunk_size, (int) TOAST_MAX_CHUNK_SIZE),
|
||||
errhint("It looks like you need to recompile or initdb.")));
|
||||
if (ControlFile->loblksize != LOBLKSIZE)
|
||||
ereport(FATAL,
|
||||
(errmsg("database files are incompatible with server"),
|
||||
errdetail("The database cluster was initialized with LOBLKSIZE %d,"
|
||||
" but the server was compiled with LOBLKSIZE %d.",
|
||||
ControlFile->loblksize, (int) LOBLKSIZE),
|
||||
errhint("It looks like you need to recompile or initdb.")));
|
||||
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
if (ControlFile->enableIntTimes != true)
|
||||
|
Reference in New Issue
Block a user