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

Commitfd49e8f

Browse files
committed
Prevent access of uninitialized memory in radix tree nodes
RT_NODE_16_SEARCH_EQ() performs comparisions using vector registerson x64-64 and aarch64. We apply a mask to the resulting bitfieldto eliminate irrelevant bits that may be set. This ensures correctbehavior, but Valgrind complains of the partially-uninitialisedvalues. So far the warnings have only occurred on aarch64, whichexplains why this hasn't been seen earlier.To fix this warning, initialize the whole fixed-sized part of the nodesupon allocation, rather than just do the minimum initialization tofunction correctly. The initialization for node48 is a bit differentin that the 256-byte slot index array must be populated with "invalidindex" rather than zero. Experimentation has shown that compilerstend to emit code that uselessly memsets that array twice. To avoidpessimizing this path, swap the order of the slot_idxs[] and isset[]arrays so we can initialize with two non-overlapping memset calls.Reported by Tomas VondraAnalysis and patch by Tom Lane, reviewed by Masahiko Sawada. Iinvestigated the behavior of memset calls to overlapping regions,leading to the above tweaks to node48 as discussed in the thread.Discussion:https://postgr.es/m/120c63ad-3d12-415f-a7bf-3da451c31bf6%40enterprisedb.com
1 parentc5c8212 commitfd49e8f

File tree

1 file changed

+14
-12
lines changed

1 file changed

+14
-12
lines changed

‎src/include/lib/radixtree.h

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -541,15 +541,19 @@ typedef struct RT_NODE_48
541541
{
542542
RT_NODEbase;
543543

544-
/* The index of slots for each fanout */
544+
/* bitmap to track which slots are in use */
545+
bitmapwordisset[RT_BM_IDX(RT_FANOUT_48_MAX)];
546+
547+
/*
548+
* Lookup table for indexes into the children[] array. We make this the
549+
* last fixed-size member so that it's convenient to memset separately
550+
* from the previous members.
551+
*/
545552
uint8slot_idxs[RT_NODE_MAX_SLOTS];
546553

547554
/* Invalid index */
548555
#defineRT_INVALID_SLOT_IDX0xFF
549556

550-
/* bitmap to track which slots are in use */
551-
bitmapwordisset[RT_BM_IDX(RT_FANOUT_48_MAX)];
552-
553557
/* number of children depends on size class */
554558
RT_PTR_ALLOCchildren[FLEXIBLE_ARRAY_MEMBER];
555559
}RT_NODE_48;
@@ -845,27 +849,25 @@ RT_ALLOC_NODE(RT_RADIX_TREE * tree, const uint8 kind, const RT_SIZE_CLASS size_c
845849

846850
/* initialize contents */
847851

848-
memset(node,0,sizeof(RT_NODE));
849852
switch (kind)
850853
{
851854
caseRT_NODE_KIND_4:
855+
memset(node,0, offsetof(RT_NODE_4,children));
856+
break;
852857
caseRT_NODE_KIND_16:
858+
memset(node,0, offsetof(RT_NODE_16,children));
853859
break;
854860
caseRT_NODE_KIND_48:
855861
{
856862
RT_NODE_48*n48= (RT_NODE_48*)node;
857863

858-
memset(n48->isset,0,sizeof(n48->isset));
864+
memset(n48,0,offsetof(RT_NODE_48,slot_idxs));
859865
memset(n48->slot_idxs,RT_INVALID_SLOT_IDX,sizeof(n48->slot_idxs));
860866
break;
861867
}
862868
caseRT_NODE_KIND_256:
863-
{
864-
RT_NODE_256*n256= (RT_NODE_256*)node;
865-
866-
memset(n256->isset,0,sizeof(n256->isset));
867-
break;
868-
}
869+
memset(node,0, offsetof(RT_NODE_256,children));
870+
break;
869871
default:
870872
pg_unreachable();
871873
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp