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

Commit99e74cd

Browse files
committed
Fix erroneous Valgrind markings in AllocSetRealloc.
If asked to decrease the size of a large (>8K) palloc chunk,AllocSetRealloc could improperly change the Valgrind state of memorybeyond the new end of the chunk: it would mark data UNDEFINED as faras the old end of the chunk after having done the realloc(3) call,thus tromping on the state of memory that no longer belongs to it.One would normally expect that memory to now be marked NOACCESS,so that this mislabeling might prevent detection of later errors.If realloc() had chosen to move the chunk someplace else (unlikely,but well within its rights) we could also mismark perfectly-validDEFINED data as UNDEFINED, causing false-positive valgrind reportslater. Also, any malloc bookkeeping data placed within this areamight now be wrongly marked, causing additional problems.Fix by replacing relevant uses of "oldsize" with "Min(size, oldsize)".It's sufficient to mark as far as "size" when that's smaller, becausewhatever remains in the new chunk size will be marked NOACCESS below,and we expect realloc() to have taken care of marking the memorybeyond the new official end of the chunk.While we're here, also rename the function's "oldsize" variableto "oldchksize" to more clearly explain what it actually holds,namely the distance to the end of the chunk (that is, requested sizeplus trailing padding). This is more consistent with the use of"size" and "chksize" to hold the new requested size and chunk size.Add a new variable "oldsize" in the one stanza where we're actuallytalking about the old requested size.Oversight in commitc477f3e. Back-patch to all supported branches,as that was, just in case anybody wants to do valgrind testing on backbranches.Karina LitskevichDiscussion:https://postgr.es/m/CACiT8iaAET-fmzjjZLjaJC4zwSJmrFyL7LAdHwaYyjjQOQ4hcg@mail.gmail.com
1 parent4efb4f0 commit99e74cd

File tree

1 file changed

+33
-20
lines changed

1 file changed

