Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(260)

Side by Side Diff: chrome/browser/nacl_host/pnacl_file_host.cc

Issue 9158005: RFC: Add an interface for having the browser open a pnacl support file (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add a test, do some tweaks. Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/nacl_host/pnacl_file_host.h"
6
7 #include <stdio.h>
8
9 #include "base/bind.h"
10 #include "base/file_path.h"
11 #include "base/file_util.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/path_service.h"
14 #include "base/platform_file.h"
15 #include "chrome/common/chrome_paths.h"
16 #include "chrome/common/render_messages.h"
17 #include "chrome/browser/renderer_host/chrome_render_message_filter.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "native_client/src/shared/imc/nacl_imc.h"
20
21 using content::BrowserThread;
22
23 namespace {
24
25 // Need the DuplicateHandle good to send the handle over to the
26 // plugin process.
27 // TODO(jvoung): share some code with nacl_process_host if possible.
28 bool SendHandleToNaClPlugin(
29 base::ProcessHandle target_processh,
30 nacl::Handle sourceh,
31 bool close_source,
32 nacl::FileDescriptor* handle_for_plugin) {
33 #if defined(OS_WIN)
34 HANDLE channel;
35 int flags = DUPLICATE_SAME_ACCESS;
36 if (close_source)
37 flags |= DUPLICATE_CLOSE_SOURCE;
38 if (!DuplicateHandle(GetCurrentProcess(),
39 reinterpret_cast<HANDLE>(sourceh),
40 target_processh,
41 &channel,
42 0, // Unused given DUPLICATE_SAME_ACCESS.
43 FALSE,
44 flags)) {
45 LOG(ERROR) << "DuplicateHandle() failed";
46 return false;
47 }
48 *handle_for_plugin = reinterpret_cast<nacl::FileDescriptor>(channel);
49 #else
50 nacl::FileDescriptor channel;
51 channel.fd = sourceh;
52 channel.auto_close = close_source;
53 *handle_for_plugin = channel;
54 #endif
55 return true;
56 }
57
58 void NotifyRendererOfError(
59 ChromeRenderMessageFilter* chrome_render_message_filter,
60 IPC::Message* reply_msg) {
61 reply_msg->set_reply_error();
62 chrome_render_message_filter->Send(reply_msg);
63 }
64
65 // This only ever runs on the BrowserThread::FILE thread.
66 // TODO(jvoung): assert that.
67 void DoOpenPnaclFile(
68 ChromeRenderMessageFilter* chrome_render_message_filter,
69 std::string filename,
70 IPC::Message* reply_msg) {
71 FilePath full_filepath;
72
73 // Do some validation.
74 if (!pnacl_file_host::PnaclCanOpenFile(filename, &full_filepath)) {
75 LOG(ERROR) << "Failed to validate Pnacl filename: " << filename;
76 NotifyRendererOfError(chrome_render_message_filter, reply_msg);
77 return;
78 }
79
80 base::PlatformFile file_to_open;
81 if (!pnacl_file_host::PnaclDoOpenFile(full_filepath, &file_to_open)) {
82 NotifyRendererOfError(chrome_render_message_filter, reply_msg);
83 }
84
85
86 // Send the reply!
87 // Do any DuplicateHandle magic that is necessary first.
88 nacl::FileDescriptor target_desc;
89 SendHandleToNaClPlugin(chrome_render_message_filter->peer_handle(),
90 file_to_open,
91 true /* Close source */,
92 &target_desc);
93 ChromeViewHostMsg_GetReadonlyPnaclFD::WriteReplyParams(
94 reply_msg, target_desc);
95 chrome_render_message_filter->Send(reply_msg);
96 }
97
98 } // namespace
99
100 namespace pnacl_file_host {
101
102 void GetReadonlyPnaclFd(
103 ChromeRenderMessageFilter* chrome_render_message_filter,
104 const std::string& filename,
105 IPC::Message* reply_msg) {
106 fprintf(stderr, "In GetReadonlyPnaclFd: %s\n", filename.c_str());
107
108 if (!BrowserThread::PostTask(
109 BrowserThread::FILE, FROM_HERE,
110 base::Bind(&DoOpenPnaclFile,
111 make_scoped_refptr(chrome_render_message_filter),
112 filename,
113 reply_msg))) {
114 NotifyRendererOfError(chrome_render_message_filter, reply_msg);
115 }
116 }
117
118 bool PnaclCanOpenFile(const std::string& filename,
119 FilePath *file_to_open) {
120 // Do some validation.
121 // The file must use only ASCII characters.
122 if (!IsStringASCII(filename)) {
123 LOG(ERROR) << "not ASCII: " << filename;
124 return false;
125 }
126
127 if (filename.find('%') != std::string::npos ||
128 filename.find('$') != std::string::npos) {
129 LOG(ERROR) << "Has funny symbols " << filename;
130 return false;
131 }
132
133 #if defined(OS_WIN)
134 FilePath file_to_find(ASCIIToUTF16(filename));
135 #elif defined(OS_POSIX)
136 FilePath file_to_find(filename);
137 #endif
138
139 if (file_to_find.empty() || file_util::IsDot(file_to_find)) {
140 LOG(ERROR) << "Empty or dot " << file_to_find.LossyDisplayName();
141 return false;
142 }
143
144 // Disallow peeking outside of the pnacl component directory.
145 if (file_to_find.ReferencesParent() || file_to_find.IsAbsolute()) {
146 LOG(ERROR) << "ReferencesParent or IsAbsolute: "
147 << file_to_find.LossyDisplayName();
148 return false;
149 }
150
151 // Disallow special shell characters, just in case...
152
153 FilePath pnacl_dir;
154 if (!PathService::Get(chrome::DIR_PNACL_COMPONENT, &pnacl_dir)) {
155 LOG(ERROR) << "No DIR_PNACL_COMPONENT";
156 return false;
157 }
158 if (pnacl_dir.empty()) {
159 LOG(ERROR) << "pnacl_dir is empty: " << pnacl_dir.LossyDisplayName();
160 return false;
161 }
162
163 FilePath full_path = pnacl_dir.Append(file_to_find);
164 *file_to_open = full_path;
165 return true;
166 }
167
168 bool PnaclDoOpenFile(const FilePath& file_to_open,
169 base::PlatformFile* out_file) {
170 base::PlatformFileError error_code;
171 *out_file = base::CreatePlatformFile(file_to_open,
172 base::PLATFORM_FILE_OPEN |
173 base::PLATFORM_FILE_READ |
174 base::PLATFORM_FILE_SHARE_DELETE,
175 NULL,
176 &error_code);
177 if (error_code != base::PLATFORM_FILE_OK) {
178 LOG(ERROR) << "Failed to open Pnacl file \""
179 << file_to_open.LossyDisplayName()
180 << "\": " << error_code;
181 return false;
182 }
183 return true;
184 }
185
186 } // namespace pnacl_file_host
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698