Skip to content

Commit 9266678

Browse files
committed
Merge branch 'master' into PiotrSikora/sec-003
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
2 parents 35ea3e3 + fa691f8 commit 9266678

9 files changed

+99
-16
lines changed

src/bytecode_util.cc

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,18 @@ bool BytecodeUtil::getAbiVersion(std::string_view bytecode, proxy_wasm::AbiVersi
4848
return false;
4949
}
5050
if (section_type == 7 /* export section */) {
51+
const char *section_end = pos + section_len;
5152
uint32_t export_vector_size = 0;
52-
if (!parseVarint(pos, end, export_vector_size) || pos + export_vector_size > end) {
53+
if (!parseVarint(pos, section_end, export_vector_size) ||
54+
pos + export_vector_size > section_end) {
5355
return false;
5456
}
5557
// Search thourgh exports.
5658
for (uint32_t i = 0; i < export_vector_size; i++) {
5759
// Parse name of the export.
5860
uint32_t export_name_size = 0;
59-
if (!parseVarint(pos, end, export_name_size) || pos + export_name_size > end) {
61+
if (!parseVarint(pos, section_end, export_name_size) ||
62+
pos + export_name_size > section_end) {
6063
return false;
6164
}
6265
const auto *const name_begin = pos;
@@ -65,7 +68,7 @@ bool BytecodeUtil::getAbiVersion(std::string_view bytecode, proxy_wasm::AbiVersi
6568
return false;
6669
}
6770
// Check if it is a function type export
68-
if (*pos++ == 0x00) {
71+
if (*pos++ == 0x00 /* function */) {
6972
const std::string export_name = {name_begin, export_name_size};
7073
// Check the name of the function.
7174
if (export_name == "proxy_abi_version_0_1_0") {
@@ -114,24 +117,25 @@ bool BytecodeUtil::getCustomSection(std::string_view bytecode, std::string_view
114117
}
115118
if (section_type == 0) {
116119
// Custom section.
117-
const auto *const section_data_start = pos;
120+
const char *section_end = pos + section_len;
118121
uint32_t section_name_len = 0;
119-
if (!BytecodeUtil::parseVarint(pos, end, section_name_len) || pos + section_name_len > end) {
122+
if (!BytecodeUtil::parseVarint(pos, section_end, section_name_len) ||
123+
pos + section_name_len > section_end) {
120124
return false;
121125
}
122126
if (section_name_len == name.size() && ::memcmp(pos, name.data(), section_name_len) == 0) {
123127
pos += section_name_len;
124-
ret = {pos, static_cast<size_t>(section_data_start + section_len - pos)};
128+
ret = {pos, static_cast<size_t>(section_end - pos)};
125129
return true;
126130
}
127-
pos = section_data_start + section_len;
131+
pos = section_end;
128132
} else {
129133
// Skip other sections.
130134
pos += section_len;
131135
}
132136
}
133137
return true;
134-
};
138+
}
135139

136140
bool BytecodeUtil::getFunctionNameIndex(std::string_view bytecode,
137141
std::unordered_map<uint32_t, std::string> &ret) {
@@ -242,16 +246,32 @@ bool BytecodeUtil::getStrippedSource(std::string_view bytecode, std::string &ret
242246

243247
bool BytecodeUtil::parseVarint(const char *&pos, const char *end, uint32_t &ret) {
244248
uint32_t shift = 0;
249+
uint32_t total = 0;
250+
uint32_t v;
245251
char b;
246-
do {
252+
while (pos < end) {
247253
if (pos + 1 > end) {
254+
// overread
248255
return false;
249256
}
250257
b = *pos++;
251-
ret += (b & 0x7f) << shift;
258+
v = (b & 0x7f);
259+
if (shift == 28 && v > 3) {
260+
// overflow
261+
return false;
262+
}
263+
total += v << shift;
264+
if ((b & 0x80) == 0) {
265+
ret = total;
266+
return true;
267+
}
252268
shift += 7;
253-
} while ((b & 0x80) != 0);
254-
return ret != static_cast<uint32_t>(-1);
269+
if (shift > 28) {
270+
// overflow
271+
return false;
272+
}
273+
}
274+
return false;
255275
}
256276

257277
} // namespace proxy_wasm

src/exports.cc

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -455,13 +455,21 @@ Word get_buffer_bytes(Word type, Word start, Word length, Word ptr_ptr, Word siz
455455
return WasmResult::BadArgument;
456456
}
457457
// Don't overread.
458-
if (start + length > buffer->size()) {
458+
if (start > buffer->size()) {
459+
length = 0;
460+
} else if (start + length > buffer->size()) {
459461
length = buffer->size() - start;
460462
}
461-
if (length > 0) {
462-
return buffer->copyTo(context->wasm(), start, length, ptr_ptr, size_ptr);
463+
if (length == 0) {
464+
if (!context->wasmVm()->setWord(ptr_ptr, Word(0))) {
465+
return WasmResult::InvalidMemoryAccess;
466+
}
467+
if (!context->wasmVm()->setWord(size_ptr, Word(0))) {
468+
return WasmResult::InvalidMemoryAccess;
469+
}
470+
return WasmResult::Ok;
463471
}
464-
return WasmResult::Ok;
472+
return buffer->copyTo(context->wasm(), start, length, ptr_ptr, size_ptr);
465473
}
466474

467475
Word get_buffer_status(Word type, Word length_ptr, Word flags_ptr) {

test/fuzz/BUILD

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,20 @@ licenses(["notice"]) # Apache 2
44

55
package(default_visibility = ["//visibility:public"])
66

7+
filegroup(
8+
name = "corpus_bytecode",
9+
srcs = glob(["corpus_bytecode/**"]),
10+
)
11+
12+
cc_fuzz_test(
13+
name = "bytecode_util_fuzzer",
14+
srcs = ["bytecode_util_fuzzer.cc"],
15+
corpus = [":corpus_bytecode"],
16+
deps = [
17+
"//:lib",
18+
],
19+
)
20+
721
filegroup(
822
name = "corpus_pairs",
923
srcs = glob(["corpus_pairs/**"]),

test/fuzz/bytecode_util_fuzzer.cc

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "include/proxy-wasm/bytecode_util.h"
16+
17+
#include <string>
18+
19+
namespace proxy_wasm {
20+
namespace {
21+
22+
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
23+
auto bytecode = std::string_view(reinterpret_cast<const char *>(data), size);
24+
25+
AbiVersion version;
26+
BytecodeUtil::getAbiVersion(bytecode, version);
27+
28+
std::string_view custom_section;
29+
BytecodeUtil::getCustomSection(bytecode, "precompiled", custom_section);
30+
31+
std::string stripped_source;
32+
BytecodeUtil::getStrippedSource(bytecode, stripped_source);
33+
34+
std::unordered_map<uint32_t, std::string> function_names;
35+
BytecodeUtil::getFunctionNameIndex(bytecode, function_names);
36+
37+
return 0;
38+
}
39+
40+
} // namespace
41+
} // namespace proxy_wasm
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)