+33
-20
lines changed

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

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,22 +1075,22 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
10751075
{
10761076
AllocSetset= (AllocSet)context;
10771077
AllocChunkchunk=AllocPointerGetChunk(pointer);
1078-
Sizeoldsize;
1078+
Sizeoldchksize;
10791079

10801080
/* Allow access to private part of chunk header. */
10811081
VALGRIND_MAKE_MEM_DEFINED(chunk,ALLOCCHUNK_PRIVATE_LEN);
10821082

1083-
oldsize=chunk->size;
1083+
oldchksize=chunk->size;
10841084

10851085
#ifdefMEMORY_CONTEXT_CHECKING
10861086
/* Test for someone scribbling on unused space in chunk */
1087-
if (chunk->requested_size<oldsize)
1087+
if (chunk->requested_size<oldchksize)
10881088
if (!sentinel_ok(pointer,chunk->requested_size))
10891089
elog(WARNING,"detected write past chunk end in %s %p",
10901090
set->header.name,chunk);
10911091
#endif
10921092

1093-
if (oldsize>set->allocChunkLimit)
1093+
if (oldchksize>set->allocChunkLimit)
10941094
{
10951095
/*
10961096
* The chunk must have been allocated as a single-chunk block. Use
@@ -1110,7 +1110,7 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
11101110
if (block->aset!=set||
11111111
block->freeptr!=block->endptr||
11121112
block->freeptr!= ((char*)block)+
1113-
(oldsize+ALLOC_BLOCKHDRSZ+ALLOC_CHUNKHDRSZ))
1113+
(oldchksize+ALLOC_BLOCKHDRSZ+ALLOC_CHUNKHDRSZ))
11141114
elog(ERROR,"could not find block containing chunk %p",chunk);
11151115

11161116
/*
@@ -1153,21 +1153,29 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
11531153

11541154
#ifdefMEMORY_CONTEXT_CHECKING
11551155
#ifdefRANDOMIZE_ALLOCATED_MEMORY
1156-
/* We can only fill the extra space if we know the prior request */
1156+
1157+
/*
1158+
* We can only randomize the extra space if we know the prior request.
1159+
* When using Valgrind, randomize_mem() also marks memory UNDEFINED.
1160+
*/
11571161
if (size>chunk->requested_size)
11581162
randomize_mem((char*)pointer+chunk->requested_size,
11591163
size-chunk->requested_size);
1160-
#endif
1164+
#else
11611165

11621166
/*
1163-
* realloc() (or randomize_mem()) will have left any newly-allocated
1164-
* part UNDEFINED, but we may need to adjust trailing bytes from the
1165-
* old allocation.
1167+
* If this is an increase, realloc() will have marked any
1168+
* newly-allocated part (from oldchksize to chksize) UNDEFINED, but we
1169+
* also need to adjust trailing bytes from the old allocation (from
1170+
* chunk->requested_size to oldchksize) as they are marked NOACCESS.
1171+
* Make sure not to mark too many bytes in case chunk->requested_size
1172+
* < size < oldchksize.
11661173
*/
11671174
#ifdefUSE_VALGRIND
1168-
if (oldsize>chunk->requested_size)
1175+
if (Min(size,oldchksize)>chunk->requested_size)
11691176
VALGRIND_MAKE_MEM_UNDEFINED((char*)pointer+chunk->requested_size,
1170-
oldsize-chunk->requested_size);
1177+
Min(size,oldchksize)-chunk->requested_size);
1178+
#endif
11711179
#endif
11721180

11731181
chunk->requested_size=size;
@@ -1178,11 +1186,14 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
11781186
#else/* !MEMORY_CONTEXT_CHECKING */
11791187

11801188
/*
1181-
* We don't know how much of the old chunk size was the actual
1182-
* allocation; it could have been as small as one byte. We have to be
1183-
* conservative and just mark the entire old portion DEFINED.
1189+
* We may need to adjust marking of bytes from the old allocation as
1190+
* some of them may be marked NOACCESS. We don't know how much of the
1191+
* old chunk size was the requested size; it could have been as small
1192+
* as one byte. We have to be conservative and just mark the entire
1193+
* old portion DEFINED. Make sure not to mark memory beyond the new
1194+
* allocation in case it's smaller than the old one.
11841195
*/
1185-
VALGRIND_MAKE_MEM_DEFINED(pointer,oldsize);
1196+
VALGRIND_MAKE_MEM_DEFINED(pointer,Min(size,oldchksize));
11861197
#endif
11871198

11881199
/* Ensure any padding bytes are marked NOACCESS. */
@@ -1199,7 +1210,7 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
11991210
* allocated area already is >= the new size. (In particular, we will
12001211
* fall out here if the requested size is a decrease.)
12011212
*/
1202-
elseif (oldsize >=size)
1213+
elseif (oldchksize >=size)
12031214
{
12041215
#ifdefMEMORY_CONTEXT_CHECKING
12051216
Sizeoldrequest=chunk->requested_size;
@@ -1222,10 +1233,10 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
12221233
size-oldrequest);
12231234
else
12241235
VALGRIND_MAKE_MEM_NOACCESS((char*)pointer+size,
1225-
oldsize-size);
1236+
oldchksize-size);
12261237

12271238
/* set mark to catch clobber of "unused" space */
1228-
if (size<oldsize)
1239+
if (size<oldchksize)
12291240
set_sentinel(pointer,size);
12301241
#else/* !MEMORY_CONTEXT_CHECKING */
12311242

@@ -1234,7 +1245,7 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
12341245
* the old request or shrinking it, so we conservatively mark the
12351246
* entire new allocation DEFINED.
12361247
*/
1237-
VALGRIND_MAKE_MEM_NOACCESS(pointer,oldsize);
1248+
VALGRIND_MAKE_MEM_NOACCESS(pointer,oldchksize);
12381249
VALGRIND_MAKE_MEM_DEFINED(pointer,size);
12391250
#endif
12401251

@@ -1257,6 +1268,7 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
12571268
* memory indefinitely. See pgsql-hackers archives for 2007-08-11.)
12581269
*/
12591270
AllocPointernewPointer;
1271+
Sizeoldsize;
12601272

12611273
/* allocate new chunk */
12621274
newPointer=AllocSetAlloc((MemoryContext)set,size);
@@ -1281,6 +1293,7 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
12811293
#ifdefMEMORY_CONTEXT_CHECKING
12821294
oldsize=chunk->requested_size;
12831295
#else
1296+
oldsize=oldchksize;
12841297
VALGRIND_MAKE_MEM_DEFINED(pointer,oldsize);
12851298
#endif
12861299

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp