Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite976fd4

Browse files
committed
Add some simple defenses against null fields in pg_largeobject, and add
comments noting that there's an alignment assumption now that the datafield could be in 1-byte-header format. Per discussion with Greg Stark.
1 parentee0d34a commite976fd4

File tree

1 file changed

+20
-5
lines changed

1 file changed

+20
-5
lines changed

‎src/backend/storage/large_object/inv_api.c

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
* contains the user-level large object application interface routines.
66
*
77
*
8+
* Note: we access pg_largeobject.data using its C struct declaration.
9+
* This is safe because it immediately follows pageno which is an int4 field,
10+
* and therefore the data field will always be 4-byte aligned, even if it
11+
* is in the short 1-byte-header format. We have to detoast it since it's
12+
* quite likely to be in compressed or short format. We also need to check
13+
* for NULLs, since initdb will mark loid and pageno but not data as NOT NULL.
14+
*
815
* Note: many of these routines leak memory in CurrentMemoryContext, as indeed
916
* does most of the backend code. We expect that CurrentMemoryContext will
1017
* be a short-lived context. Data that must persist across function calls
@@ -17,7 +24,7 @@
1724
*
1825
*
1926
* IDENTIFICATION
20-
* $PostgreSQL: pgsql/src/backend/storage/large_object/inv_api.c,v 1.124 2007/04/06 04:21:42 tgl Exp $
27+
* $PostgreSQL: pgsql/src/backend/storage/large_object/inv_api.c,v 1.125 2007/06/12 19:46:24 tgl Exp $
2128
*
2229
*-------------------------------------------------------------------------
2330
*/
@@ -330,8 +337,10 @@ inv_getsize(LargeObjectDesc *obj_desc)
330337
boolpfreeit;
331338

332339
found= true;
340+
if (HeapTupleHasNulls(tuple))/* paranoia */
341+
elog(ERROR,"null field found in pg_largeobject");
333342
data= (Form_pg_largeobject)GETSTRUCT(tuple);
334-
datafield=&(data->data);
343+
datafield=&(data->data);/* see note at top of file */
335344
pfreeit= false;
336345
if (VARATT_IS_EXTENDED(datafield))
337346
{
@@ -434,6 +443,8 @@ inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
434443
bytea*datafield;
435444
boolpfreeit;
436445

446+
if (HeapTupleHasNulls(tuple))/* paranoia */
447+
elog(ERROR,"null field found in pg_largeobject");
437448
data= (Form_pg_largeobject)GETSTRUCT(tuple);
438449

439450
/*
@@ -457,7 +468,7 @@ inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
457468
off= (int) (obj_desc->offset-pageoff);
458469
Assert(off >=0&&off<LOBLKSIZE);
459470

460-
datafield=&(data->data);
471+
datafield=&(data->data);/* see note at top of file */
461472
pfreeit= false;
462473
if (VARATT_IS_EXTENDED(datafield))
463474
{
@@ -558,6 +569,8 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
558569
{
559570
if ((oldtuple=index_getnext(sd,ForwardScanDirection))!=NULL)
560571
{
572+
if (HeapTupleHasNulls(oldtuple))/* paranoia */
573+
elog(ERROR,"null field found in pg_largeobject");
561574
olddata= (Form_pg_largeobject)GETSTRUCT(oldtuple);
562575
Assert(olddata->pageno >=pageno);
563576
}
@@ -575,7 +588,7 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
575588
*
576589
* First, load old data into workbuf
577590
*/
578-
datafield=&(olddata->data);
591+
datafield=&(olddata->data);/* see note at top of file */
579592
pfreeit= false;
580593
if (VARATT_IS_EXTENDED(datafield))
581594
{
@@ -737,6 +750,8 @@ inv_truncate(LargeObjectDesc *obj_desc, int len)
737750
olddata=NULL;
738751
if ((oldtuple=index_getnext(sd,ForwardScanDirection))!=NULL)
739752
{
753+
if (HeapTupleHasNulls(oldtuple))/* paranoia */
754+
elog(ERROR,"null field found in pg_largeobject");
740755
olddata= (Form_pg_largeobject)GETSTRUCT(oldtuple);
741756
Assert(olddata->pageno >=pageno);
742757
}
@@ -749,7 +764,7 @@ inv_truncate(LargeObjectDesc *obj_desc, int len)
749764
if (olddata!=NULL&&olddata->pageno==pageno)
750765
{
751766
/* First, load old data into workbuf */
752-
bytea*datafield=&(olddata->data);
767+
bytea*datafield=&(olddata->data);/* see note at top of file */
753768
boolpfreeit= false;
754769
intpagelen;
755770

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp