mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-23 10:15:41 +00:00
f1fbd2ff00
# ignore-this-changeset Differential Revision: https://phabricator.services.mozilla.com/D33456 --HG-- extra : moz-landing-system : lando
162 lines
4.7 KiB
C++
162 lines
4.7 KiB
C++
#include "mozilla/Preferences.h"
|
|
|
|
#include "nsCOMPtr.h"
|
|
#include "nsNetCID.h"
|
|
#include "nsString.h"
|
|
#include "nsComponentManagerUtils.h"
|
|
#include "nsContentUtils.h"
|
|
#include "nsIPrincipal.h"
|
|
#include "nsScriptSecurityManager.h"
|
|
#include "nsServiceManagerUtils.h"
|
|
#include "nsNetUtil.h"
|
|
#include "NullPrincipal.h"
|
|
#include "nsCycleCollector.h"
|
|
|
|
#include "FuzzingInterface.h"
|
|
|
|
namespace mozilla {
|
|
namespace net {
|
|
|
|
class FuzzingStreamListener final : public nsIStreamListener {
|
|
public:
|
|
NS_DECL_ISUPPORTS
|
|
NS_DECL_NSIREQUESTOBSERVER
|
|
NS_DECL_NSISTREAMLISTENER
|
|
|
|
FuzzingStreamListener() = default;
|
|
|
|
void waitUntilDone() {
|
|
SpinEventLoopUntil([&]() { return mChannelDone; });
|
|
}
|
|
|
|
private:
|
|
~FuzzingStreamListener() = default;
|
|
bool mChannelDone = false;
|
|
};
|
|
|
|
NS_IMPL_ISUPPORTS(FuzzingStreamListener, nsIStreamListener, nsIRequestObserver)
|
|
|
|
NS_IMETHODIMP
|
|
FuzzingStreamListener::OnStartRequest(nsIRequest* aRequest) {
|
|
FUZZING_LOG(("FuzzingStreamListener::OnStartRequest"));
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
FuzzingStreamListener::OnDataAvailable(nsIRequest* aRequest,
|
|
nsIInputStream* aInputStream,
|
|
uint64_t aOffset, uint32_t aCount) {
|
|
FUZZING_LOG(("FuzzingStreamListener::OnDataAvailable"));
|
|
static uint32_t const kCopyChunkSize = 128 * 1024;
|
|
uint32_t toRead = std::min<uint32_t>(aCount, kCopyChunkSize);
|
|
nsCString data;
|
|
|
|
while (aCount) {
|
|
nsresult rv = NS_ReadInputStreamToString(aInputStream, data, toRead);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
aOffset += toRead;
|
|
aCount -= toRead;
|
|
toRead = std::min<uint32_t>(aCount, kCopyChunkSize);
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
FuzzingStreamListener::OnStopRequest(nsIRequest* aRequest,
|
|
nsresult aStatusCode) {
|
|
FUZZING_LOG(("FuzzingStreamListener::OnStopRequest"));
|
|
mChannelDone = true;
|
|
return NS_OK;
|
|
}
|
|
|
|
// Forward declaration to the function in FuzzyLayer.cpp,
|
|
// used to set the buffer to the global defined there.
|
|
void setNetworkFuzzingBuffer(const uint8_t* data, size_t size);
|
|
extern Atomic<bool> gFuzzingConnClosed;
|
|
|
|
static int FuzzingInitNetworkHttp(int* argc, char*** argv) {
|
|
Preferences::SetBool("network.dns.native-is-localhost", true);
|
|
Preferences::SetBool("fuzzing.necko.enabled", true);
|
|
Preferences::SetInt("network.http.speculative-parallel-limit", 0);
|
|
return 0;
|
|
}
|
|
|
|
static int FuzzingRunNetworkHttp(const uint8_t* data, size_t size) {
|
|
// Set the data to be processed
|
|
setNetworkFuzzingBuffer(data, size);
|
|
|
|
nsWeakPtr channelRef;
|
|
|
|
{
|
|
nsCOMPtr<nsIURI> url;
|
|
nsAutoCString spec;
|
|
nsresult rv;
|
|
|
|
spec = "http://127.0.0.1:8000";
|
|
if (NS_NewURI(getter_AddRefs(url), spec) != NS_OK) {
|
|
MOZ_CRASH("Call to NS_NewURI failed.");
|
|
}
|
|
|
|
nsLoadFlags loadFlags;
|
|
loadFlags = nsIRequest::LOAD_BACKGROUND | nsIRequest::LOAD_BYPASS_CACHE |
|
|
nsIRequest::INHIBIT_CACHING |
|
|
nsIRequest::LOAD_FRESH_CONNECTION |
|
|
nsIChannel::LOAD_INITIAL_DOCUMENT_URI;
|
|
nsSecurityFlags secFlags;
|
|
secFlags = nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL |
|
|
nsILoadInfo::SEC_SANDBOXED;
|
|
nsCOMPtr<nsIChannel> channel;
|
|
rv = NS_NewChannel(getter_AddRefs(channel), url,
|
|
nsContentUtils::GetSystemPrincipal(), secFlags,
|
|
nsIContentPolicy::TYPE_INTERNAL_XMLHTTPREQUEST,
|
|
nullptr, // aCookieSettings
|
|
nullptr, // aPerformanceStorage
|
|
nullptr, // loadGroup
|
|
nullptr, // aCallbacks
|
|
loadFlags, // aLoadFlags
|
|
nullptr // aIoService
|
|
);
|
|
|
|
if (rv != NS_OK) {
|
|
MOZ_CRASH("Call to NS_NewChannel failed.");
|
|
}
|
|
|
|
RefPtr<FuzzingStreamListener> gStreamListener;
|
|
nsCOMPtr<nsIHttpChannel> gHttpChannel;
|
|
|
|
gHttpChannel = do_QueryInterface(channel);
|
|
rv = gHttpChannel->SetRequestMethod(NS_LITERAL_CSTRING("GET"));
|
|
if (rv != NS_OK) {
|
|
MOZ_CRASH("SetRequestMethod on gHttpChannel failed.");
|
|
}
|
|
|
|
gStreamListener = new FuzzingStreamListener();
|
|
gHttpChannel->AsyncOpen(gStreamListener);
|
|
|
|
// Wait for StopRequest
|
|
gStreamListener->waitUntilDone();
|
|
|
|
channelRef = do_GetWeakReference(gHttpChannel);
|
|
}
|
|
|
|
// Wait for the channel to be destroyed
|
|
SpinEventLoopUntil([&]() -> bool {
|
|
nsCycleCollector_collect(nullptr);
|
|
nsCOMPtr<nsIHttpChannel> channel = do_QueryReferent(channelRef);
|
|
return channel == nullptr;
|
|
});
|
|
|
|
// Wait for the connection to indicate closed
|
|
SpinEventLoopUntil([&]() -> bool { return gFuzzingConnClosed; });
|
|
|
|
return 0;
|
|
}
|
|
|
|
MOZ_FUZZING_INTERFACE_RAW(FuzzingInitNetworkHttp, FuzzingRunNetworkHttp,
|
|
NetworkHttp);
|
|
|
|
} // namespace net
|
|
} // namespace mozilla
|