1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
#include "mozilla/Preferences.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "nsCOMPtr.h"
#include "nsNetCID.h"
#include "nsString.h"
#include "nsComponentManagerUtils.h"
#include "nsContentUtils.h"
#include "nsScriptSecurityManager.h"
#include "nsServiceManagerUtils.h"
#include "nsNetUtil.h"
#include "NullPrincipal.h"
#include "nsCycleCollector.h"
#include "nsIChannel.h"
#include "nsSandboxFlags.h"
#include "nsFtpProtocolHandler.h"
#include "FuzzingInterface.h"
#include "FuzzingStreamListener.h"
#include "FuzzyLayer.h"
namespace mozilla {
namespace net {
static nsAutoCString ftpSpec;
static int FuzzingInitNetworkFtp(int* argc, char*** argv) {
Preferences::SetBool("network.dns.native-is-localhost", true);
Preferences::SetBool("fuzzing.necko.enabled", true);
Preferences::SetBool("network.connectivity-service.enabled", false);
if (ftpSpec.IsEmpty()) {
ftpSpec = "ftp://127.0.0.1/";
}
return 0;
}
static int FuzzingInitNetworkFtpDownload(int* argc, char*** argv) {
ftpSpec = "ftp://127.0.0.1/test.txt";
return FuzzingInitNetworkFtp(argc, argv);
}
static int FuzzingRunNetworkFtp(const uint8_t* data, size_t size) {
// Set the data to be processed
if (size > 1024) {
// If we have more than 1024 bytes, we use the excess for
// an optional data connection.
addNetworkFuzzingBuffer(data, 1024, true);
addNetworkFuzzingBuffer(data + 1024, size - 1024, true, true);
} else {
addNetworkFuzzingBuffer(data, size, true);
}
nsWeakPtr channelRef;
{
nsCOMPtr<nsIURI> url;
nsAutoCString spec;
nsresult rv;
if (NS_NewURI(getter_AddRefs(url), ftpSpec) != 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_SEC_CONTEXT_IS_NULL;
uint32_t sandboxFlags = SANDBOXED_ORIGIN;
nsCOMPtr<nsIChannel> channel;
rv = NS_NewChannel(getter_AddRefs(channel), url,
nsContentUtils::GetSystemPrincipal(), secFlags,
nsIContentPolicy::TYPE_INTERNAL_XMLHTTPREQUEST,
nullptr, // aCookieJarSettings
nullptr, // aPerformanceStorage
nullptr, // loadGroup
nullptr, // aCallbacks
loadFlags, // aLoadFlags
nullptr, // aIoService
sandboxFlags);
if (rv != NS_OK) {
MOZ_CRASH("Call to NS_NewChannel failed.");
}
RefPtr<FuzzingStreamListener> gStreamListener;
gStreamListener = new FuzzingStreamListener();
rv = channel->AsyncOpen(gStreamListener);
if (NS_FAILED(rv)) {
MOZ_CRASH("asyncOpen failed");
}
FUZZING_LOG(("Spinning for StopRequest"));
// Wait for StopRequest
gStreamListener->waitUntilDone();
// The FTP code can cache control connections which would cause
// a strong reference to be held to our channel. After performing
// all requests here, we need to prune all cached connections to
// let the channel die. In the future we can test the caching further
// with multiple requests using a cached control connection.
gFtpHandler->Observe(nullptr, "net:clear-active-logins", nullptr);
channelRef = do_GetWeakReference(channel);
}
FUZZING_LOG(("Spinning for channel == nullptr"));
// Wait for the channel to be destroyed
SpinEventLoopUntil([&]() -> bool {
nsCycleCollector_collect(nullptr);
nsCOMPtr<nsIChannel> channel = do_QueryReferent(channelRef);
return channel == nullptr;
});
if (!signalNetworkFuzzingDone()) {
// Wait for the connection to indicate closed
FUZZING_LOG(("Spinning for gFuzzingConnClosed"));
SpinEventLoopUntil([&]() -> bool { return gFuzzingConnClosed; });
}
FUZZING_LOG(("End of iteration"));
return 0;
}
MOZ_FUZZING_INTERFACE_RAW(FuzzingInitNetworkFtp, FuzzingRunNetworkFtp,
NetworkFtp);
MOZ_FUZZING_INTERFACE_RAW(FuzzingInitNetworkFtpDownload, FuzzingRunNetworkFtp,
NetworkFtpDownload);
} // namespace net
} // namespace mozilla
|