OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/safe_browsing/sandboxed_zip_analyzer.h" | 5 #include "chrome/browser/safe_browsing/sandboxed_zip_analyzer.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/files/file_util.h" | |
9 #include "base/location.h" | 10 #include "base/location.h" |
10 #include "base/logging.h" | 11 #include "base/logging.h" |
11 #include "base/threading/sequenced_worker_pool.h" | 12 #include "base/threading/sequenced_worker_pool.h" |
12 #include "chrome/common/chrome_utility_messages.h" | 13 #include "chrome/common/chrome_utility_messages.h" |
13 #include "chrome/common/safe_browsing/zip_analyzer.h" | 14 #include "chrome/common/safe_browsing/zip_analyzer_results.h" |
14 #include "content/public/browser/browser_thread.h" | 15 #include "content/public/browser/browser_thread.h" |
15 #include "content/public/browser/child_process_data.h" | 16 #include "content/public/browser/child_process_data.h" |
16 #include "content/public/browser/render_process_host.h" | 17 #include "content/public/browser/render_process_host.h" |
17 #include "content/public/common/content_switches.h" | 18 #include "content/public/common/content_switches.h" |
18 #include "ipc/ipc_message_macros.h" | 19 #include "ipc/ipc_message_macros.h" |
19 #include "ipc/ipc_platform_file.h" | 20 #include "ipc/ipc_platform_file.h" |
20 | 21 |
21 using content::BrowserThread; | 22 using content::BrowserThread; |
22 | 23 |
23 namespace safe_browsing { | 24 namespace safe_browsing { |
(...skipping 14 matching lines...) Expand all Loading... | |
38 FROM_HERE, | 39 FROM_HERE, |
39 base::Bind(&SandboxedZipAnalyzer::AnalyzeInSandbox, this), | 40 base::Bind(&SandboxedZipAnalyzer::AnalyzeInSandbox, this), |
40 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)) { | 41 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)) { |
41 NOTREACHED(); | 42 NOTREACHED(); |
42 } | 43 } |
43 } | 44 } |
44 | 45 |
45 SandboxedZipAnalyzer::~SandboxedZipAnalyzer() { | 46 SandboxedZipAnalyzer::~SandboxedZipAnalyzer() { |
46 // If we're using UtilityProcessHost, we may not be destroyed on | 47 // If we're using UtilityProcessHost, we may not be destroyed on |
47 // the UI or IO thread. | 48 // the UI or IO thread. |
49 CloseTemporaryFile(); | |
48 } | 50 } |
49 | 51 |
50 void SandboxedZipAnalyzer::AnalyzeInSandbox() { | 52 void SandboxedZipAnalyzer::AnalyzeInSandbox() { |
53 // This zip file will be closed on the IO thread once it has been handed | |
54 // off to the child process. | |
51 zip_file_.Initialize(zip_file_name_, | 55 zip_file_.Initialize(zip_file_name_, |
52 base::File::FLAG_OPEN | base::File::FLAG_READ); | 56 base::File::FLAG_OPEN | base::File::FLAG_READ); |
53 if (!zip_file_.IsValid()) { | 57 if (!zip_file_.IsValid()) { |
54 DVLOG(1) << "Could not open zip file: " << zip_file_name_.value(); | 58 DVLOG(1) << "Could not open zip file: " << zip_file_name_.value(); |
55 if (!BrowserThread::PostTask( | 59 if (!BrowserThread::PostTask( |
56 BrowserThread::IO, FROM_HERE, | 60 BrowserThread::IO, FROM_HERE, |
57 base::Bind(&SandboxedZipAnalyzer::OnAnalyzeZipFileFinished, this, | 61 base::Bind(&SandboxedZipAnalyzer::OnAnalyzeZipFileFinished, this, |
58 zip_analyzer::Results()))) { | 62 zip_analyzer::Results()))) { |
59 NOTREACHED(); | 63 NOTREACHED(); |
60 } | 64 } |
61 return; | 65 return; |
62 } | 66 } |
63 | 67 |
68 // This temp file will be closed in the blocking pool when results from the | |
69 // analyzer return. | |
70 base::FilePath temp_path; | |
71 if (base::CreateTemporaryFile(&temp_path)) { | |
72 temp_file_.Initialize(temp_path, (base::File::FLAG_CREATE_ALWAYS | | |
73 base::File::FLAG_READ | | |
74 base::File::FLAG_WRITE | | |
75 base::File::FLAG_TEMPORARY | | |
76 base::File::FLAG_DELETE_ON_CLOSE)); | |
77 } | |
78 DVLOG_IF(1, !temp_file_.IsValid()) | |
79 << "Could not open temporary output file: " << temp_path.value(); | |
80 | |
64 BrowserThread::PostTask( | 81 BrowserThread::PostTask( |
65 BrowserThread::IO, FROM_HERE, | 82 BrowserThread::IO, FROM_HERE, |
66 base::Bind(&SandboxedZipAnalyzer::StartProcessOnIOThread, this)); | 83 base::Bind(&SandboxedZipAnalyzer::StartProcessOnIOThread, this)); |
67 // The file will be closed on the IO thread once it has been handed | |
68 // off to the child process. | |
69 } | 84 } |
70 | 85 |
71 bool SandboxedZipAnalyzer::OnMessageReceived(const IPC::Message& message) { | 86 bool SandboxedZipAnalyzer::OnMessageReceived(const IPC::Message& message) { |
72 bool handled = true; | 87 bool handled = true; |
73 IPC_BEGIN_MESSAGE_MAP(SandboxedZipAnalyzer, message) | 88 IPC_BEGIN_MESSAGE_MAP(SandboxedZipAnalyzer, message) |
74 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ProcessStarted, | 89 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ProcessStarted, |
75 OnUtilityProcessStarted) | 90 OnUtilityProcessStarted) |
76 IPC_MESSAGE_HANDLER( | 91 IPC_MESSAGE_HANDLER( |
77 ChromeUtilityHostMsg_AnalyzeZipFileForDownloadProtection_Finished, | 92 ChromeUtilityHostMsg_AnalyzeZipFileForDownloadProtection_Finished, |
78 OnAnalyzeZipFileFinished) | 93 OnAnalyzeZipFileFinished) |
79 IPC_MESSAGE_UNHANDLED(handled = false) | 94 IPC_MESSAGE_UNHANDLED(handled = false) |
80 IPC_END_MESSAGE_MAP() | 95 IPC_END_MESSAGE_MAP() |
81 return handled; | 96 return handled; |
82 } | 97 } |
83 | 98 |
84 void SandboxedZipAnalyzer::OnAnalyzeZipFileFinished( | 99 void SandboxedZipAnalyzer::OnAnalyzeZipFileFinished( |
85 const zip_analyzer::Results& results) { | 100 const zip_analyzer::Results& results) { |
86 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 101 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
87 if (callback_called_) | 102 if (callback_called_) |
88 return; | 103 return; |
89 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 104 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
90 base::Bind(callback_, results)); | 105 base::Bind(callback_, results)); |
91 callback_called_ = true; | 106 callback_called_ = true; |
107 CloseTemporaryFile(); | |
92 } | 108 } |
93 | 109 |
94 void SandboxedZipAnalyzer::StartProcessOnIOThread() { | 110 void SandboxedZipAnalyzer::StartProcessOnIOThread() { |
95 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 111 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
96 utility_process_host_ = content::UtilityProcessHost::Create( | 112 utility_process_host_ = content::UtilityProcessHost::Create( |
97 this, | 113 this, |
98 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get()) | 114 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get()) |
99 ->AsWeakPtr(); | 115 ->AsWeakPtr(); |
100 utility_process_host_->Send(new ChromeUtilityMsg_StartupPing); | 116 utility_process_host_->Send(new ChromeUtilityMsg_StartupPing); |
101 // Wait for the startup notification before sending the main IPC to the | 117 // Wait for the startup notification before sending the main IPC to the |
102 // utility process, so that we can dup the file handle. | 118 // utility process, so that we can dup the file handle. |
103 } | 119 } |
104 | 120 |
121 void SandboxedZipAnalyzer::CloseTemporaryFile() { | |
mattm
2015/03/23 01:53:40
nit: I'd move this so that StartProcessOnIOThread
grt (UTC plus 2)
2015/03/23 13:29:16
Done. I also made the order in the .h match that h
| |
122 if (!temp_file_.IsValid()) | |
123 return; | |
124 // Close the temporary file in the blocking pool since doing so will delete | |
125 // the file. | |
126 if (!BrowserThread::GetBlockingPool()->PostWorkerTaskWithShutdownBehavior( | |
127 FROM_HERE, base::Bind(&base::File::Close, | |
128 base::Owned(new base::File(temp_file_.Pass()))), | |
129 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)) { | |
130 NOTREACHED(); | |
131 } | |
132 } | |
133 | |
105 void SandboxedZipAnalyzer::OnUtilityProcessStarted() { | 134 void SandboxedZipAnalyzer::OnUtilityProcessStarted() { |
106 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 135 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
107 base::ProcessHandle utility_process = | 136 base::ProcessHandle utility_process = |
108 content::RenderProcessHost::run_renderer_in_process() ? | 137 content::RenderProcessHost::run_renderer_in_process() ? |
109 base::GetCurrentProcessHandle() : | 138 base::GetCurrentProcessHandle() : |
110 utility_process_host_->GetData().handle; | 139 utility_process_host_->GetData().handle; |
111 | 140 |
112 if (utility_process == base::kNullProcessHandle) { | 141 if (utility_process == base::kNullProcessHandle) { |
113 DLOG(ERROR) << "Child process handle is null"; | 142 DLOG(ERROR) << "Child process handle is null"; |
114 } | 143 } |
115 utility_process_host_->Send( | 144 utility_process_host_->Send( |
116 new ChromeUtilityMsg_AnalyzeZipFileForDownloadProtection( | 145 new ChromeUtilityMsg_AnalyzeZipFileForDownloadProtection( |
117 IPC::TakeFileHandleForProcess(zip_file_.Pass(), utility_process))); | 146 IPC::TakeFileHandleForProcess(zip_file_.Pass(), utility_process), |
147 IPC::GetFileHandleForProcess(temp_file_.GetPlatformFile(), | |
148 utility_process, | |
149 false /* !close_source_handle */))); | |
118 } | 150 } |
119 | 151 |
120 } // namespace safe_browsing | 152 } // namespace safe_browsing |
OLD | NEW |