Skip to content

Commit 4c30933

Browse files
author
Kim Barrett
committedJan 14, 2025
8346971: [ubsan] psCardTable.cpp:131:24: runtime error: large index is out of bounds
Reviewed-by: ayang, tschatzl
1 parent 06ff4c1 commit 4c30933

File tree

1 file changed

+35
-6
lines changed

1 file changed

+35
-6
lines changed
 

‎src/hotspot/share/gc/parallel/psCardTable.cpp

+35-6
Original file line numberDiff line numberDiff line change
@@ -122,13 +122,38 @@ class PSStripeShadowCardTable {
122122
const uint _card_shift;
123123
const uint _card_size;
124124
CardValue _table[PSCardTable::num_cards_in_stripe];
125-
const CardValue* _table_base;
125+
uintptr_t _table_base;
126+
127+
// Avoid UB pointer operations by using integers internally.
128+
129+
static_assert(sizeof(uintptr_t) == sizeof(CardValue*), "simplifying assumption");
130+
static_assert(sizeof(CardValue) == 1, "simplifying assumption");
131+
132+
static uintptr_t iaddr(const void* p) {
133+
return reinterpret_cast<uintptr_t>(p);
134+
}
135+
136+
uintptr_t compute_table_base(HeapWord* start) const {
137+
uintptr_t offset = iaddr(start) >> _card_shift;
138+
return iaddr(_table) - offset;
139+
}
140+
141+
void verify_card_inclusive(const CardValue* card) const {
142+
assert(iaddr(card) >= iaddr(_table), "out of bounds");
143+
assert(iaddr(card) <= (iaddr(_table) + sizeof(_table)), "out of bounds");
144+
}
145+
146+
void verify_card_exclusive(const CardValue* card) const {
147+
assert(iaddr(card) >= iaddr(_table), "out of bounds");
148+
assert(iaddr(card) < (iaddr(_table) + sizeof(_table)), "out of bounds");
149+
}
126150

127151
public:
128152
PSStripeShadowCardTable(PSCardTable* pst, HeapWord* const start, HeapWord* const end) :
129153
_card_shift(CardTable::card_shift()),
130154
_card_size(CardTable::card_size()),
131-
_table_base(_table - (uintptr_t(start) >> _card_shift)) {
155+
_table_base(compute_table_base(start))
156+
{
132157
size_t stripe_byte_size = pointer_delta(end, start) * HeapWordSize;
133158
size_t copy_length = align_up(stripe_byte_size, _card_size) >> _card_shift;
134159
// The end of the last stripe may not be card aligned as it is equal to old
@@ -143,20 +168,24 @@ class PSStripeShadowCardTable {
143168
}
144169

145170
HeapWord* addr_for(const CardValue* const card) {
146-
assert(card >= _table && card <= &_table[PSCardTable::num_cards_in_stripe], "out of bounds");
147-
return (HeapWord*) ((card - _table_base) << _card_shift);
171+
verify_card_inclusive(card);
172+
uintptr_t addr = (iaddr(card) - _table_base) << _card_shift;
173+
return reinterpret_cast<HeapWord*>(addr);
148174
}
149175

150176
const CardValue* card_for(HeapWord* addr) {
151-
return &_table_base[uintptr_t(addr) >> _card_shift];
177+
uintptr_t icard = _table_base + (iaddr(addr) >> _card_shift);
178+
const CardValue* card = reinterpret_cast<const CardValue*>(icard);
179+
verify_card_inclusive(card);
180+
return card;
152181
}
153182

154183
bool is_dirty(const CardValue* const card) {
155184
return !is_clean(card);
156185
}
157186

158187
bool is_clean(const CardValue* const card) {
159-
assert(card >= _table && card < &_table[PSCardTable::num_cards_in_stripe], "out of bounds");
188+
verify_card_exclusive(card);
160189
return *card == PSCardTable::clean_card_val();
161190
}
162191

0 commit comments

Comments
 (0)
Please sign in to comment.