0001-_bt_restore_page-have-issues-can-lead-a-memory-corru.patch
application/octet-stream
Filename: 0001-_bt_restore_page-have-issues-can-lead-a-memory-corru.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch 0001
Subject: _bt_restore_page have issues can lead a memory corrupt, when recovery tries restore index tuples to a page.
| File | + | − |
|---|---|---|
| src/backend/access/nbtree/nbtxlog.c | 10 | 7 |
From f965132abc3520f06dbfc8d5f89222cf00728e00 Mon Sep 17 00:00:00 2001
From: Ranier Vilela <ranier.vf@gmail.com>
Date: Sun, 11 Jul 2021 16:17:50 -0300
Subject: [PATCH] _bt_restore_page have issues can lead a memory corrupt, when
recovery tries restore index tuples to a page.
First the maximum index tuples per page varies that system to system.
at Windows 64 bits, the MaxIndexTuplesPerPage is 408.
The int *len* parameter allows 268.435.455 index tuples per page.
2.147.483.647 / sizeof(IndexTupleData) = 268.435.455 /* IndexTupleData size is 8 bytes */
So if _bt_restore_page tries restore a file corrupted or maliciously created,
can write after array bounds.
Fix by checking and raising a error PANIC in this case.
Another issue is that _bt_restore_page can increment the pointer *from*,
to after bounds that can point.
Fix by removing the unnecessary increment.
While there, reduce scope of two variables.
Author: Ranier Vilela (ranier.vf@gmail.com)
---
src/backend/access/nbtree/nbtxlog.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/src/backend/access/nbtree/nbtxlog.c b/src/backend/access/nbtree/nbtxlog.c
index c2e920f159..8fe80bc8ff 100644
--- a/src/backend/access/nbtree/nbtxlog.c
+++ b/src/backend/access/nbtree/nbtxlog.c
@@ -35,16 +35,19 @@ static MemoryContext opCtx; /* working memory for operations */
* the one with highest item number appears first (lowest on the page).
*/
static void
-_bt_restore_page(Page page, char *from, int len)
+_bt_restore_page(Page page, char *from, Size len)
{
- IndexTupleData itupdata;
- Size itemsz;
- char *end = from + len;
+ const char *end = from + len;
Item items[MaxIndexTuplesPerPage];
uint16 itemsizes[MaxIndexTuplesPerPage];
int i;
int nitems;
+ /* Protect against corrupted recovery file */
+ nitems = (len / sizeof(IndexTupleData));
+ if (nitems < 0 || nitems > MaxIndexTuplesPerPage)
+ elog(PANIC, "_bt_restore_page: cannot restore %d items to page", nitems);
+
/*
* To get the items back in the original order, we add them to the page in
* reverse. To figure out where one tuple ends and another begins, we
@@ -53,6 +56,9 @@ _bt_restore_page(Page page, char *from, int len)
i = 0;
while (from < end)
{
+ IndexTupleData itupdata;
+ Size itemsz;
+
/*
* As we step through the items, 'from' won't always be properly
* aligned, so we need to use memcpy(). Further, we use Item (which
@@ -73,12 +79,9 @@ _bt_restore_page(Page page, char *from, int len)
nitems = i;
for (i = nitems - 1; i >= 0; i--)
- {
if (PageAddItem(page, items[i], itemsizes[i], nitems - i,
false, false) == InvalidOffsetNumber)
elog(PANIC, "_bt_restore_page: cannot add item to page");
- from += itemsz;
- }
}
static void
--
2.32.0.windows.1