-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WebAssembly] Limit increase of Ctx.End #76676
base: main
Are you sure you want to change the base?
Conversation
Extending `Ctx.End` beyond the original buffer leads to buffer overflows. This limits extending Ctx.End beyond OrigEnd to prevent these overflows. Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65432 Signed-off-by: David Korczynski <david@adalogics.com>
@llvm/pr-subscribers-llvm-binary-utilities @llvm/pr-subscribers-backend-webassembly Author: None (DavidKorczynski) ChangesExtending Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65432 Full diff: https://github.com/llvm/llvm-project/pull/76676.diff 1 Files Affected:
diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp
index 40665d686cf939..6f89e183118d63 100644
--- a/llvm/lib/Object/WasmObjectFile.cpp
+++ b/llvm/lib/Object/WasmObjectFile.cpp
@@ -546,6 +546,9 @@ Error WasmObjectFile::parseLinkingSection(ReadContext &Ctx) {
uint32_t Size = readVaruint32(Ctx);
LLVM_DEBUG(dbgs() << "readSubsection type=" << int(Type) << " size=" << Size
<< "\n");
+ if ((const uint8_t *)(Ctx.Ptr + Size) > OrigEnd)
+ return make_error<GenericBinaryError>("invalid segment size",
+ object_error::parse_failed);
Ctx.End = Ctx.Ptr + Size;
switch (Type) {
case wasm::WASM_SYMBOL_TABLE:
|
Test coverage? |
Signed-off-by: David Korczynski <david@adalogics.com>
Added a regression test -- this approach of embedding the fuzz data in the test works well for small cases but may become tricky when the fuzz data gets large (tens of KBs) |
This looks good to me in general. |
0x02, 0xea, 0x06, 0xf9, 0xee, 0x28, 0xe1, 0x2b, 0x2f, 0x09, 0x00, 0xef, | ||
0xbf, 0xbf, 0x00, 0x00, 0xdd, 0x73, 0x66, 0x83, 0x7b, 0x00, 0x55}; | ||
|
||
std::string Payload(reinterpret_cast<const char *>(data), 47); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps use sizeof(data) to avoid the magic number here?
Expected<std::unique_ptr<ObjectFile>> ObjOrErr = | ||
ObjectFile::createObjectFile(Buff->getMemBufferRef()); | ||
if (auto E = ObjOrErr.takeError()) { | ||
consumeError(std::move(E)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we expect a particular error here, perhaps we can check for the details in the error to ensure we're diagnosing this correctly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure tbh -- the test is a copy of the parts of the fuzzer that is needed to trigger the overflow: https://github.com/llvm/llvm-project/blob/main/llvm/tools/llvm-dwarfdump/fuzzer/llvm-dwarfdump-fuzzer.cpp
I'm not sure which is best. Our existing tests for this kind of thing currently live in
One nice think about checking in the binaries is that its easy to read and modify them. For example, I could take |
I think its probably best to add this new test alongside the existing |
Am not sure what the status is on this one in terms of testing: are we keeping the unit test or? if not, I can add the reproducer testcase linked to in https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65432 to the directory mentioned by @sbc100 -- however, I suspect many fuzzers won't have a given binary in a similar way to just add the fuzzer files? Does it perhaps make more sense to create a folder next to the fuzzer with the testcases that has produced errors in the past? This would at least be more general from a fuzzing perspective. |
I like the test, but I'd prefer binaries to be checked in as separate files. I'm not a fan a direct fuzzer outputs being checked in unless we can't find a way to reduce to something small/understandable (such as the one in this case). |
OSS-Fuzz minimizes the input and the input added here is the fuzzer input as minimized by OSS-Fuzz. Similarly the minimized input produced by OSS-Fuzz in #77708 is 25 bytes and the one in #77698 is 132 bytes |
Those both sounds fine to checkin then. In general, If possible, I'd think still prefer to have them named something meaningful (and possibly reduced even more) once the root causes is established. |
a2880ea
to
eb8a47d
Compare
Signed-off-by: David Korczynski <david@adalogics.com>
I added the trigger file and adjusted the I likely won't have cycles to reduce it even further or similar just because I know little of the LLVM code -- I'm coming from the fuzz world and know my way around e.g. https://github.com/google/oss-fuzz , but am not well-versed in the details of LLVMs codebase. Am happy to monitor the LLVM's OSS-Fuzz set up to ensure it's running proper and submit fixes for the issues (which happens in various parts of the codebase) I can handle (i.e. with the limited knowledge of the codebase), but I don't have cycles to go much further than that unfortunately. |
Not that it necessarily needs to block this PR, but: |
To a large extent I'm coming from the angle of an issue was reported by OSS-Fuzz so I added a fix. I assume once this bug is fixed the fuzzer will quickly report others. I'm not sure about the threat model, but for what it's worth the majority of issues I previously fixed from this fuzzer occurred in WasmObjectFile.cpp as opposed to the other files in |
Extending
Ctx.End
beyond the original buffer leads to buffer overflows. This limits extending Ctx.End beyond OrigEnd to prevent these overflows.Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65432