aboutsummaryrefslogtreecommitdiff
path: root/contrib/amcheck/verify_heapam.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/amcheck/verify_heapam.c')
-rw-r--r--contrib/amcheck/verify_heapam.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index e84ecd1c981..774a70f63df 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -30,6 +30,9 @@ PG_FUNCTION_INFO_V1(verify_heapam);
/* The number of columns in tuples returned by verify_heapam */
#define HEAPCHECK_RELATION_COLS 4
+/* The largest valid toast va_rawsize */
+#define VARLENA_SIZE_LIMIT 0x3FFFFFFF
+
/*
* Despite the name, we use this for reporting problems with both XIDs and
* MXIDs.
@@ -1414,6 +1417,49 @@ check_tuple_attribute(HeapCheckContext *ctx)
*/
VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr);
+ /* Toasted attributes too large to be untoasted should never be stored */
+ if (toast_pointer.va_rawsize > VARLENA_SIZE_LIMIT)
+ report_corruption(ctx,
+ psprintf("toast value %u rawsize %u exceeds limit %u",
+ toast_pointer.va_valueid,
+ toast_pointer.va_rawsize,
+ VARLENA_SIZE_LIMIT));
+
+ if (VARATT_IS_COMPRESSED(&toast_pointer))
+ {
+ ToastCompressionId cmid;
+ bool valid = false;
+
+ /* Compression should never expand the attribute */
+ if (VARATT_EXTERNAL_GET_EXTSIZE(toast_pointer) > toast_pointer.va_rawsize - VARHDRSZ)
+ report_corruption(ctx,
+ psprintf("toast value %u external size %u exceeds maximum expected for rawsize %u",
+ toast_pointer.va_valueid,
+ VARATT_EXTERNAL_GET_EXTSIZE(toast_pointer),
+ toast_pointer.va_rawsize));
+
+ /* Compressed attributes should have a valid compression method */
+ cmid = TOAST_COMPRESS_METHOD(&toast_pointer);
+ switch (cmid)
+ {
+ /* List of all valid compression method IDs */
+ case TOAST_PGLZ_COMPRESSION_ID:
+ case TOAST_LZ4_COMPRESSION_ID:
+ valid = true;
+ break;
+
+ /* Recognized but invalid compression method ID */
+ case TOAST_INVALID_COMPRESSION_ID:
+ break;
+
+ /* Intentionally no default here */
+ }
+ if (!valid)
+ report_corruption(ctx,
+ psprintf("toast value %u has invalid compression method id %d",
+ toast_pointer.va_valueid, cmid));
+ }
+
/* The tuple header better claim to contain toasted values */
if (!(infomask & HEAP_HASEXTERNAL))
{