Skip to content
Permalink
Browse files

[HPHP Tainting] Generalizing trace guard system

Summary:
Title; this is done in anticipation of other traces, like
TAINT_BIT_TRACE_SELF.

Test Plan: ran a lot of requests in hphpi with trace activated

Reviewers: mwilliams, srenfro, amenghra

Reviewed By: srenfro

CC: ps, mwilliams, srenfro, amenghra

Differential Revision: 312552
  • Loading branch information...
mxw authored and scottmac committed Aug 25, 2011
1 parent 39b4b08 commit b44280b90446df3e184b67e75084823fcb70f3fb
@@ -33,6 +33,7 @@
#define TAINT_BIT_TRACE_HTML (0x10)
#define TAINT_BIT_ALL (0x1f)
#define TAINT_BIT_TRACE_SELF (0x20)
#define TAINT_BIT_TRACE_ALL (0x30)

#define TAINT_BITS_RESERVED (0xe0000000)
#define TAINT_GET_TAINT(bits) ((bits) & (~TAINT_BITS_RESERVED))
@@ -39,7 +39,7 @@ void TaintObserver::RegisterAccessed(const TaintData& td) {

// Absorb the taint and any trace data.
tc->m_current_taint.setTaint(td.getTaint());
if (TaintTracer::IsEnabledHtml()) {
if (TaintTracer::IsTraceEnabled(TAINT_BIT_TRACE_HTML)) {
tc->m_current_taint.attachTaintTrace(td.getTaintTrace());
}
}
@@ -60,7 +60,7 @@ void TaintObserver::RegisterMutated(TaintData& td, const char *s) {
td.attachTaintTrace(NEW(TaintTraceData)(TaintTracer::Trace(s, true, true)));
}

if (TaintTracer::IsEnabledHtml()) {
if (TaintTracer::IsTraceEnabled(TAINT_BIT_TRACE_HTML)) {
ASSERT(!(TAINT_ISSET_HTML_NO_TRACE(set_mask) &&
TAINT_ISSET_HTML_NO_TRACE(clear_mask)));

@@ -79,7 +79,7 @@ void TaintObserver::RegisterMutated(TaintData& td, const char *s) {

// Propagate the taint and any trace data.
td.setTaint(set_mask | (~clear_mask & t));
if (TaintTracer::IsEnabledHtml()) {
if (TaintTracer::IsTraceEnabled(TAINT_BIT_TRACE_HTML)) {
td.setTaintTrace(tc->m_current_taint.getTaintTrace());
}
}
@@ -62,19 +62,20 @@ class TaintTraceData : public Countable {
class TaintTracerRequestData : public RequestEventHandler {
public:
virtual void requestInit() {
m_enabled_html = false;
m_trace_states = TAINT_BIT_NONE;
}
virtual void requestShutdown() {
m_enabled_html = false;
m_trace_states = TAINT_BIT_NONE;
m_stringset.clear();
}

bool isEnabledHtml() { return m_enabled_html; }
bool switchHtml(bool state) {
bool old = m_enabled_html;
m_enabled_html = state;
bool isTraceEnabled(taint_t trace) { return m_trace_states & trace; }
taint_t switchTrace(taint_t trace, bool state) {
taint_t old = m_trace_states;
m_trace_states = (m_trace_states & ~trace) | (trace & ((~state) + 1));
return old;
}
void restoreTrace(taint_t trace) { m_trace_states = trace; }

const String insert(String str) {
return *(m_stringset.insert(str).first);
@@ -84,7 +85,7 @@ class TaintTracerRequestData : public RequestEventHandler {
}

private:
bool m_enabled_html;
taint_t m_trace_states;
StringSet m_stringset;
};

@@ -99,9 +100,14 @@ class TaintTracer {
static TaintTraceDataPtr CreateTrace();
static std::string ExtractTrace(const TaintTraceNodePtr& root);

static bool IsEnabledHtml() { return s_requestdata->isEnabledHtml(); }
static bool SwitchHtml(bool state) {
return s_requestdata->switchHtml(state);
static bool IsTraceEnabled(taint_t trace) {
return s_requestdata->isTraceEnabled(trace);
}
static taint_t SwitchTrace(taint_t trace, bool state) {
return s_requestdata->switchTrace(trace, state);
}
static void RestoreTrace(taint_t trace) {
s_requestdata->restoreTrace(trace);
}

private:
@@ -117,17 +123,21 @@ class TaintTracer {
/*
* Stack-scoped guard for HTML trace.
*/
class TaintTracerHtmlSwitchGuard {
class TaintTracerSwitchGuard {
public:
TaintTracerHtmlSwitchGuard(bool state) {
old = TaintTracer::SwitchHtml(state);
TaintTracerSwitchGuard(taint_t trace, bool state) {
m_old = TaintTracer::SwitchTrace(trace, state);
}
~TaintTracerHtmlSwitchGuard() {
TaintTracer::SwitchHtml(old);
~TaintTracerSwitchGuard() {
TaintTracer::RestoreTrace(m_old);
}

private:
bool old;
taint_t m_old;

void *operator new(long unsigned int size);
TaintTracerSwitchGuard(const TaintTracerSwitchGuard&);
TaintTracerSwitchGuard &operator=(const TaintTracerSwitchGuard&);
};

}
@@ -37,7 +37,7 @@ void TaintWarning::WarnIfTainted(CStrRef s, const taint_t bit) {
switch (bit) {
case TAINT_BIT_HTML:
buf += "HTML-unsafe (tainted)";
if (TaintTracer::IsEnabledHtml()) {
if (TaintTracer::IsTraceEnabled(TAINT_BIT_TRACE_HTML)) {
force_warning = true;
aux = TaintTracer::ExtractTrace(td.getTaintTrace());
}
@@ -26,6 +26,7 @@
#include <runtime/base/builtin_functions.h>
#include <runtime/base/variable_serializer.h>
#include <util/alloc.h>
#include <runtime/base/taint/taint_data.h>
#include <runtime/base/taint/taint_trace.h>

using namespace std;
@@ -45,7 +46,7 @@ bool f_apc_store(CStrRef key, CVarRef var, int64 ttl /* = 0 */,
}

#ifdef TAINTED
TaintTracerHtmlSwitchGuard guard(false);
TaintTracerSwitchGuard guard(TAINT_BIT_TRACE_ALL, false);
#endif
return s_apc_store[cache_id].store(key, var, ttl);
}
@@ -60,7 +61,7 @@ bool f_apc_add(CStrRef key, CVarRef var, int64 ttl /* = 0 */,
}

#ifdef TAINTED
TaintTracerHtmlSwitchGuard guard(false);
TaintTracerSwitchGuard guard(TAINT_BIT_TRACE_ALL, false);
#endif
return s_apc_store[cache_id].store(key, var, ttl, false);
}
@@ -75,7 +76,7 @@ Variant f_apc_fetch(CVarRef key, VRefParam success /* = null */,
}

#ifdef TAINTED
TaintTracerHtmlSwitchGuard guard(false);
TaintTracerSwitchGuard guard(TAINT_BIT_TRACE_ALL, false);
#endif
Variant v;

@@ -926,7 +926,7 @@ Array f_fb_get_taint_warning_counts() {

void f_fb_enable_html_taint_trace() {
#ifdef TAINTED
TaintTracer::SwitchHtml(true);
TaintTracer::SwitchTrace(TAINT_BIT_TRACE_HTML, true);
#endif
}

0 comments on commit b44280b

Please sign in to comment.
You can’t perform that action at this time.