-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
AddressSanitizer: stack-overflow in regex_executor.tcc #1264
Comments
@pietroborrello, thanks for the report. Does this problem only happen with the commit 696239d? |
Thank you for your reply. That is the commit I tested the fuzzer on, not sure on master, but it is really a recent commit |
@pietroborrello, your log shows that the problem is happening at |
Hello, I confirm the issue seems to reproduce on the current master. Line 5500 in 1be1b3a
|
@pietroborrello, I was trying to reproduce this problem on my machine, but I couldn't... What I did was to copy your test case to Here is the result. Did I miss something?
|
I am not sure why it does not work for you, to reproduce on my machine I do exactly this (commit fee8e97) :
I am not sure what are you using as LIB_FUZZING_ENGINE and whether or not it affects it. |
Uh I confirm that if I use the |
I can also confirm it reproduces when compiling with AFLplusplus with default configurations:
|
Ok the problem is that in cpp-httplib/test/fuzzing/server_fuzzer.cc Line 56 in fee8e97
|
@omjego, do you have any thought for the previous comment by @pietroborrello, since I am not familiar to the code very much. Thanks for taking your time. @pietroborrello, could you tell me where |
I have added it as the first instruction inside the // Copyright 2017 Google Inc. All Rights Reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// This runner does not do any fuzzing, but allows us to run the fuzz target
// on the test corpus or on a single file,
// e.g. the one that comes from a bug report.
#include <cassert>
#include <iostream>
#include <fstream>
#include <vector>
// Forward declare the "fuzz target" interface.
// We deliberately keep this inteface simple and header-free.
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
extern "C" int LLVMFuzzerInitialize(int * /*argc*/, char *** /*argv*/); // <-------------
// It reads all files passed as parameters and feeds their contents
// one by one into the fuzz target (LLVMFuzzerTestOneInput).
int main(int argc, char **argv) {
for (int i = 1; i < argc; i++) {
LLVMFuzzerInitialize(&argc, &argv); // <-------------
std::ifstream in(argv[i]);
in.seekg(0, in.end);
size_t length = static_cast<size_t>(in.tellg());
in.seekg (0, in.beg);
std::cout << "Reading " << length << " bytes from " << argv[i] << std::endl;
// Allocate exactly length bytes so that we reliably catch buffer overflows.
std::vector<char> bytes(length);
in.read(bytes.data(), static_cast<std::streamsize>(bytes.size()));
LLVMFuzzerTestOneInput(reinterpret_cast<const uint8_t *>(bytes.data()),
bytes.size());
std::cout << "Execution successful" << std::endl;
}
std::cout << "Execution finished" << std::endl;
return 0;
} |
@pietroborrello, I added the call, but I still don't get the same result as yours... I probably should try on linux instead of macOS?
|
Ah yes, I'm on ubuntu 18.04 |
@pietroborrello, since I don't have a linux desktop machine, I tested on ubuntu 20.04 on vagrant. But I am still not able to reproduce this problem. Can you reproduce the problem by running
|
So the way I'm compiling is
Directly in the
Maybe the different variables that the Makefile sets in |
So the bug does not reproduce in the Makefile in cpp-httplib/test/fuzzing/Makefile Line 4 in fee8e97
While in the Line 2 in fee8e97
|
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86164 seems to describe a similar issue, which basically means that in theory, it is unsafe to use |
@pietroborrello, thanks for the additional information. I am now able to reproduce it.
This library takes an advantage of the regular expression to parse and retrieve path components as below. So we cannot be away from it. Also using a different regex library isn't an option either, since it'll add an additional dependency. (I only accept such external library dependency for compression and SSL like zlib, brotli and openssl. svr.Get(R"(/numbers/(\d+))", [&](const Request& req, Response& res) {
auto numbers = req.matches[1];
res.set_content(numbers, "text/plain");
}); It seems like this problem is caused by the following code in extern "C" int LLVMFuzzerInitialize(int * /*argc*/, char *** /*argv*/) {
g_server.Get(R"(.*)",
[&](const httplib::Request & /*req*/, httplib::Response &res) {
res.set_content("response content", "text/plain");
});
g_server.Post(R"(.*)",
[&](const httplib::Request & /*req*/, httplib::Response &res) {
res.set_content("response content", "text/plain");
});
g_server.Put(R"(.*)",
[&](const httplib::Request & /*req*/, httplib::Response &res) {
res.set_content("response content", "text/plain");
});
g_server.Patch(R"(.*)",
[&](const httplib::Request & /*req*/, httplib::Response &res) {
res.set_content("response content", "text/plain");
});
g_server.Delete(
R"(.*)", [&](const httplib::Request & /*req*/, httplib::Response &res) {
res.set_content("response content", "text/plain");
});
g_server.Options(
R"(.*)", [&](const httplib::Request & /*req*/, httplib::Response &res) {
res.set_content("response content", "text/plain");
});
return 0;
} The infinite repetition pattern |
Thank you for looking into that! |
I am able to reproduce it on my machine with the following simple code: // a.cpp
#include <regex>
int main(void) {
auto s = std::string(1024 * 11, '?');
auto re = std::regex(".*");
std::smatch m;
auto ret = std::regex_match(s, m, re);
}
|
@pietroborrello if you add |
I confirm that I can reproduce it too with the minimized test
And I confirm that setting the limit to 4096 does not crash on my machine, but I guess this depends on the size of the stack of the system. |
Describe the bug
AddressSanitizer: stack-overflow in regex_executor.tcc
To Reproduce
Built cpp-httplib using clang-10 according to the oss-fuzz script with
CXXFLAGS='-O1 -fsanitize=address -fsanitize=array-bounds,bool,builtin,enum,float-divide-by-zero,function,integer-divide-by-zero,null,object-size,return,returns-nonnull-attribute,shift,signed-integer-overflow,unreachable,vla-bound,vptr'
commit: 696239d
testcase:
httplib-server_fuzzer.zip
ASAN Output (trimmed since it was too long)
The text was updated successfully, but these errors were encountered: