Skip to content

Commit d17e86f

Browse files
authored
Merge pull request #307 from leeN/e2e-uptodate
End to End tainting reactivated
2 parents 9b0177c + 20f99c8 commit d17e86f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+647
-97
lines changed

dom/base/JSExecutionContext.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ nsresult JSExecutionContext::Compile(const nsAString& aScript) {
163163

164164
const nsPromiseFlatString& flatScript = PromiseFlatString(aScript);
165165
JS::SourceText<char16_t> srcBuf;
166-
if (!srcBuf.init(mCx, flatScript.get(), flatScript.Length(),
166+
if (!srcBuf.init(mCx, flatScript.get(), flatScript.Length(), aScript.Taint(),
167167
JS::SourceOwnership::Borrowed)) {
168168
mSkip = true;
169169
mRv = EvaluationExceptionToNSResult(mCx);

dom/html/HTMLTextAreaElement.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ void HTMLTextAreaElement::GetValueInternal(nsAString& aValue,
157157
bool aIgnoreWrap) const {
158158
MOZ_ASSERT(mState);
159159
mState->GetValue(aValue, aIgnoreWrap, /* aForDisplay = */ true);
160+
MarkTaintSourceElement(aValue, "textarea.value", this);
161+
160162
}
161163

162164
void HTMLTextAreaElement::SetTaintSourceGetAttr(const nsAString& aName, nsAString& aResult) const {

dom/script/ScriptLoadHandler.cpp

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ ScriptDecoder::ScriptDecoder(const Encoding* aEncoding,
6868
template <typename Unit>
6969
nsresult ScriptDecoder::DecodeRawDataHelper(
7070
JS::loader::ScriptLoadRequest* aRequest, const uint8_t* aData,
71-
uint32_t aDataLength, bool aEndOfStream) {
71+
uint32_t aDataLength, bool aEndOfStream, const StringTaint& aTaint) {
7272
CheckedInt<size_t> needed =
7373
ScriptDecoding<Unit>::MaxBufferLength(mDecoder, aDataLength);
7474
if (!needed.isValid()) {
@@ -99,19 +99,26 @@ nsresult ScriptDecoder::DecodeRawDataHelper(
9999
MOZ_ALWAYS_TRUE(scriptText.resize(haveRead));
100100
aRequest->SetReceivedScriptTextLength(scriptText.length());
101101

102+
// Foxhound: Append Taint
103+
// Foxhound(David): Check if this really matches the prior semantics
104+
SafeStringTaint taint(aRequest->Taint());
105+
taint.concat(aTaint, aRequest->ReceivedScriptTextLength());
106+
aRequest->SetReceivedScriptTaint(taint);
107+
102108
return NS_OK;
103109
}
104110

105111
nsresult ScriptDecoder::DecodeRawData(JS::loader::ScriptLoadRequest* aRequest,
106112
const uint8_t* aData,
107-
uint32_t aDataLength, bool aEndOfStream) {
113+
uint32_t aDataLength, bool aEndOfStream,
114+
const StringTaint& aTaint) {
108115
if (aRequest->IsUTF16Text()) {
109116
return DecodeRawDataHelper<char16_t>(aRequest, aData, aDataLength,
110-
aEndOfStream);
117+
aEndOfStream, aTaint);
111118
}
112119

113120
return DecodeRawDataHelper<Utf8Unit>(aRequest, aData, aDataLength,
114-
aEndOfStream);
121+
aEndOfStream, aTaint);
115122
}
116123

117124
ScriptLoadHandler::ScriptLoadHandler(
@@ -191,8 +198,18 @@ ScriptLoadHandler::OnIncrementalData(nsIIncrementalStreamLoader* aLoader,
191198

192199
// Decoder has already been initialized. -- trying to decode all loaded
193200
// bytes.
201+
SafeStringTaint taint(EmptyTaint);
202+
if(aTaint != nullptr) {
203+
taint = *aTaint;
204+
}
194205
rv = mDecoder->DecodeRawData(mRequest, aData, aDataLength,
195-
/* aEndOfStream = */ false);
206+
/* aEndOfStream = */ false, taint);
207+
208+
#if (DEBUG_E2E_TAINTING)
209+
puts(__PRETTY_FUNCTION__);
210+
DumpTaint(taint);
211+
#endif
212+
196213
NS_ENSURE_SUCCESS(rv, rv);
197214

198215
// If SRI is required for this load, appending new bytes to the hash.
@@ -419,7 +436,7 @@ ScriptLoadHandler::OnStreamComplete(nsIIncrementalStreamLoader* aLoader,
419436
EnsureDecoder(aLoader, aData, aDataLength, /* aEndOfStream = */ true);
420437
MOZ_ASSERT(encoderSet);
421438
rv = mDecoder->DecodeRawData(mRequest, aData, aDataLength,
422-
/* aEndOfStream = */ true);
439+
/* aEndOfStream = */ true, *aTaint);
423440
NS_ENSURE_SUCCESS(rv, rv);
424441

425442
LOG(("ScriptLoadRequest (%p): Source length in code units = %u",

dom/script/ScriptLoadHandler.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class ScriptDecoder {
4848
*/
4949
nsresult DecodeRawData(JS::loader::ScriptLoadRequest* aRequest,
5050
const uint8_t* aData, uint32_t aDataLength,
51-
bool aEndOfStream);
51+
bool aEndOfStream, const StringTaint& aTaint);
5252

5353
private:
5454
/*
@@ -60,8 +60,8 @@ class ScriptDecoder {
6060
*/
6161
template <typename Unit>
6262
nsresult DecodeRawDataHelper(JS::loader::ScriptLoadRequest* aRequest,
63-
const uint8_t* aData, uint32_t aDataLength,
64-
bool aEndOfStream);
63+
const uint8_t* aData, uint32_t aDataLength, bool aEndOfStream,
64+
const StringTaint& aTaint);
6565

6666
// Unicode decoder for charset.
6767
mozilla::UniquePtr<mozilla::Decoder> mDecoder;

dom/workers/loader/CacheLoadHandler.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,8 +556,9 @@ nsresult CacheLoadHandler::DataReceivedFromCache(
556556
// Set the Source type to "text" for decoding.
557557
loadContext->mRequest->SetTextSource(loadContext);
558558

559+
// Foxhound(david): Is this sane?
559560
rv = mDecoder->DecodeRawData(loadContext->mRequest, aString, aStringLen,
560-
/* aEndOfStream = */ true);
561+
/* aEndOfStream = */ true, EmptyTaint);
561562
NS_ENSURE_SUCCESS(rv, rv);
562563

563564
if (!loadContext->mRequest->ScriptTextLength()) {

dom/workers/loader/NetworkLoadHandler.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,9 @@ nsresult NetworkLoadHandler::DataReceivedFromNetwork(nsIStreamLoader* aLoader,
168168

169169
// Use the regular ScriptDecoder Decoder for this grunt work! Should be just
170170
// fine because we're running on the main thread.
171+
// Foxhound(david): Is this sane?
171172
rv = mDecoder->DecodeRawData(loadContext->mRequest, aString, aStringLen,
172-
/* aEndOfStream = */ true);
173+
/* aEndOfStream = */ true, EmptyTaint);
173174
NS_ENSURE_SUCCESS(rv, rv);
174175

175176
if (!loadContext->mRequest->ScriptTextLength()) {

dom/worklet/WorkletFetchHandler.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,9 @@ NS_IMETHODIMP FetchCompleteRunnable::RunOnWorkletThread() {
215215
if (mScriptBuffer) {
216216
UniquePtr<ScriptDecoder> decoder = MakeUnique<ScriptDecoder>(
217217
UTF_8_ENCODING, ScriptDecoder::BOMHandling::Remove);
218+
// Foxhound(david): Is this sane?
218219
rv = decoder->DecodeRawData(request, mScriptBuffer.get(), mScriptLength,
219-
true);
220+
true, EmptyTaint);
220221
NS_ENSURE_SUCCESS(rv, rv);
221222
}
222223

dom/xhr/XMLHttpRequestMainThread.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,9 @@ nsresult XMLHttpRequestMainThread::AppendToResponseText(
605605

606606
auto handle = handleOrErr.unwrap();
607607

608+
// Foxhound: propagate taint. TODO(samuel) deal with encoding
609+
helper.AppendTaintAt(len, aTaint);
610+
608611
uint32_t result;
609612
size_t read;
610613
size_t written;
@@ -615,8 +618,6 @@ nsresult XMLHttpRequestMainThread::AppendToResponseText(
615618
len += written;
616619
MOZ_ASSERT(len <= destBufferLen.value());
617620
handle.Finish(len, false);
618-
// Foxhound: propagate taint. TODO(samuel) deal with encoding
619-
helper.AppendTaintAt(len, aTaint);
620621
} // release mutex
621622

622623
if (aLast) {

js/loader/LoadedScript.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "mozilla/UniquePtr.h" // mozilla::UniquePtr
1111

1212
#include "mozilla/dom/ScriptLoadContext.h" // ScriptLoadContext
13+
#include "nsTaintingUtils.h"
1314
#include "jsfriendapi.h"
1415
#include "js/Modules.h" // JS::{Get,Set}ModulePrivate
1516
#include "LoadContextBase.h" // LoadContextBase
@@ -49,6 +50,7 @@ LoadedScript::LoadedScript(ScriptKind aKind,
4950
mURI(aURI),
5051
mDataType(DataType::eUnknown),
5152
mReceivedScriptTextLength(0),
53+
mScriptTextTaint(EmptyTaint),
5254
mBytecodeOffset(0) {
5355
MOZ_ASSERT(mFetchOptions);
5456
MOZ_ASSERT(mURI);
@@ -134,6 +136,10 @@ nsresult LoadedScript::GetScriptSource(JSContext* aCx,
134136
scriptLoadContext->GetInlineScriptText(inlineData);
135137

136138
size_t nbytes = inlineData.Length() * sizeof(char16_t);
139+
140+
// Foxhound: tainted JavaScript inline script data
141+
// Foxhound(david): This breaks some tests atm, have to investigate.
142+
// ReportTaintSink(inlineData, "Inline Script");
137143
JS::UniqueTwoByteChars chars(
138144
static_cast<char16_t*>(JS_malloc(aCx, nbytes)));
139145
if (!chars) {
@@ -143,7 +149,7 @@ nsresult LoadedScript::GetScriptSource(JSContext* aCx,
143149
memcpy(chars.get(), inlineData.get(), nbytes);
144150

145151
SourceText<char16_t> srcBuf;
146-
if (!srcBuf.init(aCx, std::move(chars), inlineData.Length())) {
152+
if (!srcBuf.init(aCx, std::move(chars), inlineData.Length(), inlineData.Taint())) {
147153
return NS_ERROR_OUT_OF_MEMORY;
148154
}
149155

@@ -161,7 +167,7 @@ nsresult LoadedScript::GetScriptSource(JSContext* aCx,
161167
}
162168

163169
SourceText<char16_t> srcBuf;
164-
if (!srcBuf.init(aCx, std::move(chars), length)) {
170+
if (!srcBuf.init(aCx, std::move(chars), length, mScriptTextTaint)) {
165171
return NS_ERROR_OUT_OF_MEMORY;
166172
}
167173

@@ -178,7 +184,7 @@ nsresult LoadedScript::GetScriptSource(JSContext* aCx,
178184
}
179185

180186
SourceText<Utf8Unit> srcBuf;
181-
if (!srcBuf.init(aCx, std::move(chars), length)) {
187+
if (!srcBuf.init(aCx, std::move(chars), length, mScriptTextTaint)) {
182188
return NS_ERROR_OUT_OF_MEMORY;
183189
}
184190

js/loader/LoadedScript.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,14 @@ class LoadedScript : public nsIMemoryReporter {
203203
mReceivedScriptTextLength = aLength;
204204
}
205205

206+
void SetReceivedScriptTaint(const StringTaint& aTaint) {
207+
mScriptTextTaint = aTaint;
208+
}
209+
210+
const StringTaint& Taint() {
211+
return mScriptTextTaint;
212+
}
213+
206214
bool CanHaveBytecode() const {
207215
return IsBytecode() || IsSource() || IsStencil();
208216
}
@@ -256,6 +264,9 @@ class LoadedScript : public nsIMemoryReporter {
256264
// since mScriptData is cleared when the source is passed to the JS engine.
257265
size_t mReceivedScriptTextLength;
258266

267+
// The taint corresponding to the script data
268+
SafeStringTaint mScriptTextTaint;
269+
259270
// Holds the SRI serialized hash and the script bytecode for non-inline
260271
// scripts. The data is laid out according to ScriptBytecodeDataLayout
261272
// or, if compression is enabled, ScriptBytecodeCompressedDataLayout.
@@ -335,6 +346,14 @@ class LoadedScriptDelegate {
335346
GetLoadedScript()->SetReceivedScriptTextLength(aLength);
336347
}
337348

349+
const StringTaint& Taint() {
350+
return GetLoadedScript()->Taint();
351+
}
352+
353+
void SetReceivedScriptTaint(const StringTaint& aTaint) {
354+
GetLoadedScript()->SetReceivedScriptTaint(aTaint);
355+
}
356+
338357
// Get source text. On success |aMaybeSource| will contain either UTF-8 or
339358
// UTF-16 source; on failure it will remain in its initial state.
340359
nsresult GetScriptSource(JSContext* aCx, MaybeSourceText* aMaybeSource,

0 commit comments

Comments
 (0)