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

Commit5265e91

Browse files
committed
Make MemoryContextContains work correctly again
c6e0fe1 recently changed the way we store headers for allocated chunksof memory. Prior to that commit, we stored a pointer to the owningMemoryContext directly prior to the pointer to the allocated memory.That's no longer true andc6e0fe1 neglected to updateMemoryContextContains() so that it correctly obtains the owning contextwith the new method.A side effect of this change andc6e0fe1, in general, is that it's evenless safe than it was previously to pass MemoryContextContains() anarbitrary pointer which was not allocated by one of our MemoryContexts.Previously some comments in MemoryContextContains() seemed to indicatethat the worst that could happen by passing an arbitrary pointer would bea false positive return value. It seems to me that this was a ratherwishful outlook as we subsequently proceeded to subtract sizeof(void *)from the given pointer and then dereferenced that memory. So it seemsquite likely that we could have segfaulted instead of returning a falsepositive. However, it's not impossible that the memory sizeof(void *)bytes before the pointer could have been owned by the process, but it'sfar less likely to work now as obtaining a pointer to the owningMemoryContext is less direct than beforec6e0fe1 and will access memorythat's possibly much further away to obtain the owning MemoryContext.Because of this, I took the liberty of updating the comment to warnagainst any future usages of the function and checked the existing coreusages to ensure that we only ever pass in a pointer to memory allocatedby a MemoryContext.Extension authors updating their code for PG16 who are usingMemoryContextContains should check to ensure that only NULL pointers andpointers to chunks allocated with a MemoryContext will ever be passed toMemoryContextContains.Reported-by: Andres FreundDiscussion:https://postgr.es/m/20220905230949.kb3x2fkpfwtngz43@awork3.anarazel.de
1 parent3fe76ab commit5265e91

File tree

1 file changed

+36
-9
lines changed

1 file changed

+36
-9
lines changed

‎src/backend/utils/mmgr/mcxt.c‎

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,15 @@ MemoryContextAllowInCriticalSection(MemoryContext context, bool allow)
482482
MemoryContext
483483
GetMemoryChunkContext(void*pointer)
484484
{
485+
/*
486+
* Try to detect bogus pointers handed to us, poorly though we can.
487+
* Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
488+
* allocated chunk.
489+
*/
490+
Assert(pointer!=NULL);
491+
Assert(pointer== (void*)MAXALIGN(pointer));
492+
/* adding further Asserts here? See pre-checks in MemoryContextContains */
493+
485494
returnMCXT_METHOD(pointer,get_chunk_context) (pointer);
486495
}
487496

@@ -809,21 +818,19 @@ MemoryContextCheck(MemoryContext context)
809818
*Detect whether an allocated chunk of memory belongs to a given
810819
*context or not.
811820
*
812-
* Caution: this test is reliable as long as 'pointer' does point to
813-
* a chunk of memory allocated from *some* context. If 'pointer' points
814-
* at memory obtained in some other way, there is a small chance of a
815-
* false-positive result, since the bits right before it might look like
816-
* a valid chunk header by chance.
821+
* Caution: 'pointer' must point to a pointer which was allocated by a
822+
* MemoryContext. It's not safe or valid to use this function on arbitrary
823+
* pointers as obtaining the MemoryContext which 'pointer' belongs to requires
824+
* possibly several pointer dereferences.
817825
*/
818826
bool
819827
MemoryContextContains(MemoryContextcontext,void*pointer)
820828
{
821829
MemoryContextptr_context;
822830

823831
/*
824-
* NB: Can't use GetMemoryChunkContext() here - that performs assertions
825-
* that aren't acceptable here since we might be passed memory not
826-
* allocated by any memory context.
832+
* NB: We must perform run-time checks here which GetMemoryChunkContext()
833+
* does as assertions before calling GetMemoryChunkContext().
827834
*
828835
* Try to detect bogus pointers handed to us, poorly though we can.
829836
* Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
@@ -835,7 +842,7 @@ MemoryContextContains(MemoryContext context, void *pointer)
835842
/*
836843
* OK, it's probably safe to look at the context.
837844
*/
838-
ptr_context=*(MemoryContext*) (((char*)pointer)-sizeof(void*));
845+
ptr_context=GetMemoryChunkContext(pointer);
839846

840847
returnptr_context==context;
841848
}
@@ -953,6 +960,8 @@ MemoryContextAlloc(MemoryContext context, Size size)
953960

954961
VALGRIND_MEMPOOL_ALLOC(context,ret,size);
955962

963+
Assert(MemoryContextContains(context,ret));
964+
956965
returnret;
957966
}
958967

@@ -991,6 +1000,8 @@ MemoryContextAllocZero(MemoryContext context, Size size)
9911000

9921001
MemSetAligned(ret,0,size);
9931002

1003+
Assert(MemoryContextContains(context,ret));
1004+
9941005
returnret;
9951006
}
9961007

@@ -1029,6 +1040,8 @@ MemoryContextAllocZeroAligned(MemoryContext context, Size size)
10291040

10301041
MemSetLoop(ret,0,size);
10311042

1043+
Assert(MemoryContextContains(context,ret));
1044+
10321045
returnret;
10331046
}
10341047

@@ -1070,6 +1083,8 @@ MemoryContextAllocExtended(MemoryContext context, Size size, int flags)
10701083
if ((flags&MCXT_ALLOC_ZERO)!=0)
10711084
MemSetAligned(ret,0,size);
10721085

1086+
Assert(MemoryContextContains(context,ret));
1087+
10731088
returnret;
10741089
}
10751090

@@ -1153,6 +1168,8 @@ palloc(Size size)
11531168

11541169
VALGRIND_MEMPOOL_ALLOC(context,ret,size);
11551170

1171+
Assert(MemoryContextContains(context,ret));
1172+
11561173
returnret;
11571174
}
11581175

@@ -1186,6 +1203,8 @@ palloc0(Size size)
11861203

11871204
MemSetAligned(ret,0,size);
11881205

1206+
Assert(MemoryContextContains(context,ret));
1207+
11891208
returnret;
11901209
}
11911210

@@ -1225,6 +1244,8 @@ palloc_extended(Size size, int flags)
12251244
if ((flags&MCXT_ALLOC_ZERO)!=0)
12261245
MemSetAligned(ret,0,size);
12271246

1247+
Assert(MemoryContextContains(context,ret));
1248+
12281249
returnret;
12291250
}
12301251

@@ -1278,6 +1299,8 @@ repalloc(void *pointer, Size size)
12781299

12791300
VALGRIND_MEMPOOL_CHANGE(context,pointer,ret,size);
12801301

1302+
Assert(MemoryContextContains(context,ret));
1303+
12811304
returnret;
12821305
}
12831306

@@ -1313,6 +1336,8 @@ MemoryContextAllocHuge(MemoryContext context, Size size)
13131336

13141337
VALGRIND_MEMPOOL_ALLOC(context,ret,size);
13151338

1339+
Assert(MemoryContextContains(context,ret));
1340+
13161341
returnret;
13171342
}
13181343

@@ -1352,6 +1377,8 @@ repalloc_huge(void *pointer, Size size)
13521377

13531378
VALGRIND_MEMPOOL_CHANGE(context,pointer,ret,size);
13541379

1380+
Assert(MemoryContextContains(context,ret));
1381+
13551382
returnret;
13561383
}
13571384

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp