mirror of
https://github.com/postgres/postgres.git
synced 2025-12-18 05:01:01 +03:00
Add offnum range checks to suppress compile warnings with UBSAN.
Late-model gcc with -fsanitize=undefined enabled issues warnings about uses of PageGetItemId() when it can't prove that the offsetNumber is > 0. The call sites where this happens are checking that the offnum is <= PageGetMaxOffsetNumber(page), so it seems reasonable to add an explicit check that offnum >= 1 too. While at it, rearrange the code to be less contorted and avoid duplicate checks on PageGetMaxOffsetNumber. Maybe the compiler would optimize away the duplicate logic or maybe not, but the existing coding has little to recommend it anyway. There are multiple instances of this identical coding pattern in heapam.c and heapam_xlog.c. Current gcc only complains about two of them, but I fixed them all in the name of consistency. Potentially this could be back-patched in the name of silencing warnings; but I think enabling UBSAN is mainly something people would do on HEAD, so for now it seems not worth the trouble. Discussion: https://postgr.es/m/1699806.1765746897@sss.pgh.pa.us
This commit is contained in:
@@ -6116,7 +6116,7 @@ heap_finish_speculative(Relation relation, const ItemPointerData *tid)
|
||||
Buffer buffer;
|
||||
Page page;
|
||||
OffsetNumber offnum;
|
||||
ItemId lp = NULL;
|
||||
ItemId lp;
|
||||
HeapTupleHeader htup;
|
||||
|
||||
buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
|
||||
@@ -6124,10 +6124,10 @@ heap_finish_speculative(Relation relation, const ItemPointerData *tid)
|
||||
page = BufferGetPage(buffer);
|
||||
|
||||
offnum = ItemPointerGetOffsetNumber(tid);
|
||||
if (PageGetMaxOffsetNumber(page) >= offnum)
|
||||
if (offnum < 1 || offnum > PageGetMaxOffsetNumber(page))
|
||||
elog(ERROR, "offnum out of range");
|
||||
lp = PageGetItemId(page, offnum);
|
||||
|
||||
if (PageGetMaxOffsetNumber(page) < offnum || !ItemIdIsNormal(lp))
|
||||
if (!ItemIdIsNormal(lp))
|
||||
elog(ERROR, "invalid lp");
|
||||
|
||||
htup = (HeapTupleHeader) PageGetItem(page, lp);
|
||||
|
||||
@@ -422,7 +422,7 @@ heap_xlog_delete(XLogReaderState *record)
|
||||
xl_heap_delete *xlrec = (xl_heap_delete *) XLogRecGetData(record);
|
||||
Buffer buffer;
|
||||
Page page;
|
||||
ItemId lp = NULL;
|
||||
ItemId lp;
|
||||
HeapTupleHeader htup;
|
||||
BlockNumber blkno;
|
||||
RelFileLocator target_locator;
|
||||
@@ -451,10 +451,10 @@ heap_xlog_delete(XLogReaderState *record)
|
||||
{
|
||||
page = BufferGetPage(buffer);
|
||||
|
||||
if (PageGetMaxOffsetNumber(page) >= xlrec->offnum)
|
||||
if (xlrec->offnum < 1 || xlrec->offnum > PageGetMaxOffsetNumber(page))
|
||||
elog(PANIC, "offnum out of range");
|
||||
lp = PageGetItemId(page, xlrec->offnum);
|
||||
|
||||
if (PageGetMaxOffsetNumber(page) < xlrec->offnum || !ItemIdIsNormal(lp))
|
||||
if (!ItemIdIsNormal(lp))
|
||||
elog(PANIC, "invalid lp");
|
||||
|
||||
htup = (HeapTupleHeader) PageGetItem(page, lp);
|
||||
@@ -817,7 +817,7 @@ heap_xlog_update(XLogReaderState *record, bool hot_update)
|
||||
nbuffer;
|
||||
Page page;
|
||||
OffsetNumber offnum;
|
||||
ItemId lp = NULL;
|
||||
ItemId lp;
|
||||
HeapTupleData oldtup;
|
||||
HeapTupleHeader htup;
|
||||
uint16 prefixlen = 0,
|
||||
@@ -881,10 +881,10 @@ heap_xlog_update(XLogReaderState *record, bool hot_update)
|
||||
{
|
||||
page = BufferGetPage(obuffer);
|
||||
offnum = xlrec->old_offnum;
|
||||
if (PageGetMaxOffsetNumber(page) >= offnum)
|
||||
if (offnum < 1 || offnum > PageGetMaxOffsetNumber(page))
|
||||
elog(PANIC, "offnum out of range");
|
||||
lp = PageGetItemId(page, offnum);
|
||||
|
||||
if (PageGetMaxOffsetNumber(page) < offnum || !ItemIdIsNormal(lp))
|
||||
if (!ItemIdIsNormal(lp))
|
||||
elog(PANIC, "invalid lp");
|
||||
|
||||
htup = (HeapTupleHeader) PageGetItem(page, lp);
|
||||
@@ -1087,7 +1087,7 @@ heap_xlog_confirm(XLogReaderState *record)
|
||||
Buffer buffer;
|
||||
Page page;
|
||||
OffsetNumber offnum;
|
||||
ItemId lp = NULL;
|
||||
ItemId lp;
|
||||
HeapTupleHeader htup;
|
||||
|
||||
if (XLogReadBufferForRedo(record, 0, &buffer) == BLK_NEEDS_REDO)
|
||||
@@ -1095,10 +1095,10 @@ heap_xlog_confirm(XLogReaderState *record)
|
||||
page = BufferGetPage(buffer);
|
||||
|
||||
offnum = xlrec->offnum;
|
||||
if (PageGetMaxOffsetNumber(page) >= offnum)
|
||||
if (offnum < 1 || offnum > PageGetMaxOffsetNumber(page))
|
||||
elog(PANIC, "offnum out of range");
|
||||
lp = PageGetItemId(page, offnum);
|
||||
|
||||
if (PageGetMaxOffsetNumber(page) < offnum || !ItemIdIsNormal(lp))
|
||||
if (!ItemIdIsNormal(lp))
|
||||
elog(PANIC, "invalid lp");
|
||||
|
||||
htup = (HeapTupleHeader) PageGetItem(page, lp);
|
||||
@@ -1126,7 +1126,7 @@ heap_xlog_lock(XLogReaderState *record)
|
||||
Buffer buffer;
|
||||
Page page;
|
||||
OffsetNumber offnum;
|
||||
ItemId lp = NULL;
|
||||
ItemId lp;
|
||||
HeapTupleHeader htup;
|
||||
|
||||
/*
|
||||
@@ -1155,10 +1155,10 @@ heap_xlog_lock(XLogReaderState *record)
|
||||
page = BufferGetPage(buffer);
|
||||
|
||||
offnum = xlrec->offnum;
|
||||
if (PageGetMaxOffsetNumber(page) >= offnum)
|
||||
if (offnum < 1 || offnum > PageGetMaxOffsetNumber(page))
|
||||
elog(PANIC, "offnum out of range");
|
||||
lp = PageGetItemId(page, offnum);
|
||||
|
||||
if (PageGetMaxOffsetNumber(page) < offnum || !ItemIdIsNormal(lp))
|
||||
if (!ItemIdIsNormal(lp))
|
||||
elog(PANIC, "invalid lp");
|
||||
|
||||
htup = (HeapTupleHeader) PageGetItem(page, lp);
|
||||
@@ -1200,7 +1200,7 @@ heap_xlog_lock_updated(XLogReaderState *record)
|
||||
Buffer buffer;
|
||||
Page page;
|
||||
OffsetNumber offnum;
|
||||
ItemId lp = NULL;
|
||||
ItemId lp;
|
||||
HeapTupleHeader htup;
|
||||
|
||||
xlrec = (xl_heap_lock_updated *) XLogRecGetData(record);
|
||||
@@ -1231,10 +1231,10 @@ heap_xlog_lock_updated(XLogReaderState *record)
|
||||
page = BufferGetPage(buffer);
|
||||
|
||||
offnum = xlrec->offnum;
|
||||
if (PageGetMaxOffsetNumber(page) >= offnum)
|
||||
if (offnum < 1 || offnum > PageGetMaxOffsetNumber(page))
|
||||
elog(PANIC, "offnum out of range");
|
||||
lp = PageGetItemId(page, offnum);
|
||||
|
||||
if (PageGetMaxOffsetNumber(page) < offnum || !ItemIdIsNormal(lp))
|
||||
if (!ItemIdIsNormal(lp))
|
||||
elog(PANIC, "invalid lp");
|
||||
|
||||
htup = (HeapTupleHeader) PageGetItem(page, lp);
|
||||
@@ -1263,7 +1263,7 @@ heap_xlog_inplace(XLogReaderState *record)
|
||||
Buffer buffer;
|
||||
Page page;
|
||||
OffsetNumber offnum;
|
||||
ItemId lp = NULL;
|
||||
ItemId lp;
|
||||
HeapTupleHeader htup;
|
||||
uint32 oldlen;
|
||||
Size newlen;
|
||||
@@ -1275,10 +1275,10 @@ heap_xlog_inplace(XLogReaderState *record)
|
||||
page = BufferGetPage(buffer);
|
||||
|
||||
offnum = xlrec->offnum;
|
||||
if (PageGetMaxOffsetNumber(page) >= offnum)
|
||||
if (offnum < 1 || offnum > PageGetMaxOffsetNumber(page))
|
||||
elog(PANIC, "offnum out of range");
|
||||
lp = PageGetItemId(page, offnum);
|
||||
|
||||
if (PageGetMaxOffsetNumber(page) < offnum || !ItemIdIsNormal(lp))
|
||||
if (!ItemIdIsNormal(lp))
|
||||
elog(PANIC, "invalid lp");
|
||||
|
||||
htup = (HeapTupleHeader) PageGetItem(page, lp);
|
||||
|
||||
@@ -2148,6 +2148,9 @@ _bt_get_endpoint(Relation rel, uint32 level, bool rightmost)
|
||||
else
|
||||
offnum = P_FIRSTDATAKEY(opaque);
|
||||
|
||||
if (offnum < 1 || offnum > PageGetMaxOffsetNumber(page))
|
||||
elog(PANIC, "offnum out of range");
|
||||
|
||||
itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum));
|
||||
blkno = BTreeTupleGetDownLink(itup);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user