diff options
-rw-r--r-- | chrome/browser/renderer_host/resource_message_filter.cc | 22 | ||||
-rw-r--r-- | chrome/browser/renderer_host/resource_message_filter.h | 3 | ||||
-rw-r--r-- | chrome/common/render_messages.h | 24 | ||||
-rw-r--r-- | chrome/common/render_messages_internal.h | 7 | ||||
-rw-r--r-- | chrome/renderer/webplugin_delegate_pepper.cc | 33 | ||||
-rw-r--r-- | chrome/renderer/webplugin_delegate_pepper.h | 2 | ||||
-rw-r--r-- | webkit/glue/pepper/pepper.h | 4 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_host.cc | 11 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl.h | 59 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl_mac.mm | 8 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl_win.cc | 33 | ||||
-rw-r--r-- | webkit/glue/webkitclient_impl.cc | 3 | ||||
-rw-r--r-- | webkit/glue/webplugin_delegate.h | 4 | ||||
-rw-r--r-- | webkit/tools/pepper_test_plugin/plugin_object.cc | 34 |
14 files changed, 178 insertions, 69 deletions
diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc index 5b4aa81..f817a9b 100644 --- a/chrome/browser/renderer_host/resource_message_filter.cc +++ b/chrome/browser/renderer_host/resource_message_filter.cc @@ -390,6 +390,7 @@ bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(ViewHostMsg_SetCacheMode, OnSetCacheMode) IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetFileSize, OnGetFileSize) IPC_MESSAGE_HANDLER(ViewHostMsg_Keygen, OnKeygen) + IPC_MESSAGE_HANDLER(ViewMsg_OpenFileForPlugin, OnOpenFileForPlugin) #if defined(USE_TCMALLOC) IPC_MESSAGE_HANDLER(ViewHostMsg_RendererTcmalloc, OnRendererTcmalloc) #endif @@ -399,9 +400,8 @@ bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& msg) { IPC_END_MESSAGE_MAP_EX() } - if (!msg_is_ok) { + if (!msg_is_ok) BrowserRenderProcessHost::BadMessageTerminateProcess(msg.type(), handle()); - } return handled; } @@ -1163,6 +1163,24 @@ void ResourceMessageFilter::OnKeygen(uint32 key_size_index, *signed_public_key = keygen_handler->GenKeyAndSignChallenge(); } +void ResourceMessageFilter::OnOpenFileForPlugin( + const FilePath& file_name, + ViewMsg_OpenFileForPluginResponse_Params* result) { + // TODO(brettw) finish up this API. This will allow sandboxed plugins to open + // certain restricted files by opening the file from the browser and + // duplicating the file into the renderer. + // + // This needs to be done with care because of the security implications. Don't + // implement this without getting a thorough security review. +#if defined(OS_WIN) + result->file_handle = NULL; +#elif defined(OS_POSIX) + // TODO(brettw) this currently violates the API provided since it specifies + // NULL means error, and this will give -1. We need to be consistent. + result->file_handle = base::FileDescriptor(); +#endif +} + #if defined(USE_TCMALLOC) void ResourceMessageFilter::OnRendererTcmalloc(base::ProcessId pid, const std::string& output) { diff --git a/chrome/browser/renderer_host/resource_message_filter.h b/chrome/browser/renderer_host/resource_message_filter.h index 0184591..82a9383 100644 --- a/chrome/browser/renderer_host/resource_message_filter.h +++ b/chrome/browser/renderer_host/resource_message_filter.h @@ -59,6 +59,7 @@ struct WebScreenInfo; } struct ViewHostMsg_ScriptedPrint_Params; +struct ViewMsg_OpenFileForPluginResponse_Params; #if defined(OS_LINUX) struct ViewHostMsg_DidPrintPage_Params; #endif @@ -284,6 +285,8 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter, void OnGetFileSizeOnFileThread(const FilePath& path, IPC::Message* reply_msg); void OnKeygen(uint32 key_size_index, const std::string& challenge_string, const GURL& url, std::string* signed_public_key); + void OnOpenFileForPlugin(const FilePath& file_path, + ViewMsg_OpenFileForPluginResponse_Params* result); #if defined(OS_LINUX) void SendDelayedReply(IPC::Message* reply_msg); void DoOnGetScreenInfo(gfx::NativeViewId view, IPC::Message* reply_msg); diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h index 3216721..57ba3b4 100644 --- a/chrome/common/render_messages.h +++ b/chrome/common/render_messages.h @@ -396,6 +396,16 @@ struct ViewMsg_DatabaseOpenFileResponse_Params { #endif }; +struct ViewMsg_OpenFileForPluginResponse_Params { + // Note: if we end up having to add a directory handle, this should be + // combined with the DatabaseOpenFileResponse_Params struct. +#if defined(OS_WIN) + base::PlatformFile file_handle; +#elif defined(OS_POSIX) + base::FileDescriptor file_handle; +#endif +}; + // Parameters to describe a rendered page. struct ViewHostMsg_DidPrintPage_Params { // A shared memory handle to the EMF data. This data can be quite large so a @@ -1775,6 +1785,20 @@ struct ParamTraits<ViewMsg_DatabaseOpenFileResponse_Params> { }; template <> +struct ParamTraits<ViewMsg_OpenFileForPluginResponse_Params> { + typedef ViewMsg_OpenFileForPluginResponse_Params param_type; + static void Write(Message* m, const param_type& p) { + WriteParam(m, p.file_handle); + } + static bool Read(const Message* m, void** iter, param_type* p) { + return ReadParam(m, iter, &p->file_handle); + } + static void Log(const param_type& p, std::wstring* l) { + LogParam(p.file_handle, l); + } +}; + +template <> struct ParamTraits<appcache::Status> { typedef appcache::Status param_type; static void Write(Message* m, const param_type& p) { diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index 4b45f8f..f3887f0 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -781,6 +781,13 @@ IPC_BEGIN_MESSAGES(View) bool /* on or off */) #endif + // Opens the given file for the sandboxed plugin, returning a handle + // duplicated into the destination process. On error, or if the file is not + // permitted by the security policy, the response will contain a 0 handle. + IPC_SYNC_MESSAGE_CONTROL1_1(ViewMsg_OpenFileForPlugin, + FilePath, /* file_name */ + ViewMsg_OpenFileForPluginResponse_Params) + //--------------------------------------------------------------------------- // Utility process messages: // These are messages from the browser to the utility process. They're here diff --git a/chrome/renderer/webplugin_delegate_pepper.cc b/chrome/renderer/webplugin_delegate_pepper.cc index 30d29b7..1621406 100644 --- a/chrome/renderer/webplugin_delegate_pepper.cc +++ b/chrome/renderer/webplugin_delegate_pepper.cc @@ -16,6 +16,8 @@ #include "base/scoped_ptr.h" #include "base/stats_counters.h" #include "base/string_util.h" +#include "chrome/common/render_messages.h" +#include "chrome/renderer/render_thread.h" #include "webkit/api/public/WebInputEvent.h" #include "webkit/glue/glue_util.h" #include "webkit/glue/pepper/pepper.h" @@ -36,7 +38,9 @@ using WebKit::WebMouseEvent; using WebKit::WebMouseWheelEvent; namespace { - const uint32 kBytesPerPixel = 4; // Only 8888 RGBA for now. + +const uint32 kBytesPerPixel = 4; // Only 8888 RGBA for now. + } // namespace uint32 WebPluginDelegatePepper::next_buffer_id = 0; @@ -444,3 +448,30 @@ NPError WebPluginDelegatePepper::FlushRenderContext(NPRenderContext* context) { committed_bitmap_.setIsOpaque(false); return NPERR_NO_ERROR; } + +NPError WebPluginDelegatePepper::OpenFileInSandbox(const char* file_name, + void** handle) { + *handle = NULL; + +#if defined(OS_WIN) + FilePath file_path(UTF8ToUTF16(file_name)); +#elif defined(OS_POSIX) + FilePath file_path(file_name); +#endif + + ViewMsg_OpenFileForPluginResponse_Params result; + RenderThread::current()->Send(new ViewMsg_OpenFileForPlugin( + file_path, &result)); + +#if defined(OS_WIN) + if (!result.file_handle) + return NPERR_INVALID_PARAM; + *handle = result.file_handle; +#elif defined(OS_POSIX) + if (result.file_handle.fd == -1) + return NPERR_INVALID_PARAM; + *reinterpret_cast<int*>(handle) = result.file_handle.fd; +#endif + + return NPERR_NO_ERROR; +} diff --git a/chrome/renderer/webplugin_delegate_pepper.h b/chrome/renderer/webplugin_delegate_pepper.h index 214ff43..caba02a 100644 --- a/chrome/renderer/webplugin_delegate_pepper.h +++ b/chrome/renderer/webplugin_delegate_pepper.h @@ -99,6 +99,8 @@ class WebPluginDelegatePepper : public webkit_glue::WebPluginDelegate { NPRenderContext* context); virtual NPError FlushRenderContext(NPRenderContext* context); + virtual NPError OpenFileInSandbox(const char* file_name, void** handle); + // Tells the plugin about the current state of the window. // See NPAPI NPP_SetWindow for more information. void WindowlessSetWindow(bool force_set_window); diff --git a/webkit/glue/pepper/pepper.h b/webkit/glue/pepper/pepper.h index 901109b..9ae47f9 100644 --- a/webkit/glue/pepper/pepper.h +++ b/webkit/glue/pepper/pepper.h @@ -149,6 +149,7 @@ typedef NPError (*NPFlushRenderContextPtr)(NPP instance, void* userData); typedef NPError (*NPDestroyRenderContextPtr)(NPP instance, NPRenderContext* context); +typedef NPError (*NPOpenFilePtr)(NPP instance, const char* fileName, void** handle); typedef struct _NPPepperExtensions { @@ -157,6 +158,9 @@ typedef struct _NPPepperExtensions NPFlushRenderContextPtr flushRender; NPDestroyRenderContextPtr destroyRender; /* Shared memory extensions */ + + /* I/O extensions */ + NPOpenFilePtr openFile; } NPPepperExtensions; #endif /* PEPPER_APIS_ENABLED */ diff --git a/webkit/glue/plugins/plugin_host.cc b/webkit/glue/plugins/plugin_host.cc index 5385dda..efd84af 100644 --- a/webkit/glue/plugins/plugin_host.cc +++ b/webkit/glue/plugins/plugin_host.cc @@ -702,6 +702,14 @@ static NPError DestroyRenderContext(NPP id, // TODO(sehr) implement render context destruction. return NPERR_GENERIC_ERROR; } + +static NPError OpenFileInSandbox(NPP id, const char* file_name, void** handle) { + scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + if (!plugin) + return NPERR_GENERIC_ERROR; + webkit_glue::WebPluginDelegate* delegate = plugin->webplugin()->delegate(); + return delegate->OpenFileInSandbox(file_name, handle); +} #endif // defined(PEPPER_APIS_ENABLED) NPError NPN_GetValue(NPP id, NPNVariable variable, void *value) { @@ -862,7 +870,8 @@ NPError NPN_GetValue(NPP id, NPNVariable variable, void *value) { static const NPPepperExtensions kExtensions = { InitializeRenderContext, FlushRenderContext, - DestroyRenderContext + DestroyRenderContext, + OpenFileInSandbox, }; // Return a pointer to the canonical function table. NPPepperExtensions* extensions = diff --git a/webkit/glue/plugins/webplugin_delegate_impl.h b/webkit/glue/plugins/webplugin_delegate_impl.h index 65e01b6..8384e73 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl.h +++ b/webkit/glue/plugins/webplugin_delegate_impl.h @@ -270,7 +270,34 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { // a plugin in the course of a NPP_HandleEvent call. static LRESULT CALLBACK HandleEventMessageFilterHook(int code, WPARAM wParam, LPARAM lParam); + + // TrackPopupMenu interceptor. Parameters are the same as the Win32 function + // TrackPopupMenu. + static BOOL WINAPI TrackPopupMenuPatch(HMENU menu, unsigned int flags, int x, + int y, int reserved, HWND window, + const RECT* rect); + + // SetCursor interceptor for windowless plugins. + static HCURSOR WINAPI SetCursorPatch(HCURSOR cursor); + + // RegEnumKeyExW interceptor. + static LONG WINAPI RegEnumKeyExWPatch( + HKEY key, DWORD index, LPWSTR name, LPDWORD name_size, LPDWORD reserved, + LPWSTR class_name, LPDWORD class_size, PFILETIME last_write_time); + +#elif defined(OS_MACOSX) + + // Indicates that it's time to send the plugin a null event. + void OnNullEvent(); + + // Runnable Method Factory used to drip null events into the plugin. + ScopedRunnableMethodFactory<WebPluginDelegateImpl> null_event_factory_; + + // Last mouse position within the plugin's rect (used for null events). + int last_mouse_x_; + int last_mouse_y_; #endif + // Called by the message filter hook when the plugin enters a modal loop. void OnModalLoopEntered(); @@ -286,11 +313,9 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { #if defined(OS_WIN) // Handle to the message filter hook HHOOK handle_event_message_filter_hook_; -#endif // Event which is set when the plugin enters a modal loop in the course // of a NPP_HandleEvent call. -#if defined(OS_WIN) HANDLE handle_event_pump_messages_event_; #endif @@ -306,38 +331,10 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { ScopedRunnableMethodFactory<WebPluginDelegateImpl> user_gesture_msg_factory_; #endif -#if defined(OS_WIN) - // TrackPopupMenu interceptor. Parameters are the same as the Win32 function - // TrackPopupMenu. - static BOOL WINAPI TrackPopupMenuPatch(HMENU menu, unsigned int flags, int x, - int y, int reserved, HWND window, - const RECT* rect); - - // SetCursor interceptor for windowless plugins. - static HCURSOR WINAPI SetCursorPatch(HCURSOR cursor); - - // RegEnumKeyExW interceptor. - static LONG WINAPI RegEnumKeyExWPatch( - HKEY key, DWORD index, LPWSTR name, LPDWORD name_size, LPDWORD reserved, - LPWSTR class_name, LPDWORD class_size, PFILETIME last_write_time); -#endif - -#if defined(OS_MACOSX) - // Runnable Method Factory used to drip null events into the plugin - ScopedRunnableMethodFactory<WebPluginDelegateImpl> null_event_factory_; - - // indicates that it's time to send the plugin a null event - void OnNullEvent(); - - // last mouse position within the plugin's rect (used for null events) - int last_mouse_x_; - int last_mouse_y_; -#endif - // Holds the current cursor set by the windowless plugin. WebCursor current_windowless_cursor_; DISALLOW_COPY_AND_ASSIGN(WebPluginDelegateImpl); }; -#endif // #ifndef WEBKIT_GLUE_PLUGIN_WEBPLUGIN_DELEGATE_IMPL_H_ +#endif // WEBKIT_GLUE_PLUGIN_WEBPLUGIN_DELEGATE_IMPL_H_ diff --git a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm index 5452e61..d51e4fc 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm +++ b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm @@ -102,12 +102,12 @@ WebPluginDelegateImpl::WebPluginDelegateImpl( parent_(containing_view), qd_world_(0), quirks_(0), - handle_event_depth_(0), - user_gesture_message_posted_(this), - user_gesture_msg_factory_(this), null_event_factory_(this), last_mouse_x_(0), - last_mouse_y_(0) { + last_mouse_y_(0), + handle_event_depth_(0), + user_gesture_message_posted_(this), + user_gesture_msg_factory_(this) { memset(&window_, 0, sizeof(window_)); #ifndef NP_NO_QUICKDRAW memset(&qd_port_, 0, sizeof(qd_port_)); diff --git a/webkit/glue/plugins/webplugin_delegate_impl_win.cc b/webkit/glue/plugins/webplugin_delegate_impl_win.cc index 330cb39..9c28d0f 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl_win.cc +++ b/webkit/glue/plugins/webplugin_delegate_impl_win.cc @@ -437,18 +437,18 @@ bool WebPluginDelegateImpl::WindowedCreatePlugin() { // The window will be sized and shown later. windowed_handle_ = CreateWindowEx( - WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR, - kNativeWindowClassName, - 0, - WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, - 0, - 0, - 0, - 0, - parent_, - 0, - GetModuleHandle(NULL), - 0); + WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR, + kNativeWindowClassName, + 0, + WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, + 0, + 0, + 0, + 0, + parent_, + 0, + GetModuleHandle(NULL), + 0); if (windowed_handle_ == 0) return false; @@ -559,10 +559,11 @@ void WebPluginDelegateImpl::OnThrottleMessage() { } } - if (throttle_queue->size() > 0) + if (throttle_queue->size() > 0) { MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableFunction(&WebPluginDelegateImpl::OnThrottleMessage), kFlashWMUSERMessageThrottleDelayMs); + } } // Schedule a windows message for delivery later. @@ -756,7 +757,7 @@ void WebPluginDelegateImpl::WindowedSetWindow() { ATOM WebPluginDelegateImpl::RegisterNativeWindowClass() { static bool have_registered_window_class = false; if (have_registered_window_class == true) - return true; + return true; have_registered_window_class = true; @@ -856,7 +857,7 @@ LRESULT CALLBACK WebPluginDelegateImpl::NativeWndProc( delegate->is_calling_wndproc = true; if (!delegate->user_gesture_message_posted_ && - IsUserGestureMessage(message)) { + IsUserGestureMessage(message)) { delegate->user_gesture_message_posted_ = true; delegate->instance()->PushPopupsEnabledState(true); @@ -874,7 +875,7 @@ LRESULT CALLBACK WebPluginDelegateImpl::NativeWndProc( if (message == WM_NCDESTROY) { RemoveProp(hwnd, kWebPluginDelegateProperty); - ATOM plugin_name_atom = reinterpret_cast <ATOM>( + ATOM plugin_name_atom = reinterpret_cast<ATOM>( RemoveProp(hwnd, kPluginNameAtomProperty)); if (plugin_name_atom != 0) GlobalDeleteAtom(plugin_name_atom); diff --git a/webkit/glue/webkitclient_impl.cc b/webkit/glue/webkitclient_impl.cc index a578d7c..50ffbd1 100644 --- a/webkit/glue/webkitclient_impl.cc +++ b/webkit/glue/webkitclient_impl.cc @@ -389,8 +389,7 @@ WebKit::WebString WebKitClientImpl::pathByAppendingComponent( return webkit_glue::FilePathStringToWebString(combined_path.value()); } -bool WebKitClientImpl::makeAllDirectories( - const WebKit::WebString& path) { +bool WebKitClientImpl::makeAllDirectories(const WebKit::WebString& path) { DCHECK(!sandboxEnabled()); FilePath::StringType file_path = webkit_glue::WebStringToFilePathString(path); return file_util::CreateDirectory(FilePath(file_path)); diff --git a/webkit/glue/webplugin_delegate.h b/webkit/glue/webplugin_delegate.h index a2df27f..3d4515e 100644 --- a/webkit/glue/webplugin_delegate.h +++ b/webkit/glue/webplugin_delegate.h @@ -137,6 +137,10 @@ class WebPluginDelegate { virtual NPError FlushRenderContext(NPRenderContext* context) { return NPERR_GENERIC_ERROR; } + + virtual NPError OpenFileInSandbox(const char* file_name, void** handle) { + return NPERR_GENERIC_ERROR; + } }; } // namespace webkit_glue diff --git a/webkit/tools/pepper_test_plugin/plugin_object.cc b/webkit/tools/pepper_test_plugin/plugin_object.cc index bd3e9e2..8af7591 100644 --- a/webkit/tools/pepper_test_plugin/plugin_object.cc +++ b/webkit/tools/pepper_test_plugin/plugin_object.cc @@ -25,6 +25,7 @@ #include "webkit/tools/pepper_test_plugin/plugin_object.h" +#include <stdio.h> #include <string> #include "base/logging.h" @@ -223,8 +224,7 @@ void DrawSampleBitmap(SkCanvas& canvas, int width, int height) { canvas.drawPath(path, paint); } -NPInitializeRenderContextPtr initialize_render_context = NULL; -NPFlushRenderContextPtr flush_render_context = NULL; +NPPepperExtensions* pepper = NULL; void FlushCallback(NPRenderContext* context, void* user_data) { } @@ -237,15 +237,10 @@ void FlushCallback(NPRenderContext* context, void* user_data) { PluginObject::PluginObject(NPP npp) : npp_(npp), test_object_(browser->createobject(npp, GetTestClass())) { - if (!initialize_render_context || !flush_render_context) { - NPPepperExtensions* extensions; + if (!pepper) { browser->getvalue(npp_, NPNVPepperExtensions, - reinterpret_cast<void*>(&extensions)); - CHECK(extensions); - initialize_render_context = extensions->initializeRender; - CHECK(initialize_render_context); - flush_render_context = extensions->flushRender; - CHECK(flush_render_context); + reinterpret_cast<void*>(&pepper)); + CHECK(pepper); } } @@ -259,11 +254,26 @@ NPClass* PluginObject::GetPluginClass() { } void PluginObject::SetWindow(const NPWindow& window) { + // File test + /* TODO(brettw): remove this when the file stuff is complete. This code is for + testing the OpenFileInSandbox function which is not complete. + { + void* handle = (void*)112358; + NPError err = pepper->openFile(npp_, + "q:\\prj\\src2\\src\\webkit\\tools\\pepper_test_plugin\\README", + &handle); + CHECK(err == NPERR_NO_ERROR); + + char buf[256]; + sprintf(buf, "Got the handle %d", (int)handle); + ::MessageBoxA(NULL, buf, "pepper", 0); + }*/ + size_.set_width(window.width); size_.set_height(window.height); NPRenderContext context; - initialize_render_context(npp_, NPRenderGraphicsRGBA, &context); + pepper->initializeRender(npp_, NPRenderGraphicsRGBA, &context); SkBitmap bitmap; bitmap.setConfig(SkBitmap::kARGB_8888_Config, window.width, window.height); @@ -276,5 +286,5 @@ void PluginObject::SetWindow(const NPWindow& window) { // match. Could be a calling convention mismatch? NPFlushRenderContextCallbackPtr callback = reinterpret_cast<NPFlushRenderContextCallbackPtr>(&FlushCallback); - flush_render_context(npp_, &context, callback, NULL); + pepper->flushRender(npp_, &context, callback, NULL); } |