Bug 1130672 - ARM assembler: Check oom() before using editSrc(). r=jandem

The editSrc() function returns a pointer into the assembly buffer. This
may not be a valid pointer if the assembly buffer ran out of memory.

Harden AssemblerBuffer::getInst() by adding assertions. Since invalid
uses of getInst() may be security bugs, use MOZ_RELEASE_ASSERT for the
range check.
This commit is contained in:
Jakob Olesen 2015-10-08 11:41:42 +05:30
Родитель 2f9c01a010
Коммит 996f1627b4
2 изменённых файлов: 12 добавлений и 5 удалений

Просмотреть файл

@ -2816,6 +2816,9 @@ Assembler::bind(Label* label, BufferOffset boff)
BufferOffset dest = boff.assigned() ? boff : nextOffset();
BufferOffset b(label);
do {
// Even a 0 offset may be invalid if we're out of memory.
if (oom())
return;
BufferOffset next;
more = nextLink(b, &next);
Instruction branch = *editSrc(b);
@ -2839,7 +2842,7 @@ Assembler::bind(RepatchLabel* label)
// disassembly, as the value that is bound to the label is often
// effectively garbage and is replaced by something else later.
BufferOffset dest = nextOffset();
if (label->used()) {
if (label->used() && !oom()) {
// If the label has a use, then change this use to refer to the bound
// label.
BufferOffset branchOff(label->offset());
@ -2864,7 +2867,7 @@ Assembler::retarget(Label* label, Label* target)
#ifdef JS_DISASM_ARM
spewRetarget(label, target);
#endif
if (label->used()) {
if (label->used() && !oom()) {
if (target->bound()) {
bind(label, BufferOffset(target));
} else if (target->used()) {

Просмотреть файл

@ -246,7 +246,7 @@ class AssemblerBuffer
slicesSkipped++;
}
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Invalid instruction cursor.");
MOZ_CRASH("Invalid instruction cursor.");
}
Inst* getInstBackwards(BufferOffset off, Slice* start, int startOffset, bool updateFinger = false) {
@ -275,7 +275,7 @@ class AssemblerBuffer
slicesSkipped++;
}
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Invalid instruction cursor.");
MOZ_CRASH("Invalid instruction cursor.");
}
public:
@ -285,8 +285,11 @@ class AssemblerBuffer
return getInst(off);
}
// Get a pointer to the instruction at offset |off| which must be within the
// bounds of the buffer. Use |getInstOrNull()| if |off| may be unassigned.
Inst* getInst(BufferOffset off) {
const int offset = off.getOffset();
MOZ_RELEASE_ASSERT(off.assigned() && offset >= 0 && (unsigned)offset < size());
// Is the instruction in the last slice?
if (offset >= int(bufferSize))
@ -306,7 +309,8 @@ class AssemblerBuffer
if (offset < int(bufferSize - offset))
return getInstForwards(off, head, 0);
// The last slice was already checked above, so start at the second-to-last.
// The last slice was already checked above, so start at the
// second-to-last.
Slice* prev = tail->getPrev();
return getInstBackwards(off, prev, bufferSize - prev->length());
}