summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoroysteine <oysteine@chromium.org>2015-06-05 22:02:28 -0700
committerCommit bot <commit-bot@chromium.org>2015-06-06 05:02:53 +0000
commitaf2b800518e5f6a4b0704aa2ba936dc4ae569369 (patch)
tree85bfdbcce0aae40d1363ba2c0eca49d1bac60fc4
parent049996311153997f3c5aaf178b44d9208ccc0f4f (diff)
downloadchromium_src-af2b800518e5f6a4b0704aa2ba936dc4ae569369.zip
chromium_src-af2b800518e5f6a4b0704aa2ba936dc4ae569369.tar.gz
chromium_src-af2b800518e5f6a4b0704aa2ba936dc4ae569369.tar.bz2
Hooked the trace event argument whitelist up to the BackgroundTracingManager
R=dsinclair,nduca,davidben,shatch BUG=466769 Review URL: https://codereview.chromium.org/1148633007 Cr-Commit-Position: refs/heads/master@{#333214}
-rw-r--r--base/trace_event/trace_config.h1
-rw-r--r--chrome/browser/tracing/background_tracing_field_trial.cc5
-rw-r--r--content/browser/tracing/background_tracing_manager_browsertest.cc167
-rw-r--r--content/browser/tracing/background_tracing_manager_impl.cc18
-rw-r--r--content/browser/tracing/background_tracing_manager_impl.h6
-rw-r--r--content/public/browser/background_tracing_manager.h13
6 files changed, 186 insertions, 24 deletions
diff --git a/base/trace_event/trace_config.h b/base/trace_event/trace_config.h
index fe23c17..a9f8306 100644
--- a/base/trace_event/trace_config.h
+++ b/base/trace_event/trace_config.h
@@ -122,6 +122,7 @@ class BASE_EXPORT TraceConfig {
void SetTraceRecordMode(TraceRecordMode mode) { record_mode_ = mode; }
void EnableSampling() { enable_sampling_ = true; }
void EnableSystrace() { enable_systrace_ = true; }
+ void EnableArgumentFilter() { enable_argument_filter_ = true; }
// Writes the string representation of the TraceConfig. The string is JSON
// formatted.
diff --git a/chrome/browser/tracing/background_tracing_field_trial.cc b/chrome/browser/tracing/background_tracing_field_trial.cc
index c509d68..8d459ba 100644
--- a/chrome/browser/tracing/background_tracing_field_trial.cc
+++ b/chrome/browser/tracing/background_tracing_field_trial.cc
@@ -34,7 +34,7 @@ void OnUploadComplete(TraceCrashServiceUploader* uploader,
done_callback.Run();
}
-void UploadCallback(const base::RefCountedString* file_contents,
+void UploadCallback(const scoped_refptr<base::RefCountedString>& file_contents,
base::Closure callback) {
TraceCrashServiceUploader* uploader = new TraceCrashServiceUploader(
g_browser_process->system_request_context());
@@ -66,7 +66,8 @@ void SetupBackgroundTracingFieldTrial() {
return;
content::BackgroundTracingManager::GetInstance()->SetActiveScenario(
- config.Pass(), base::Bind(&UploadCallback), true);
+ config.Pass(), base::Bind(&UploadCallback),
+ content::BackgroundTracingManager::ANONYMIZE_DATA);
}
} // namespace tracing
diff --git a/content/browser/tracing/background_tracing_manager_browsertest.cc b/content/browser/tracing/background_tracing_manager_browsertest.cc
index 54a1127..13a309e 100644
--- a/content/browser/tracing/background_tracing_manager_browsertest.cc
+++ b/content/browser/tracing/background_tracing_manager_browsertest.cc
@@ -3,12 +3,14 @@
// found in the LICENSE file.
#include "base/bind.h"
+#include "base/trace_event/trace_event.h"
#include "content/public/browser/background_tracing_manager.h"
#include "content/public/browser/background_tracing_preemptive_config.h"
#include "content/public/browser/background_tracing_reactive_config.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_utils.h"
+#include "third_party/zlib/zlib.h"
namespace content {
@@ -29,16 +31,42 @@ class BackgroundTracingManagerUploadConfigWrapper {
base::Unretained(this));
}
- void Upload(const base::RefCountedString* file_contents,
+ void Upload(const scoped_refptr<base::RefCountedString>& file_contents,
base::Callback<void()> done_callback) {
receive_count_ += 1;
+ EXPECT_TRUE(file_contents);
+ size_t compressed_length = file_contents->data().length();
+ const size_t kOutputBufferLength = 10 * 1024 * 1024;
+ std::vector<char> output_str(kOutputBufferLength);
+
+ z_stream stream = {0};
+ stream.avail_in = compressed_length;
+ stream.avail_out = kOutputBufferLength;
+ stream.next_in = (Bytef*)&file_contents->data()[0];
+ stream.next_out = (Bytef*)vector_as_array(&output_str);
+
+ // 16 + MAX_WBITS means only decoding gzip encoded streams, and using
+ // the biggest window size, according to zlib.h
+ int result = inflateInit2(&stream, 16 + MAX_WBITS);
+ EXPECT_EQ(Z_OK, result);
+ result = inflate(&stream, Z_FINISH);
+ int bytes_written = kOutputBufferLength - stream.avail_out;
+
+ inflateEnd(&stream);
+ EXPECT_EQ(Z_STREAM_END, result);
+
+ last_file_contents_.assign(vector_as_array(&output_str), bytes_written);
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(done_callback));
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(callback_));
}
+ bool TraceHasMatchingString(const char* str) {
+ return last_file_contents_.find(str) != std::string::npos;
+ }
+
int get_receive_count() const { return receive_count_; }
const BackgroundTracingManager::ReceiveCallback& get_receive_callback()
@@ -50,6 +78,7 @@ class BackgroundTracingManagerUploadConfigWrapper {
BackgroundTracingManager::ReceiveCallback receive_callback_;
base::Closure callback_;
int receive_count_;
+ std::string last_file_contents_;
};
void StartedFinalizingCallback(base::Closure callback,
@@ -97,7 +126,8 @@ void SetupBackgroundTracingManager() {
void DisableScenarioWhenIdle() {
BackgroundTracingManager::GetInstance()->SetActiveScenario(
- NULL, BackgroundTracingManager::ReceiveCallback(), false);
+ NULL, BackgroundTracingManager::ReceiveCallback(),
+ BackgroundTracingManager::NO_DATA_FILTERING);
}
// This tests that the endpoint receives the final trace data.
@@ -118,7 +148,8 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
GetInstance()->RegisterTriggerType("preemptive_test");
BackgroundTracingManager::GetInstance()->SetActiveScenario(
- config.Pass(), upload_config_wrapper.get_receive_callback(), true);
+ config.Pass(), upload_config_wrapper.get_receive_callback(),
+ BackgroundTracingManager::NO_DATA_FILTERING);
BackgroundTracingManager::GetInstance()->WhenIdle(
base::Bind(&DisableScenarioWhenIdle));
@@ -150,7 +181,8 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
"preemptive_test");
BackgroundTracingManager::GetInstance()->SetActiveScenario(
- config.Pass(), upload_config_wrapper.get_receive_callback(), true);
+ config.Pass(), upload_config_wrapper.get_receive_callback(),
+ BackgroundTracingManager::NO_DATA_FILTERING);
BackgroundTracingManager::GetInstance()->WhenIdle(
base::Bind(&DisableScenarioWhenIdle));
@@ -166,6 +198,112 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
}
}
+namespace {
+
+bool IsTraceEventArgsWhitelisted(const char* category_group_name,
+ const char* event_name) {
+ if (MatchPattern(category_group_name, "benchmark") &&
+ MatchPattern(event_name, "whitelisted")) {
+ return true;
+ }
+
+ return false;
+}
+
+} // namespace
+
+// This tests that non-whitelisted args get stripped if required.
+IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
+ NoWhitelistedArgsStripped) {
+ SetupBackgroundTracingManager();
+
+ base::trace_event::TraceLog::GetInstance()->SetArgumentFilterPredicate(
+ base::Bind(&IsTraceEventArgsWhitelisted));
+
+ base::RunLoop wait_for_upload;
+ BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
+ wait_for_upload.QuitClosure());
+
+ scoped_ptr<BackgroundTracingPreemptiveConfig> config =
+ CreatePreemptiveConfig();
+
+ content::BackgroundTracingManager::TriggerHandle handle =
+ content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
+ "preemptive_test");
+
+ base::RunLoop wait_for_activated;
+ BackgroundTracingManager::GetInstance()->SetTracingEnabledCallbackForTesting(
+ wait_for_activated.QuitClosure());
+ EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
+ config.Pass(), upload_config_wrapper.get_receive_callback(),
+ BackgroundTracingManager::ANONYMIZE_DATA));
+
+ wait_for_activated.Run();
+
+ TRACE_EVENT1("benchmark", "whitelisted", "find_this", 1);
+ TRACE_EVENT1("benchmark", "not_whitelisted", "this_not_found", 1);
+
+ BackgroundTracingManager::GetInstance()->WhenIdle(
+ base::Bind(&DisableScenarioWhenIdle));
+
+ BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
+ handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
+
+ wait_for_upload.Run();
+
+ EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 1);
+ EXPECT_TRUE(upload_config_wrapper.TraceHasMatchingString("{"));
+ EXPECT_TRUE(upload_config_wrapper.TraceHasMatchingString("find_this"));
+ EXPECT_TRUE(!upload_config_wrapper.TraceHasMatchingString("this_not_found"));
+}
+
+// This tests subprocesses (like a navigating renderer) which gets told to
+// provide a argument-filtered trace and has no predicate in place to do the
+// filtering (in this case, only the browser process gets it set), will crash
+// rather than return potential PII.
+IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
+ CrashWhenSubprocessWithoutArgumentFilter) {
+ SetupBackgroundTracingManager();
+
+ base::trace_event::TraceLog::GetInstance()->SetArgumentFilterPredicate(
+ base::Bind(&IsTraceEventArgsWhitelisted));
+
+ base::RunLoop wait_for_upload;
+ BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
+ wait_for_upload.QuitClosure());
+
+ scoped_ptr<BackgroundTracingPreemptiveConfig> config =
+ CreatePreemptiveConfig();
+
+ content::BackgroundTracingManager::TriggerHandle handle =
+ content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
+ "preemptive_test");
+
+ base::RunLoop wait_for_activated;
+ BackgroundTracingManager::GetInstance()->SetTracingEnabledCallbackForTesting(
+ wait_for_activated.QuitClosure());
+ EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
+ config.Pass(), upload_config_wrapper.get_receive_callback(),
+ BackgroundTracingManager::ANONYMIZE_DATA));
+
+ wait_for_activated.Run();
+
+ NavigateToURL(shell(), GetTestUrl("", "about:blank"));
+
+ BackgroundTracingManager::GetInstance()->WhenIdle(
+ base::Bind(&DisableScenarioWhenIdle));
+
+ BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
+ handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
+
+ wait_for_upload.Run();
+
+ EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 1);
+ // We should *not* receive anything at all from the renderer,
+ // the process should've crashed rather than letting that happen.
+ EXPECT_TRUE(!upload_config_wrapper.TraceHasMatchingString("CrRendererMain"));
+}
+
// This tests multiple triggers still only gathers once.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
CallMultipleTriggersOnlyGatherOnce) {
@@ -194,7 +332,8 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
BackgroundTracingManager::GetInstance()->RegisterTriggerType("test2");
BackgroundTracingManager::GetInstance()->SetActiveScenario(
- config.Pass(), upload_config_wrapper.get_receive_callback(), true);
+ config.Pass(), upload_config_wrapper.get_receive_callback(),
+ BackgroundTracingManager::NO_DATA_FILTERING);
BackgroundTracingManager::GetInstance()->WhenIdle(
base::Bind(&DisableScenarioWhenIdle));
@@ -256,7 +395,8 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
"does_not_exist");
BackgroundTracingManager::GetInstance()->SetActiveScenario(
- config.Pass(), upload_config_wrapper.get_receive_callback(), true);
+ config.Pass(), upload_config_wrapper.get_receive_callback(),
+ BackgroundTracingManager::NO_DATA_FILTERING);
BackgroundTracingManager::GetInstance()->WhenIdle(
base::Bind(&DisableScenarioWhenIdle));
@@ -292,7 +432,8 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
->InvalidateTriggerHandlesForTesting();
BackgroundTracingManager::GetInstance()->SetActiveScenario(
- config.Pass(), upload_config_wrapper.get_receive_callback(), true);
+ config.Pass(), upload_config_wrapper.get_receive_callback(),
+ BackgroundTracingManager::NO_DATA_FILTERING);
BackgroundTracingManager::GetInstance()->WhenIdle(
base::Bind(&DisableScenarioWhenIdle));
@@ -327,7 +468,8 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
config->configs.push_back(rule);
bool result = BackgroundTracingManager::GetInstance()->SetActiveScenario(
- config.Pass(), upload_config_wrapper.get_receive_callback(), true);
+ config.Pass(), upload_config_wrapper.get_receive_callback(),
+ BackgroundTracingManager::NO_DATA_FILTERING);
EXPECT_FALSE(result);
}
@@ -351,7 +493,8 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
GetInstance()->RegisterTriggerType("reactive_test");
BackgroundTracingManager::GetInstance()->SetActiveScenario(
- config.Pass(), upload_config_wrapper.get_receive_callback(), true);
+ config.Pass(), upload_config_wrapper.get_receive_callback(),
+ BackgroundTracingManager::NO_DATA_FILTERING);
BackgroundTracingManager::GetInstance()->WhenIdle(
base::Bind(&DisableScenarioWhenIdle));
@@ -385,7 +528,8 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
GetInstance()->RegisterTriggerType("reactive_test");
BackgroundTracingManager::GetInstance()->SetActiveScenario(
- config.Pass(), upload_config_wrapper.get_receive_callback(), true);
+ config.Pass(), upload_config_wrapper.get_receive_callback(),
+ BackgroundTracingManager::NO_DATA_FILTERING);
BackgroundTracingManager::GetInstance()->WhenIdle(
base::Bind(&DisableScenarioWhenIdle));
@@ -420,7 +564,8 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
GetInstance()->RegisterTriggerType("reactive_test");
BackgroundTracingManager::GetInstance()->SetActiveScenario(
- config.Pass(), upload_config_wrapper.get_receive_callback(), true);
+ config.Pass(), upload_config_wrapper.get_receive_callback(),
+ BackgroundTracingManager::NO_DATA_FILTERING);
BackgroundTracingManager::GetInstance()->WhenIdle(
base::Bind(&DisableScenarioWhenIdle));
diff --git a/content/browser/tracing/background_tracing_manager_impl.cc b/content/browser/tracing/background_tracing_manager_impl.cc
index b636cc8..14f07cf 100644
--- a/content/browser/tracing/background_tracing_manager_impl.cc
+++ b/content/browser/tracing/background_tracing_manager_impl.cc
@@ -130,7 +130,7 @@ bool BackgroundTracingManagerImpl::IsSupportedConfig(
bool BackgroundTracingManagerImpl::SetActiveScenario(
scoped_ptr<BackgroundTracingConfig> config,
const BackgroundTracingManager::ReceiveCallback& receive_callback,
- bool requires_anonymized_data) {
+ DataFiltering data_filtering) {
CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
if (is_tracing_)
return false;
@@ -144,7 +144,7 @@ bool BackgroundTracingManagerImpl::SetActiveScenario(
config_ = config.Pass();
receive_callback_ = receive_callback;
- requires_anonymized_data_ = requires_anonymized_data;
+ requires_anonymized_data_ = (data_filtering == ANONYMIZE_DATA);
EnableRecordingIfConfigNeedsIt();
@@ -296,6 +296,11 @@ void BackgroundTracingManagerImpl::InvalidateTriggerHandlesForTesting() {
trigger_handles_.clear();
}
+void BackgroundTracingManagerImpl::SetTracingEnabledCallbackForTesting(
+ const base::Closure& callback) {
+ tracing_enabled_callback_for_testing_ = callback;
+};
+
void BackgroundTracingManagerImpl::FireTimerForTesting() {
tracing_timer_->FireTimerForTesting();
}
@@ -303,9 +308,12 @@ void BackgroundTracingManagerImpl::FireTimerForTesting() {
void BackgroundTracingManagerImpl::EnableRecording(
std::string category_filter_str,
base::trace_event::TraceRecordMode record_mode) {
+ base::trace_event::TraceConfig trace_config(category_filter_str, record_mode);
+ if (requires_anonymized_data_)
+ trace_config.EnableArgumentFilter();
+
is_tracing_ = TracingController::GetInstance()->EnableRecording(
- base::trace_event::TraceConfig(category_filter_str, record_mode),
- TracingController::EnableRecordingDoneCallback());
+ trace_config, tracing_enabled_callback_for_testing_);
}
void BackgroundTracingManagerImpl::OnFinalizeStarted(
@@ -314,7 +322,7 @@ void BackgroundTracingManagerImpl::OnFinalizeStarted(
if (!receive_callback_.is_null())
receive_callback_.Run(
- file_contents.get(),
+ file_contents,
base::Bind(&BackgroundTracingManagerImpl::OnFinalizeComplete,
base::Unretained(this)));
}
diff --git a/content/browser/tracing/background_tracing_manager_impl.h b/content/browser/tracing/background_tracing_manager_impl.h
index 9795629..0ce73f9 100644
--- a/content/browser/tracing/background_tracing_manager_impl.h
+++ b/content/browser/tracing/background_tracing_manager_impl.h
@@ -21,7 +21,7 @@ class BackgroundTracingManagerImpl : public content::BackgroundTracingManager {
bool SetActiveScenario(scoped_ptr<BackgroundTracingConfig>,
const ReceiveCallback&,
- bool) override;
+ DataFiltering data_filtering) override;
void WhenIdle(IdleCallback idle_callback) override;
void TriggerNamedEvent(TriggerHandle, StartedFinalizingCallback) override;
@@ -29,7 +29,8 @@ class BackgroundTracingManagerImpl : public content::BackgroundTracingManager {
void GetTriggerNameList(std::vector<std::string>* trigger_names) override;
void InvalidateTriggerHandlesForTesting() override;
-
+ void SetTracingEnabledCallbackForTesting(
+ const base::Closure& callback) override;
void FireTimerForTesting() override;
private:
@@ -94,6 +95,7 @@ class BackgroundTracingManagerImpl : public content::BackgroundTracingManager {
int trigger_handle_ids_;
IdleCallback idle_callback_;
+ base::Closure tracing_enabled_callback_for_testing_;
friend struct base::DefaultLazyInstanceTraits<BackgroundTracingManagerImpl>;
diff --git a/content/public/browser/background_tracing_manager.h b/content/public/browser/background_tracing_manager.h
index 87f3279..75e2d34 100644
--- a/content/public/browser/background_tracing_manager.h
+++ b/content/public/browser/background_tracing_manager.h
@@ -39,8 +39,8 @@ class BackgroundTracingManager {
// );
// }
//
- typedef base::Callback<void(const base::RefCountedString*, base::Closure)>
- ReceiveCallback;
+ typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&,
+ base::Closure)> ReceiveCallback;
// Set the triggering rules for when to start recording.
//
@@ -57,9 +57,13 @@ class BackgroundTracingManager {
// Calls to SetActiveScenario() with a config will fail if tracing is
// currently on. Use WhenIdle to register a callback to get notified when
// the manager is idle and a config can be set again.
+ enum DataFiltering {
+ NO_DATA_FILTERING,
+ ANONYMIZE_DATA,
+ };
virtual bool SetActiveScenario(scoped_ptr<BackgroundTracingConfig> config,
const ReceiveCallback& receive_callback,
- bool requires_anonymized_data) = 0;
+ DataFiltering data_filtering) = 0;
// Notifies the caller when the manager is idle (not recording or uploading),
// so that a call to SetActiveScenario() is likely to succeed.
@@ -84,7 +88,8 @@ class BackgroundTracingManager {
virtual void GetTriggerNameList(std::vector<std::string>* trigger_names) = 0;
virtual void InvalidateTriggerHandlesForTesting() = 0;
-
+ virtual void SetTracingEnabledCallbackForTesting(
+ const base::Closure& callback) = 0;
virtual void FireTimerForTesting() = 0;
protected: