summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2021-06-24 11:32:37 -0700
committerGitHub <noreply@github.com>2021-06-24 11:32:37 -0700
commit1b0d724fd5938931e6924941641dd8924ad49938 (patch)
tree704722f4c2d6785289e712b66957a33757dbb484 /src
parent21711ffea3cea19cab52bbd989a1c8638b3dd9a7 (diff)
downloadbinaryen-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.cpp38
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);
}
}
};