diff options
author | Alon Zakai <azakai@google.com> | 2021-06-24 11:32:37 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-24 11:32:37 -0700 |
commit | 1b0d724fd5938931e6924941641dd8924ad49938 (patch) | |
tree | 704722f4c2d6785289e712b66957a33757dbb484 /src | |
parent | 21711ffea3cea19cab52bbd989a1c8638b3dd9a7 (diff) | |
download | binaryen-1b0d724fd5938931e6924941641dd8924ad49938.tar.gz binaryen-1b0d724fd5938931e6924941641dd8924ad49938.tar.bz2 binaryen-1b0d724fd5938931e6924941641dd8924ad49938.zip |
Handle invokes of invalid function pointers. See #14174 (#3951)
PostEmscripten will turn an invoke of a constant function
pointer index into a direct call. However, due to UB it is possible to
have invalid function pointers, and we should not crash on that
(and do nothing to optimize, of course).
Mostly whitespace; to avoid deep nesting, I added more
early returns.
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/PostEmscripten.cpp | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/src/passes/PostEmscripten.cpp b/src/passes/PostEmscripten.cpp index 403fb998b..f3ad35783 100644 --- a/src/passes/PostEmscripten.cpp +++ b/src/passes/PostEmscripten.cpp @@ -108,20 +108,32 @@ struct PostEmscripten : public Pass { void visitCall(Call* curr) { auto* target = getModule()->getFunction(curr->target); - if (isInvoke(target)) { - // The first operand is the function pointer index, which must be - // constant if we are to optimize it statically. - if (auto* index = curr->operands[0]->dynCast<Const>()) { - auto actualTarget = flatTable.names.at(index->value.geti32()); - if (!map[getModule()->getFunction(actualTarget)].canThrow) { - // This invoke cannot throw! Make it a direct call. - curr->target = actualTarget; - for (Index i = 0; i < curr->operands.size() - 1; i++) { - curr->operands[i] = curr->operands[i + 1]; - } - curr->operands.resize(curr->operands.size() - 1); - } + if (!isInvoke(target)) { + return; + } + // The first operand is the function pointer index, which must be + // constant if we are to optimize it statically. + if (auto* index = curr->operands[0]->dynCast<Const>()) { + size_t indexValue = index->value.geti32(); + if (indexValue >= flatTable.names.size()) { + // UB can lead to indirect calls to invalid pointers. + return; + } + auto actualTarget = flatTable.names[indexValue]; + if (actualTarget.isNull()) { + // UB can lead to an indirect call of 0 or an index in which there + // is no function name. + return; + } + if (map[getModule()->getFunction(actualTarget)].canThrow) { + return; + } + // This invoke cannot throw! Make it a direct call. + curr->target = actualTarget; + for (Index i = 0; i < curr->operands.size() - 1; i++) { + curr->operands[i] = curr->operands[i + 1]; } + curr->operands.resize(curr->operands.size() - 1); } } }; |