Title: [98268] trunk/Source/_javascript_Core
- Revision
- 98268
- Author
- [email protected]
- Date
- 2011-10-24 12:41:29 -0700 (Mon, 24 Oct 2011)
Log Message
BitVector isInline check could fail
https://bugs.webkit.org/show_bug.cgi?id=70691
Patch by Yuqiang Xian <[email protected]> on 2011-10-24
Reviewed by Geoffrey Garen.
Current BitVector uses the highest bit of m_bitsOrPointer to indicate
whether it's an inlined bit set or a pointer to an outOfLine bit set.
This check may fail in case the pointer also has the highest bit set,
which is surely possible on IA32 (Linux).
In this case the check failure can result in unexpected behaviors,
for example if the BitVector is incorrectly determined as having an
inlined bit set, then setting a bit exceeding maxInlineBits will wrongly
modify the memory adjacent to the BitVector object.
This fix is to use the lowest bit of m_bitsOrPointer to indicate inline
or outofline, based on the assumption that the pointer to OutOfLineBits
should be 4 or 8 byte aligned.
We could mark the lowest bit (bit 0) with 1 for inlined bit set,
and bits 1~bitsInPointer are used for bit set/test.
In this case we need do one bit more shift for bit set/test.
* wtf/BitVector.cpp:
(WTF::BitVector::resizeOutOfLine):
* wtf/BitVector.h:
(WTF::BitVector::quickGet):
(WTF::BitVector::quickSet):
(WTF::BitVector::quickClear):
(WTF::BitVector::makeInlineBits):
(WTF::BitVector::isInline):
Modified Paths
Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (98267 => 98268)
--- trunk/Source/_javascript_Core/ChangeLog 2011-10-24 19:40:54 UTC (rev 98267)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-10-24 19:41:29 UTC (rev 98268)
@@ -1,3 +1,34 @@
+2011-10-24 Yuqiang Xian <[email protected]>
+
+ BitVector isInline check could fail
+ https://bugs.webkit.org/show_bug.cgi?id=70691
+
+ Reviewed by Geoffrey Garen.
+
+ Current BitVector uses the highest bit of m_bitsOrPointer to indicate
+ whether it's an inlined bit set or a pointer to an outOfLine bit set.
+ This check may fail in case the pointer also has the highest bit set,
+ which is surely possible on IA32 (Linux).
+ In this case the check failure can result in unexpected behaviors,
+ for example if the BitVector is incorrectly determined as having an
+ inlined bit set, then setting a bit exceeding maxInlineBits will wrongly
+ modify the memory adjacent to the BitVector object.
+ This fix is to use the lowest bit of m_bitsOrPointer to indicate inline
+ or outofline, based on the assumption that the pointer to OutOfLineBits
+ should be 4 or 8 byte aligned.
+ We could mark the lowest bit (bit 0) with 1 for inlined bit set,
+ and bits 1~bitsInPointer are used for bit set/test.
+ In this case we need do one bit more shift for bit set/test.
+
+ * wtf/BitVector.cpp:
+ (WTF::BitVector::resizeOutOfLine):
+ * wtf/BitVector.h:
+ (WTF::BitVector::quickGet):
+ (WTF::BitVector::quickSet):
+ (WTF::BitVector::quickClear):
+ (WTF::BitVector::makeInlineBits):
+ (WTF::BitVector::isInline):
+
2011-10-24 Mark Hahnenberg <[email protected]>
Rename static getOwnPropertySlot to getOwnPropertySlotByIndex
Modified: trunk/Source/_javascript_Core/wtf/BitVector.cpp (98267 => 98268)
--- trunk/Source/_javascript_Core/wtf/BitVector.cpp 2011-10-24 19:40:54 UTC (rev 98267)
+++ trunk/Source/_javascript_Core/wtf/BitVector.cpp 2011-10-24 19:41:29 UTC (rev 98268)
@@ -91,7 +91,7 @@
OutOfLineBits* newOutOfLineBits = OutOfLineBits::create(numBits);
if (isInline()) {
// Make sure that all of the bits are zero in case we do a no-op resize.
- *newOutOfLineBits->bits() = m_bitsOrPointer & ~(static_cast<uintptr_t>(1) << maxInlineBits());
+ *newOutOfLineBits->bits() = m_bitsOrPointer & ~(static_cast<uintptr_t>(1));
} else {
if (numBits > size()) {
size_t oldNumWords = outOfLineBits()->numWords();
@@ -103,6 +103,7 @@
OutOfLineBits::destroy(outOfLineBits());
}
m_bitsOrPointer = bitwise_cast<uintptr_t>(newOutOfLineBits);
+ ASSERT(!isInline());
}
#ifndef NDEBUG
Modified: trunk/Source/_javascript_Core/wtf/BitVector.h (98267 => 98268)
--- trunk/Source/_javascript_Core/wtf/BitVector.h 2011-10-24 19:40:54 UTC (rev 98267)
+++ trunk/Source/_javascript_Core/wtf/BitVector.h 2011-10-24 19:41:29 UTC (rev 98268)
@@ -114,19 +114,19 @@
bool quickGet(size_t bit) const
{
ASSERT(bit < size());
- return !!(bits()[bit / bitsInPointer()] & (static_cast<uintptr_t>(1) << (bit & (bitsInPointer() - 1))));
+ return !!(bits()[bit / bitsInPointer()] & (static_cast<uintptr_t>(1) << ((bit & (bitsInPointer() - 1)) + 1)));
}
void quickSet(size_t bit)
{
ASSERT(bit < size());
- bits()[bit / bitsInPointer()] |= (static_cast<uintptr_t>(1) << (bit & (bitsInPointer() - 1)));
+ bits()[bit / bitsInPointer()] |= (static_cast<uintptr_t>(1) << ((bit & (bitsInPointer() - 1)) + 1));
}
void quickClear(size_t bit)
{
ASSERT(bit < size());
- bits()[bit / bitsInPointer()] &= ~(static_cast<uintptr_t>(1) << (bit & (bitsInPointer() - 1)));
+ bits()[bit / bitsInPointer()] &= ~(static_cast<uintptr_t>(1) << ((bit & (bitsInPointer() - 1)) + 1));
}
void quickSet(size_t bit, bool value)
@@ -187,8 +187,8 @@
static uintptr_t makeInlineBits(uintptr_t bits)
{
- ASSERT(!(bits & (static_cast<uintptr_t>(1) << maxInlineBits())));
- return bits | (static_cast<uintptr_t>(1) << maxInlineBits());
+ ASSERT(!(bits & static_cast<uintptr_t>(1)));
+ return bits | static_cast<uintptr_t>(1);
}
class OutOfLineBits {
@@ -211,7 +211,7 @@
size_t m_numBits;
};
- bool isInline() const { return m_bitsOrPointer >> maxInlineBits(); }
+ bool isInline() const { return m_bitsOrPointer & static_cast<uintptr_t>(1); }
const OutOfLineBits* outOfLineBits() const { return bitwise_cast<const OutOfLineBits*>(m_bitsOrPointer); }
OutOfLineBits* outOfLineBits() { return bitwise_cast<OutOfLineBits*>(m_bitsOrPointer); }
@@ -232,7 +232,10 @@
return &m_bitsOrPointer;
return outOfLineBits()->bits();
}
-
+
+ // The low bit of m_bitsOrPointer is a flag indicating whether this field is
+ // inline bits or a pointer to out of line bits. If the flag is set, the field
+ // is inline bits. This works because the low bit in a pointer is always unset.
uintptr_t m_bitsOrPointer;
};
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes