Skip to content

Commit

Permalink
Dump StringTaint to file via a Spewer
Browse files Browse the repository at this point in the history
  • Loading branch information
tmbrbr committed Dec 3, 2024
1 parent db7aacd commit 19ef468
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 1 deletion.
9 changes: 9 additions & 0 deletions js/moz.configure
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,15 @@ set_config("JS_JITSPEW", depends_if("--enable-jitspew")(lambda _: True))
set_define("JS_STRUCTURED_SPEW", depends_if("--enable-jitspew")(lambda _: True))
set_config("JS_STRUCTURED_SPEW", depends_if("--enable-jitspew")(lambda _: True))

option(
"--enable-taintspew",
default=False,
help="{Enable|Disable} the taint flow spew variable",
)

# Also enable the structured spewer for tainting
set_define("JS_STRUCTURED_SPEW", depends_if("--enable-taintspew")(lambda _: True))
set_config("JS_STRUCTURED_SPEW", depends_if("--enable-taintspew")(lambda _: True))

@depends("--enable-jit", "--enable-jitspew", simulator, target, moz_debug)
def jit_disasm_arm(jit_enabled, spew, simulator, target, debug):
Expand Down
2 changes: 2 additions & 0 deletions js/src/jsapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5072,6 +5072,8 @@ JS_ReportTaintSink(JSContext* cx, JS::HandleString str, const char* sink, JS::Ha
RootedValue rval(cx);
JS_CallFunction(cx, nullptr, report, arguments, &rval);
MOZ_ASSERT(!cx->isExceptionPending());

MaybeSpewStringTaint(cx, str);
}

JS_PUBLIC_API bool JS::FinishIncrementalEncoding(JSContext* cx,
Expand Down
49 changes: 49 additions & 0 deletions js/src/jstaint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "js/ErrorReport.h"
#include "js/UniquePtr.h"
#include "vm/FrameIter.h"
#include "vm/JSAtomUtils.h"
#include "vm/JSContext.h"
#include "vm/JSFunction.h"
#include "vm/StringType.h"
Expand Down Expand Up @@ -371,6 +372,54 @@ void JS::MarkTaintedFunctionArguments(JSContext* cx, JSFunction* function, const
}
}

void JS::MaybeSpewStringTaint(JSContext* cx, JSString* str) {
//#ifdef JS_STRUCTURED_SPEW
if (!str || !str->taint()) {
return;
}

AutoStructuredSpewer spew(cx, SpewChannel::TaintFlowSpewer, cx->currentScript());
if (spew) {
spew->beginList();
for (const TaintRange& range : str->taint()) {
spew->beginObject();
spew->property("begin", range.begin());
spew->property("end", range.end());

spew->beginListProperty("flow");
for (TaintNode& node : range.flow()) {
const TaintOperation& op = node.operation();
spew->beginObject();
spew->property("operation", op.name());
spew->boolProperty("builtin", op.is_native());
spew->boolProperty("source", op.isSource());

const TaintLocation& loc = op.location();
spew->beginObjectProperty("location");
spew->property("filename", loc.filename().c_str(), loc.filename().size());
spew->property("line", loc.line());
spew->property("pos", loc.pos());
spew->property("scriptline", loc.scriptStartLine());
spew->property("scripthash", JS::convertDigestToHexString(loc.scriptHash()).c_str());
spew->endObject(); // Location

spew->beginListProperty("arguments");
for (auto& arg : op.arguments()) {
spew->string(arg.c_str(), arg.size());
}
spew->endList();

spew->endObject(); // Operation
}
spew->endList(); // flow
spew->endObject(); // range
}
spew->endList();

}
//#endif
}

// Print a message to stdout.
void JS::TaintFoxReport(JSContext* cx, const char* msg)
{
Expand Down
3 changes: 3 additions & 0 deletions js/src/jstaint.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ TaintOperation TaintOperationFromContext(JSContext* cx, const char* name, bool i
// This is mainly useful for tracing tainted arguments through the code.
void MarkTaintedFunctionArguments(JSContext* cx, JSFunction* function, const JS::CallArgs& args);

// Write the taint report to file
void MaybeSpewStringTaint(JSContext* cx, JSString* str);

// Print a message to stdout.
void TaintFoxReport(JSContext* cx, const char* msg);

Expand Down
3 changes: 2 additions & 1 deletion js/src/util/StructuredSpewer.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ namespace js {

# define STRUCTURED_CHANNEL_LIST(_) \
_(BaselineICStats) \
_(CacheIRHealthReport)
_(CacheIRHealthReport) \
_(TaintFlowSpewer)

// Structured spew channels
enum class SpewChannel {
Expand Down
11 changes: 11 additions & 0 deletions js/src/vm/JSONPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,17 @@ void JSONPrinter::property(const char* name, const char* value) {
endStringProperty();
}

void JSONPrinter::property(const char* name, const char16_t* value, size_t length) {
beginStringProperty(name);
JSONString(out_, value, length);
endStringProperty();
}

void JSONPrinter::string(const char16_t* value, size_t length) {
JSONString(beginString(), value, length);
endString();
}

void JSONPrinter::formatProperty(const char* name, const char* format, ...) {
va_list ap;
va_start(ap, format);
Expand Down
3 changes: 3 additions & 0 deletions js/src/vm/JSONPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class JSONPrinter {

void property(const char* name, JSLinearString* value);
void property(const char* name, const char* value);
void property(const char* name, const char16_t* value, size_t length);
void property(const char* name, int32_t value);
void property(const char* name, uint32_t value);
void property(const char* name, int64_t value);
Expand All @@ -60,6 +61,8 @@ class JSONPrinter {
void property(const char* name, size_t value);
#endif

void string(const char16_t* value, size_t length);

void formatProperty(const char* name, const char* format, ...)
MOZ_FORMAT_PRINTF(3, 4);
void formatProperty(const char* name, const char* format, va_list ap);
Expand Down

0 comments on commit 19ef468

Please sign in to comment.